Hanamura Temple

Wiki
  • A single neutral payload spawns in the center. Both teams contest control and escort it toward their own destination.
  • Up to three allied Heroes near the payload speed it up. Enemy Heroes can contest and halt it.
  • Each team has its own three-path route, and route progress is tracked independently per team.
  • On delivery, the payload fires 12 shots at enemy Structures. The Core is only targeted once everything else eligible is gone.

Objective Timers

EventDurationSecondsSource
Payload Cooldown3:00180slibMHmu_gv_mapMechanic_CooldownTimer_Duration

Payload Escort

Up to three allied Heroes standing near the payload move it forward, with speed scaling by Hero count. A fourth Hero adds nothing. If enemy Heroes are also near the payload it becomes contested, and movement stops until one side clears out.


    // Variable Declarations
    int lv_payloadOwningTeam;
    int lv_escortCount;
    int lv_pathID;
    string lv_actorMessageString;

    // Automatic Variable Declarations
    // Variable Initialization
    lv_payloadOwningTeam = libNPLD_gv_neutralPayload.lv_destination_Team;
    lv_actorMessageString = "";

    // Implementation
    if ((UnitBehaviorCount(libNPLD_gv_neutralPayload.lv_unit, "Payload_AllyMonitor_1") > 0)) {
        lv_escortCount = 1;
    }
    else if ((UnitBehaviorCount(libNPLD_gv_neutralPayload.lv_unit, "Payload_AllyMonitor_2") > 0)) {
        lv_escortCount = 2;
    }
    else if ((UnitBehaviorCount(libNPLD_gv_neutralPayload.lv_unit, "Payload_AllyMonitor_3") > 0)) {
        lv_escortCount = 3;
    }
    else if (true) {
        ActorSend(libNPLD_gv_activePathonMap[libGame_gv_teamOrderIndex_C][1], "AnimSetPaused Progress");
        ActorSend(libNPLD_gv_activePathonMap[libGame_gv_teamOrderIndex_C][2], "AnimSetPaused Progress");
        ActorSend(libNPLD_gv_activePathonMap[libGame_gv_teamChaosIndex_C][1], "AnimSetPaused Progress");

Contested Stall

When both teams have Heroes near the payload, it becomes contested. While contested, the payload stops moving and neither team makes progress.



//--------------------------------------------------------------------------------------------------
void libNPLD_gt_Payload_ChaosMonitor_Enabled_Init () {
    libNPLD_gt_Payload_ChaosMonitor_Enabled = TriggerCreate("libNPLD_gt_Payload_ChaosMonitor_Enabled_Func");
    TriggerAddEventUnitBehaviorChange(libNPLD_gt_Payload_ChaosMonitor_Enabled, UnitRefFromVariable("libNPLD_gv_neutralPayload.lv_unit"), "Payload_ChaosMonitor", c_unitBehaviorChangeActivate);
}

//--------------------------------------------------------------------------------------------------
// Trigger: Payload_ContestedMonitor_Enabled
//--------------------------------------------------------------------------------------------------
bool libNPLD_gt_Payload_ContestedMonitor_Enabled_Func (bool testConds, bool runActions) {
    // Automatic Variable Declarations
    // Conditions
    if (testConds) {
        if (!((UnitHasBehavior2(libNPLD_gv_neutralPayload.lv_unit, "Payload_ReachedDestination") == false))) {
            return false;
        }
    }

    // Actions
    if (!runActions) {

// ...


    libNPLD_gv_neutralPayload.lv_destination_Team = 0;
    libNPLD_gv_neutralPayload.lv_isContested = true;
    UnitSetOwner(libNPLD_gv_neutralPayload.lv_unit, libCore_gv_cOMPUTER_Neutral, false);
    libNPLD_gf_PayloadPathsSetProgressTeamandAnimations();
    return true;
}

//--------------------------------------------------------------------------------------------------
void libNPLD_gt_Payload_ContestedMonitor_Enabled_Init () {
    libNPLD_gt_Payload_ContestedMonitor_Enabled = TriggerCreate("libNPLD_gt_Payload_ContestedMonitor_Enabled_Func");
    TriggerAddEventUnitBehaviorChange(libNPLD_gt_Payload_ContestedMonitor_Enabled, UnitRefFromVariable("libNPLD_gv_neutralPayload.lv_unit"), "Payload_ContestedMonitor", c_unitBehaviorChangeActivate);
}

//--------------------------------------------------------------------------------------------------
// Trigger: Payload_ContestedMonitor_Disabled
//--------------------------------------------------------------------------------------------------
bool libNPLD_gt_Payload_ContestedMonitor_Disabled_Func (bool testConds, bool runActions) {
    // Automatic Variable Declarations
    // Conditions
    if (testConds) {

Delivery: 12-Shot Volley

When the payload reaches its destination it fires 12 shots at enemy Structures. Targeting checks the enemy Fort-side town pair first and picks the side with more remaining eligible Structure Health, then does the same for the Keep-side towns. The Core is only targeted once everything else eligible is destroyed.



    if ((libNtve_gf_UnitGroupIsDead(lv_townOuterLoop3) == false)) {
        return UnitGroupRandomUnit(lv_townOuterLoop3, c_unitCountAlive);
    }

    if ((libNtve_gf_UnitGroupIsDead(lv_townOuterLoop2) == false)) {
        return UnitGroupRandomUnit(lv_townOuterLoop2, c_unitCountAlive);
    }

    return null;
}

void libMHmu_gf_MakePayloadAttack (int lp_attackingTeam) {
    // Variable Declarations
    int lv_missilesInFlight;
    int lv_shotspervolley;
    int lv_shotsRemaining;
    int lv_town;
    unit lv_target;
    unit lv_unusableTarget;
    int lv_unusableTown;
    fixed lv_targetLife;
    fixed lv_targetLife_FactoringInFlightMissiles;
    int lv_activeTargetPing;


// ...

    lv_bannerSconce = UnitGroupClosestToPoint(UnitGroup("LootBannerSconce", c_playerAny, RegionCircle(UnitGetPosition(libNPLD_gv_neutralPayload.lv_unit), 12.0), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0), UnitGetPosition(libNPLD_gv_neutralPayload.lv_unit));
    if ((lv_bannerPlayerID >= 1) && (lv_bannerPlayerID <= 10) && (lv_bannerSconce != null) && (UnitIsValid(lv_bannerSconce) == true)) {
        libGame_gf_DropLootBannerinSconce(lv_bannerSconce, libGame_gv_players[lv_bannerPlayerID].lv_lootContent.lv_loot_Banner.lv_bannerID, lv_bannerPlayerID, true);
    }

    libNPLD_gf_PayloadPathsDestroyActivePaths();
    libSond_gf_SoundtrackUpdateMapSoundtrackIndex();
    libSond_gf_SoundtrackPlayMapSoundtrackAsDefaultSoundtrackForAllPlayers();
    Wait(1.0, c_timeGame);
    DialogControlSetVisible(libNPLD_gv_hanamura.lv_attackingStructureFrame[libNPLD_gf_UnitStopsOccupyingVehicleVehicle()], PlayerGroupAll(), true);
    DialogControlSetVisible(libNPLD_gv_hanamura.lv_payloadPanel_ActivePayloadStatus, PlayerGroupAll(), false);
    Wait(1.0, c_timeGame);
    libMHmu_gf_MakePayloadAttack(libNPLD_gf_UnitStopsOccupyingVehicleVehicle());
    Wait(1.0, c_timeGame);
    UnitKill(libNPLD_gv_neutralPayload.lv_unit);
    libNPLD_gf_SetNewPayloadPathForTeam(libNPLD_gf_UnitStopsOccupyingVehicleVehicle());
    Wait(1.0, c_timeGame);
    libNPLD_gv_neutralPayload.lv_completedReward = true;
    return true;
}

//--------------------------------------------------------------------------------------------------
void libMHmu_gt_PayloadReachesDestination_Init () {
    libMHmu_gt_PayloadReachesDestination = TriggerCreate("libMHmu_gt_PayloadReachesDestination_Func");
    libNPLD_gf_PayloadReachedDestination(libMHmu_gt_PayloadReachesDestination);

Timer Source

libmhmu_h.galaxy — constants

const int libMHmu_gv_mapMechanic_CooldownTimer_Duration = 180;

libmhmu.galaxy — timer start


    // Actions
    if (!runActions) {
        return true;
    }

    TimerStart(libMHmu_gv_hanamura.lv_mapMechanic_ObjectivePreviewTimer, (libMHmu_gv_mapMechanic_CooldownTimer_Duration - libMHmu_gv_mapMechanic_WarningTimer_Duration), false, c_timeGame);
    libSond_gf_SoundtrackApplyNewDefaultSoundtrackForPlayerGroup("MX_Hanamura_GameStart", PlayerGroupAll());
    return true;
}

//--------------------------------------------------------------------------------------------------
void libMHmu_gt_OpenTheGatesTimerExpires_Init () {

// ...

        libMHmu_gf_PayloadsPathCompletedChaos();
    }
    libMHmu_gf_ElevatorAttempttoLowerMonitor();
    libMHmu_gf_DestroyDestinationIndicator(libGame_gv_teamOrderIndex_C);
    libMHmu_gf_DestroyDestinationIndicator(libGame_gv_teamChaosIndex_C);
    RemoveUnitOfInterest(libNPLD_gv_neutralPayload.lv_unit, "EscortPayload", libNtve_ge_GoalTeam_Both);
    TimerStart(libMHmu_gv_hanamura.lv_mapMechanic_ObjectivePreviewTimer, (libMHmu_gv_mapMechanic_CooldownTimer_Duration - libMHmu_gv_mapMechanic_WarningTimer_Duration), false, c_timeGame);
    UnitCreateEffectUnit(libNPLD_gv_neutralPayload.lv_unit, "RegenGlobePickupSearchSet", libNPLD_gv_neutralPayload.lv_unit);
    lv_bannerUnitGroup = UnitGroupAlliance(UnitGetOwner(libNPLD_gv_neutralPayload.lv_unit), c_unitAllianceAlly, RegionCircle(UnitGetPosition(libNPLD_gv_neutralPayload.lv_unit), 12.0), UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterNeutral) | (1 << c_targetFilterEnemy), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterSummoned - 32))), 0);
    lv_bannerPlayerID = UnitGetOwner(UnitGroupRandomUnit(lv_bannerUnitGroup, c_unitCountAlive));
    lv_bannerSconce = UnitGroupClosestToPoint(UnitGroup("LootBannerSconce", c_playerAny, RegionCircle(UnitGetPosition(libNPLD_gv_neutralPayload.lv_unit), 12.0), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0), UnitGetPosition(libNPLD_gv_neutralPayload.lv_unit));
    if ((lv_bannerPlayerID >= 1) && (lv_bannerPlayerID <= 10) && (lv_bannerSconce != null) && (UnitIsValid(lv_bannerSconce) == true)) {
        libGame_gf_DropLootBannerinSconce(lv_bannerSconce, libGame_gv_players[lv_bannerPlayerID].lv_lootContent.lv_loot_Banner.lv_bannerID, lv_bannerPlayerID, true);

// ...

    // Actions
    if (!runActions) {
        return true;
    }

    libMHmu_gf_ElevatorAddRemoveUnpathableUnit(true);
    TimerStart(libMHmu_gv_elevator.lv_elevatorInitialRaiseTimer, (libMHmu_gv_mapMechanic_CooldownTimer_Duration - 8.0), false, c_timeGame);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libMHmu_gt_ElevatorStartInitialTimer_Init () {
    libMHmu_gt_ElevatorStartInitialTimer = TriggerCreate("libMHmu_gt_ElevatorStartInitialTimer_Func");

Source Files