Warhead Junction

Wiki
  • Nuclear warheads spawn across the map. Picking one up takes a 5-second channel.
  • After pickup, the Nuke is locked out briefly. If a Hero gets crowd-controlled mid-launch, the Nuke goes on a 10-second cooldown.
  • Warheads deal 1750 base damage to enemy non-Heroes, plus 70 per minute of game time. Enemy Heroes take 30% of their max Health instead.
  • The Core periodically launches its own Nuke at nearby enemy Heroes. The Slime Boss is a separate Mercenary Camp.

Objective Timers

EventDurationSecondsSource
First Warheads3:00180slibMSC2_gv_mMSC2FirstEventDelay_C
Pickup Channel0:055slibMSC2_gv_mMSC2NukeArmingDuration_C
Warhead Warning0:3030slibMSC2_gv_mMSC2EventWarningDelayGasCanister_C
Dropped Warhead Expiration2:00120slibMSC2_gv_mMSC2NukeExpireDuration_C
Interrupted Nuke Cooldown0:1010slibMSC2_gv_mMSC2NukeInterruptDelay_C
Damage Scaling Interval1:0060slibMSC2_gv_mMSC2NukeDamageScalingDelay_C

Arming & Interruption

Picking up a Warhead takes a 5-second channel. After pickup, the Nuke is locked out for 5 seconds. If a Hero gets crowd-controlled mid-launch, the Nuke goes on a 10-second cooldown.


    }

    UnitModifyCooldown(EventPlayerEffectUsedUnit(c_effectUnitCaster), "Abil/MapMechanicNuke", libMSC2_gv_mMSC2NukeInterruptDelay_C, c_cooldownOperationSet);
    UnitModifyCooldown(EventPlayerEffectUsedUnit(c_effectUnitCaster), "Abil/MapMechanicAbilityTarget", libMSC2_gv_mMSC2NukeInterruptDelay_C, c_cooldownOperationSet);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libMSC2_gt_MMSC2NukeInterrupted_Init () {
    libMSC2_gt_MMSC2NukeInterrupted = TriggerCreate("libMSC2_gt_MMSC2NukeInterrupted_Func");
    TriggerAddEventPlayerEffectUsed(libMSC2_gt_MMSC2NukeInterrupted, c_playerAny, "NukeCCedCooldownModifyUnit");
}

//--------------------------------------------------------------------------------------------------
// Trigger: MMSC2 Nuke Used
//--------------------------------------------------------------------------------------------------
bool libMSC2_gt_MMSC2NukeUsed_Func (bool testConds, bool runActions) {
    // Variable Declarations
    unit lv_casterUnit;

    // Automatic Variable Declarations

Damage & Scaling

Warheads deal 1750 base damage to enemy non-Heroes, with 70 added per minute of game time at pickup. Enemy Heroes hit by the impact take 30% of their max Health instead. The Core periodically launches its own Nuke at nearby enemy Heroes. The Slime Boss is a separate Mercenary Camp and does not launch Core nukes.


    // Implementation
    autoD415EA51_g = libMSC2_gv_mMSC2BuiltWarheadsActive;
    autoD415EA51_u = UnitGroupCount(autoD415EA51_g, c_unitCountAll);
    for (;; autoD415EA51_u -= 1) {
        lv_itUnit = UnitGroupUnitFromEnd(autoD415EA51_g, autoD415EA51_u);
        if (lv_itUnit == null) { break; }
        TextTagShow(libCore_gf_TextTagStoredForUnit(lv_itUnit, 1), PlayerGroupSingle(lp_player), lp_showHide);
    }
}

void libMSC2_gf_MMSC2NukeDamageScalingOnPickup (int lp_playerIndex) {
    // Variable Declarations
    int lv_damageScalesForAlignment;

    // Automatic Variable Declarations
    // Variable Initialization

    // Implementation
    lv_damageScalesForAlignment = (libMSC2_gv_mMSC2NukeDamageScalesNeeded - libMSC2_gv_mMSC2NukeDamageScalesDone[lp_playerIndex]);
    CatalogFieldValueModify(c_gameCatalogEffect, "NukeOuterImpactDamage", "Amount", lp_playerIndex, FixedToString((70.0 * lv_damageScalesForAlignment), c_fixedPrecisionAny), c_upgradeOperationAdd);
    CatalogFieldValueModify(c_gameCatalogEffect, "NukeOuterImpactDamageStructure", "Amount", lp_playerIndex, FixedToString((70.0 * lv_damageScalesForAlignment), c_fixedPrecisionAny), c_upgradeOperationAdd);

// ...

    else {
        lv_varUnit = lp_unit;
    }
    lv_allyTeam = libGame_gf_TeamNumberOfPlayer(lv_player);
    lv_enemyTeam = libGame_gf_EnemyTeam(lv_allyTeam);
    UnitBehaviorAdd(lv_varUnit, "HasMapMechanicTargetAbility", lv_varUnit, 1);
    UnitModifyCooldown(lv_varUnit, "Abil/MapMechanicNuke", libMSC2_gv_mMSC2NukeArmingDuration_C, c_cooldownOperationMax);
    UnitModifyCooldown(lv_varUnit, "Abil/MapMechanicAbilityTarget", libMSC2_gv_mMSC2NukeArmingDuration_C, c_cooldownOperationMax);
    libMSC2_gf_MMSC2ShowHideNukeTextTagsForPlayer(false, lv_player);
    libMSC2_gf_MMSC2NukeButtonStartFlashingForPlayer(lv_player);
    libMSC2_gf_MMSC2NukeDamageScalingOnPickup(lv_player);
    libGame_gf_ScoreValuesReportIntegerValueAndLog(lv_player, "CarriedMechanic", 1);
    libMSC2_gv_mMSC2_Nuke_Info.lv_playerNukeStateChanged[lv_player] = true;
    libNtve_gf_SendActorMessageToUnit(libMSC2_gv_nukeSiloUnit[lv_allyTeam], "Signal Activate");
    if ((libMSC2_gv_mMSC2_Nuke_Info.lv_teamHasNukes[lv_allyTeam] == true)) {
        libMSC2_gf_MMSC2UIEnableNukeUIStateForPlayer(lv_player);
    }
    else {
        libMSC2_gv_mMSC2_Nuke_Info.lv_teamHasNukes[lv_allyTeam] = true;
        libMSC2_gf_MMSC2UIEnableNukeUIStateForPlayer(lv_player);
    }

Timer Source

libmsc2_h.galaxy — constants

const fixed libMSC2_gv_mMSC2FirstEventDelay_C = 180.0;
const fixed libMSC2_gv_mMSC2EventWarningDelayGasCanister_C = 30.0;
const fixed libMSC2_gv_mMSC2NukeArmingDuration_C = 5.0;
const fixed libMSC2_gv_mMSC2NukeInterruptDelay_C = 10.0;
const fixed libMSC2_gv_mMSC2NukeExpireDuration_C = 120.0;
const fixed libMSC2_gv_mMSC2NukeDamageScalingDelay_C = 60.0;

libmsc2.galaxy — timer start

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

    libMSC2_gv_mMSC2EventState = libMSC2_ge_MMSC2EventStates_NoEvent;
    TimerStart(libMSC2_gv_mMSC2TerrazineMainEventTimer, libMSC2_gv_mMSC2FirstEventDelay_C, false, c_timeGame);
    TimerStart(libMSC2_gv_mMSC2NukeDamageScalingTimer, libMSC2_gv_mMSC2NukeDamageScalingDelay_C, false, c_timeGame);
    TriggerExecute(libMSC2_gt_MMSC2MainThread, true, false);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libMSC2_gt_MMSC2GatesOpened_Init () {

// ...

        libMSC2_gv_mMSC2WarheadEventFirstTime = false;
        libMSC2_gf_MMSC2TransmissionWarheadsSpawnedQ();
        while (!((UnitGroupCount(libMSC2_gv_mMSC2BuiltWarheadsActive, c_unitCountAlive) == 0))) {
            Wait(0.25, c_timeGame);
        }
        libMSC2_gv_mMSC2EventTracker = (libMSC2_gv_mMSC2EventTracker + 1);
        TimerStart(libMSC2_gv_mMSC2TerrazineMainEventTimer, (libMSC2_gv_mMSC2RepeatEventDelay_C + libMSC2_gv_mMSC2EventWarningDelayGasCanister_C + libMSC2_gv_mMSC2NukeExpireDuration_C), false, c_timeGame);
        if ((libMSC2_gv_mMSC2EventTracker == 3)) {
            libMSC2_gv_mMSC2ThreeWarheadsSpawn = true;
        }
        else {
            libMSC2_gv_mMSC2ThreeWarheadsSpawn = false;
        }

// ...

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

    libMSC2_gv_mMSC2NukeDamageScalesNeeded += 1;
    TimerStart(libMSC2_gv_mMSC2NukeDamageScalingTimer, libMSC2_gv_mMSC2NukeDamageScalingDelay_C, false, c_timeGame);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libMSC2_gt_MMSC2NukeDamageScaling_Init () {
    libMSC2_gt_MMSC2NukeDamageScaling = TriggerCreate("libMSC2_gt_MMSC2NukeDamageScaling_Func");

// ...

        TimerStart(libMSC2_gv_mMSC2BuiltWarheadReminderTimer, libMSC2_gv_mMSC2WarheadPickupReminderDelay_C, false, c_timeGame);
    }
    StatEventCreate("WarheadJunctionNukeCollected");
    StatEventAddDataFixed(StatEventLastCreated(), "GameTime", libUIUI_gf_HeroesGameTime());
    StatEventAddDataInt(StatEventLastCreated(), "OwningTeam", lv_team);
    StatEventSend(StatEventLastCreated());
    Wait(libMSC2_gv_mMSC2NukeArmingDuration_C, c_timeGame);
    if ((UnitHasBehavior2(EventPlayerEffectUsedUnit(c_effectUnitCaster), "HasMapMechanicTargetAbility") == true)) {
        libMSC2_gf_MMSC2TransmissionPlayerNukeReady(UnitGetOwner(EventPlayerEffectUsedUnit(c_effectUnitCaster)));
    }

    return true;
}

// ...

    if ((UnitGroupCount(libMSC2_gv_mMSC2DroppedWarheadsGroup, c_unitCountAlive) == 0)) {
        TimerPause(libMSC2_gv_mMSC2DroppedWarheadReminderTimer, true);
    }
    else {
        TimerStart(libMSC2_gv_mMSC2DroppedWarheadReminderTimer, libMSC2_gv_mMSC2WarheadPickupReminderDelay_C, false, c_timeGame);
    }
    Wait(libMSC2_gv_mMSC2NukeArmingDuration_C, c_timeGame);
    if ((UnitHasBehavior2(EventPlayerEffectUsedUnit(c_effectUnitCaster), "HasMapMechanicTargetAbility") == true)) {
        libMSC2_gf_MMSC2TransmissionPlayerNukeReady(UnitGetOwner(EventPlayerEffectUsedUnit(c_effectUnitCaster)));
    }

    return true;
}

// ...

        return true;
    }

    if ((TimerGetRemaining(libMSC2_gv_mMSC2TerrazineMainEventTimer) > libMSC2_gv_mMSC2EventWarningDelayGasCanister_C)) {
        TimerStart(libMSC2_gv_mMSC2ObjectivePreviewTimer, 0.0625, false, c_timeGame);
        Wait(0.125, c_timeGame);
        TimerStart(libMSC2_gv_mMSC2TerrazineMainEventTimer, libMSC2_gv_mMSC2EventWarningDelayGasCanister_C, false, c_timeGame);
    }

    return true;
}

//--------------------------------------------------------------------------------------------------

Source Files