Name | Type | is_array | initial_value |
ActiveHuman | integer | No | |
AmbushGroup | group | No | |
AmbushHero | location | No | |
AmbushHeroTarget | unit | No | |
AmbushPlayerTarget | player | No | |
AmbushTargetPoint | location | No | |
ArchDemonAnchored | integer | No | |
ArchQ | quest | No | |
arkq | quest | No | |
bloodQ | quest | No | |
button1 | button | Yes | |
daemon | effect | No | |
DarkVialFX | integer | No | |
Dash_Angle | real | No | |
Dash_caster | unit | No | |
Dash_Distance | real | No | |
Dash_Loop_Integer | integer | No | |
Dash_Point | location | No | |
Dash_Speed | real | No | |
Dash_target | location | No | |
DemonBloodCleaned | integer | No | |
DemonKillCount | integer | No | |
demonq | quest | No | |
EHYDRA | effect | No | |
Eillidan | effect | No | |
EncounterTimer1 | timer | No | |
EncounterTimer2 | timer | No | |
EThanatos | effect | No | |
Etyrant | effect | No | |
EyeHolder | player | No | |
HeroGroup | group | No | |
HeroPlayers | force | No | |
Heroselected | unit | Yes | |
HumanInvadingTarget | rect | No | |
HydraQ | quest | No | |
illidanQ | quest | No | |
INVASIONPHASE | integer | No | |
IsMultiplayer | boolean | No | |
Kiljaeden | unit | No | |
kilq | quest | No | |
Lichkq | quest | No | |
mephistoQ | quest | No | |
P1LOC | location | No | |
P2LOC | location | No | |
P3LOC | location | No | |
P4LOC | location | No | |
Phase2Invasion | trigger | No | |
player | unit | Yes | |
PlayerEntered | integer | Yes | |
PlayerRandezvous | integer | No | |
PLAYERS | force | Yes | Force00 |
PlayerselectedHero | integer | Yes | |
PlayerWaitRemain | integer | No | |
PortalSFX | effect | No | |
Pulsating_Phase | integer | No | |
Q1 | trigger | No | |
quest | quest | No | |
RandomNumber | integer | No | |
RetributionTimer | timer | No | |
Retributionwindow | timerdialog | No | |
Rollencounter | integer | No | |
SeedCarried | integer | No | |
SeedCarrier | force | No | |
SeedPlayer | player | No | |
Shivon_Variable_001 | unit | No | |
sidejoin | dialog | No | |
SoloPlayer | player | No | |
Soundroll | integer | No | |
SpawnRegion_1 | rect | No | |
SpawnRegion_2 | rect | No | |
SpawnRegion_3 | rect | No | |
SpawnRegion_4 | rect | No | |
SpawnRegion_5 | rect | No | |
SpawnRegion_6 | rect | No | |
SpawnRegion_7 | rect | No | |
SpawnRegion_8 | rect | No | |
StagHeartConsumed | integer | No | |
SUMMON | effect | No | |
T_heart | item | No | |
Temp_Group | group | No | |
Temp_Point | location | No | |
TempFelLanding | location | No | |
TempFX | effect | No | |
TempLandingHuman | location | No | |
TempLoc | location | No | |
TempPlayer | force | No | |
ThanatosQ | quest | No | |
tyrantq | quest | No | |
UpperclassPlayer | force | No | |
Voiddashdisc | effect | No | |
weather | weathereffect | No | |
YskaKiller | player | No |
// Warcraft III JASS AI Hero System - Full Version
// Includes: Initialization, Combat AI, Callouts, Revive Logic
// ================================
// GLOBALS
// ================================
globals
constant integer AI_PLAYER_ID = 1
player aiPlayer = null
unit aiHero = null
real baseX = 0.0
real baseY = 0.0
boolean retreating = false
real lastDeathX = 0.0
real lastDeathY = 0.0
boolean revengeSaid = false
trigger trigAttacked = null
trigger trigHeroDeath = null
trigger trigHeroKill = null
trigger trigPeriodic = null
endglobals
// ================================
// UTILITY
// ================================
function IsBoss takes unit u returns boolean
if u == null then
return false
endif
if IsUnitType(u, UNIT_TYPE_HERO) and IsUnitEnemy(u, aiPlayer) then
return true
endif
if GetUnitLevel(u) >= 8 then
return true
endif
return false
endfunction
// ================================
// CALLOUT FUNCTIONS
// ================================
function Callout_Attacked takes nothing returns nothing
local integer index = GetRandomInt(0, 10)
if index == 0 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": Hey! I'm walking here!")
elseif index == 1 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": You wanna fight? Fine by me.")
elseif index == 2 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": Guess a quiet stroll was too much to ask...")
elseif index == 3 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": Getting ambushed, just my luck!")
elseif index == 4 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": I can't catch a break, can I?")
elseif index == 5 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": You're messing with the wrong guy.")
elseif index == 6 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": Oh great, more undead pests.")
elseif index == 7 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": Sneaky ghoul! I'll carve you up!")
elseif index == 8 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": You call that an attack?")
elseif index == 9 then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": Alright, now I'm pissed!")
else
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(aiHero) + ": Is that all you've got?")
endif
endfunction
// ================================
// EVENT HANDLERS
// ================================
function OnHeroAttacked takes nothing returns nothing
local unit attacker = GetAttacker()
if attacker != null and IsUnitEnemy(attacker, aiPlayer) and IsUnitAliveBJ(aiHero) then
call IssueTargetOrder(aiHero, "attack", attacker)
if GetRandomInt(1, 100) <= 10 then
call Callout_Attacked()
endif
endif
set attacker = null
endfunction
function OnHeroKill takes nothing returns nothing
local unit dying = GetDyingUnit()
local unit killer = GetKillingUnit()
if killer == aiHero and dying != null then
if GetRandomInt(1, 100) <= 10 then
call Callout_Attacked() // Replace with Callout_Kill
endif
endif
set dying = null
set killer = null
endfunction
function OnHeroDeath takes nothing returns nothing
set lastDeathX = GetUnitX(aiHero)
set lastDeathY = GetUnitY(aiHero)
set revengeSaid = false
if GetRandomInt(1, 100) <= 10 then
call Callout_Attacked() // Replace with Callout_Death
endif
call TimerStart(CreateTimer(), 10.0, false, function HeroRevive)
endfunction
function HeroRevive takes nothing returns nothing
local timer t = GetExpiredTimer()
call ReviveHero(aiHero, baseX, baseY, true)
set retreating = false
if GetRandomInt(1, 100) <= 10 then
call Callout_Attacked() // Replace with Callout_Revive
endif
call IssuePointOrder(aiHero, "attack", lastDeathX, lastDeathY)
if (not revengeSaid) and GetRandomInt(1, 100) <= 10 then
call Callout_Attacked() // Replace with Callout_Revenge
endif
set revengeSaid = true
call DestroyTimer(t)
endfunction
// ================================
// MAIN AI THINKING LOOP
// ================================
function AIHeroThink takes nothing returns nothing
local real hpPercent
local unit u = null
local unit target = null
local group g
local real x
local real y
local real dx
local real dy
local real dist
local real minDist
if aiHero == null or (not IsUnitAliveBJ(aiHero)) then
return
endif
set hpPercent = GetUnitState(aiHero, UNIT_STATE_LIFE) / GetUnitState(aiHero, UNIT_STATE_MAX_LIFE) * 100
if not retreating then
if hpPercent < 30 then
set retreating = true
call IssuePointOrder(aiHero, "move", baseX, baseY)
if GetRandomInt(1, 100) <= 10 then
call Callout_Attacked() // Replace with Callout_Retreat
endif
return
endif
else
if hpPercent > 50 then
set retreating = false
endif
endif
if GetUnitCurrentOrder(aiHero) == 0 then
set x = GetUnitX(aiHero)
set y = GetUnitY(aiHero)
set g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 10000.0, null)
set minDist = 999999.0
loop
set u = FirstOfGroup(g)
exitwhen u == null
if IsUnitAliveBJ(u) and IsUnitEnemy(u, aiPlayer) and (not IsUnitType(u, UNIT_TYPE_STRUCTURE)) then
set dx = GetUnitX(u) - x
set dy = GetUnitY(u) - y
set dist = dx * dx + dy * dy
if dist < minDist then
set minDist = dist
set target = u
endif
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
if target != null then
if GetRandomInt(1, 100) <= 10 then
call Callout_Attacked() // Replace with Callout_EnterCombat
endif
call IssueTargetOrder(aiHero, "attack", target)
endif
endif
endfunction
// ================================
// INITIALIZATION
// ================================
function InitCustomAI takes nothing returns nothing
local group g = CreateGroup()
local unit u
set aiPlayer = Player(AI_PLAYER_ID)
call GroupEnumUnitsOfPlayer(g, aiPlayer, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
if IsUnitType(u, UNIT_TYPE_HERO) then
set aiHero = u
exitwhen true
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
if aiHero == null then
set aiHero = CreateUnit(aiPlayer, 'Hpal', GetStartLocationX(GetPlayerStartLocation(aiPlayer)), GetStartLocationY(GetPlayerStartLocation(aiPlayer)), 0.0)
endif
set baseX = GetUnitX(aiHero)
set baseY = GetUnitY(aiHero)
set trigAttacked = CreateTrigger()
call TriggerRegisterUnitEvent(trigAttacked, aiHero, EVENT_UNIT_ATTACKED)
call TriggerAddAction(trigAttacked, function OnHeroAttacked)
set trigHeroKill = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trigHeroKill, Player(PLAYER_NEUTRAL_AGGRESSIVE), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddAction(trigHeroKill, function OnHeroKill)
set trigHeroDeath = CreateTrigger()
call TriggerRegisterUnitEvent(trigHeroDeath, aiHero, EVENT_UNIT_DEATH)
call TriggerAddAction(trigHeroDeath, function OnHeroDeath)
set trigPeriodic = CreateTrigger()
call TriggerRegisterTimerEvent(trigPeriodic, 1.0, true)
call TriggerAddAction(trigPeriodic, function AIHeroThink)
endfunction
globals
player aiPlayer
unit aiHero
real baseX
real baseY
boolean retreating
real lastDeathX
real lastDeathY
boolean revengeSaid
trigger trigAttacked
trigger trigHeroDeath
trigger trigHeroKill
trigger trigPeriodic
endglobals
// ================================
// HERO REGISTRATION MODULE
// ================================
// Call this from a separate trigger with Custom Script:
// call RegisterAIHero(Player(1), 'Hpal')
function RegisterAIHero takes player whichPlayer, integer unitId returns nothing
local real x = GetStartLocationX(GetPlayerStartLocation(whichPlayer))
local real y = GetStartLocationY(GetPlayerStartLocation(whichPlayer))
set aiPlayer = whichPlayer
set aiHero = CreateUnit(aiPlayer, unitId, x, y, 0.0)
set baseX = x
set baseY = y
endfunction
// ================================
// AI BASE CAMP ASSIGNMENT MODULE
// ================================
// This module allows dynamic reassignment of the hero's base location.
// Useful when changing zones after reaching a certain level, etc.
//
// Usage:
// call SetAIBaseCamp(X, Y)
function SetAIBaseCamp takes real x, real y returns nothing
set baseX = x
set baseY = y
endfunction
function InitHeroes takes nothing returns nothing
call RegisterAIHero(gg_unit_hfoo_0351, GetRectCenter(gg_rct_BaseRegion1))
call InitCustomAI()
endfunction
function Debug_CountUnits takes nothing returns integer
local group g = CreateGroup()
local group temp
local unit u
local integer count = 0
local integer i = 0
loop
exitwhen i > 12
if i == 10 or i == 11 or i == 12 then
set temp = GetUnitsOfPlayerAll(Player(i))
call GroupAddGroup(temp, g)
call DestroyGroup(temp)
endif
set i = i + 1
endloop
// Also count Neutral Hostile (Player PLAYER_NEUTRAL_AGGRESSIVE is index PLAYER(PLAYER_NEUTRAL_AGGRESSIVE) = PLAYER(PLAYER_NEUTRAL_AGGRESSIVE) = PLAYER(PLAYER_NEUTRAL_AGGRESSIVE) = PLAYER(PLAYER_NEUTRAL_AGGRESSIVE) = PLAYER(PLAYER_NEUTRAL_AGGRESSIVE))
set temp = GetUnitsOfPlayerAll(Player(PLAYER_NEUTRAL_AGGRESSIVE))
call GroupAddGroup(temp, g)
call DestroyGroup(temp)
loop
set u = FirstOfGroup(g)
exitwhen u == null
set count = count + 1
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
return count
endfunction
function Debug_UnitsPerPlayer takes nothing returns nothing
local integer i = 0
local group g
local integer count
loop
exitwhen i > 12
if i == 10 or i == 11 or i == 12 then
set g = GetUnitsOfPlayerAll(Player(i))
set count = CountUnitsInGroup(g)
call DestroyGroup(g)
call BJDebugMsg("Player " + I2S(i) + ": " + I2S(count) + " units")
endif
set i = i + 1
endloop
// Neutral Hostile
set g = GetUnitsOfPlayerAll(Player(PLAYER_NEUTRAL_AGGRESSIVE))
set count = CountUnitsInGroup(g)
call DestroyGroup(g)
call BJDebugMsg("Neutral Hostile: " + I2S(count) + " units")
endfunction
function Debug_HandleStats takes nothing returns nothing
local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'hpea', 0, 0, 0)
local timer t = CreateTimer()
local effect fx = AddSpecialEffect("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl", 0, 0)
call BJDebugMsg("HandleID (unit): " + I2S(GetHandleId(u)))
call BJDebugMsg("HandleID (timer): " + I2S(GetHandleId(t)))
call BJDebugMsg("HandleID (effect): " + I2S(GetHandleId(fx)))
call RemoveUnit(u)
call DestroyTimer(t)
call DestroyEffect(fx)
endfunction
function Debug_MemoryEstimator takes nothing returns nothing
local integer unitID = GetHandleId(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'hpea', 0, 0, 0))
local integer timerID = GetHandleId(CreateTimer())
local integer effectID = GetHandleId(AddSpecialEffect("Abilities\\Spells\\Other\\Drain\\DrainTarget.mdl", 0, 0))
local integer estimatedHandleCount = R2I((unitID + timerID + effectID) / 3.0)
call BJDebugMsg("Estimated Total Handles in Use: " + I2S(estimatedHandleCount))
if estimatedHandleCount > 800000 then
call BJDebugMsg("|cffff0000HIGH RISK: Handle count is dangerously high!|r")
elseif estimatedHandleCount > 500000 then
call BJDebugMsg("|cffffff00WARNING: Moderate to heavy memory usage.|r")
else
call BJDebugMsg("|cff00ff00Memory usage appears normal.|r")
endif
endfunction
function DebugCommand takes nothing returns nothing
call BJDebugMsg("=== DEBUG REPORT ===")
call BJDebugMsg("Tracked Units (Gray, Snow, Violet, Neutral Hostile): " + I2S(Debug_CountUnits()))
call Debug_UnitsPerPlayer()
call Debug_HandleStats()
call Debug_MemoryEstimator()
call BJDebugMsg("====================")
endfunction
function InitTrig_DebugCommand takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerChatEvent(t, Player(0), "-debug", true)
call TriggerAddAction(t, function DebugCommand)
endfunction
globals
timer udg_CleanupTimer = null
group udg_CleanupGroup = null
location udg_CleanupLoc = null
effect udg_CleanupEffect = null
endglobals
function Cleanup_Periodic takes nothing returns nothing
if udg_CleanupGroup != null and CountUnitsInGroup(udg_CleanupGroup) == 0 then
call DestroyGroup(udg_CleanupGroup)
set udg_CleanupGroup = null
endif
if udg_CleanupLoc != null then
call RemoveLocation(udg_CleanupLoc)
set udg_CleanupLoc = null
endif
if udg_CleanupEffect != null then
call DestroyEffect(udg_CleanupEffect)
set udg_CleanupEffect = null
endif
endfunction
function InitTrig_Handle_Cleanup takes nothing returns nothing
set udg_CleanupTimer = CreateTimer()
call TimerStart(udg_CleanupTimer, 30.00, true, function Cleanup_Periodic)
endfunction
function Trig_Unit_respawns_Garden_Fiends_Conditions takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer uID = GetUnitTypeId(u)
// Skip summoned units
if IsUnitType(u, UNIT_TYPE_SUMMONED) then
return false
endif
// Disallowed unit types
if (uID == 'n00U') then
return false
endif
if (uID == 'n00O') then
return false
endif
if (uID == 'n00H') then
return false
endif
if (uID == 'n00D') then
return false
endif
if (uID == 'n00I') then
return false
endif
if (uID == 'U000') then
return false
endif
if (uID == 'n00M') then
return false
endif
if (uID == 'u00D') then
return false
endif
if (uID == 'u00G') then
return false
endif
if (uID == 'n01E') then
return false
endif
if (uID == 'n01G') then
return false
endif
if (uID == 'n01F') then
return false
endif
return true
endfunction
function Trig_Unit_respawns_Garden_Fiends_Actions takes nothing returns nothing
local unit dying = GetDyingUnit()
local integer utype = GetUnitTypeId(dying)
local real x = GetUnitX(dying)
local real y = GetUnitY(dying)
local real face = GetUnitFacing(dying)
local player owner = GetOwningPlayer(dying)
local unit newUnit
call UnitSuspendDecay(dying, true)
call TriggerSleepAction(60.00)
call RemoveUnit(dying)
set newUnit = CreateUnit(owner, utype, x, y, face)
// Force reset of aggro memory
call IssuePointOrder(newUnit, "attack", x + 64.0, y + 64.0) // dummy offset target
call IssuePointOrder(newUnit, "attack", x, y) // redirect to home
set dying = null
set owner = null
set newUnit = null
endfunction
//===========================================================================
function InitTrig_Unit_respawns_Garden_Fiends takes nothing returns nothing
set gg_trg_Unit_respawns_Garden_Fiends = CreateTrigger()
call TriggerRegisterPlayerUnitEventSimple(gg_trg_Unit_respawns_Garden_Fiends, Player(8), EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(gg_trg_Unit_respawns_Garden_Fiends, Condition(function Trig_Unit_respawns_Garden_Fiends_Conditions))
call TriggerAddAction(gg_trg_Unit_respawns_Garden_Fiends, function Trig_Unit_respawns_Garden_Fiends_Actions)
endfunction
function Trig_Unit_respawns_Maroon_Conditions takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer uID = GetUnitTypeId(u)
// Skip summoned units
if IsUnitType(u, UNIT_TYPE_SUMMONED) then
return false
endif
if IsUnitType(u, UNIT_TYPE_STRUCTURE) then
return false
endif
// Disallowed unit types
if (uID == 'h00X') then
return false
endif
if (uID == 'h00W') then
return false
endif
if (uID == 'h00J') then
return false
endif
if (uID == 'h00P') then
return false
endif
return true
endfunction
function Trig_Unit_respawns_Maroon_Actions takes nothing returns nothing
local unit dying = GetDyingUnit()
local integer utype = GetUnitTypeId(dying)
local real x = GetUnitX(dying)
local real y = GetUnitY(dying)
local real face = GetUnitFacing(dying)
local player owner = GetOwningPlayer(dying)
call UnitSuspendDecay(dying, true)
call TriggerSleepAction(60.00)
call RemoveUnit(dying)
call CreateUnit(owner, utype, x, y, face)
set dying = null
set owner = null
endfunction
//===========================================================================
function InitTrig_Unit_respawns_Maroon takes nothing returns nothing
set gg_trg_Unit_respawns_Maroon = CreateTrigger()
// Change the player here – assuming the maroon player is Player(7).
call TriggerRegisterPlayerUnitEventSimple(gg_trg_Unit_respawns_Maroon, Player(7), EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(gg_trg_Unit_respawns_Maroon, Condition(function Trig_Unit_respawns_Maroon_Conditions))
call TriggerAddAction(gg_trg_Unit_respawns_Maroon, function Trig_Unit_respawns_Maroon_Actions)
endfunction
globals
hashtable udg_GenericHeroRespawnTable = InitHashtable()
endglobals
// === Stage 3: Cleanup FX ===
function HeroRespawn_Final takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local effect fx = LoadEffectHandle(udg_GenericHeroRespawnTable, id, 3)
if fx != null then
call DestroyEffect(fx)
endif
call FlushChildHashtable(udg_GenericHeroRespawnTable, id)
call DestroyTimer(t)
set fx = null
set t = null
endfunction
// === Stage 2: Revive hero and spawn FX ===
function HeroRespawn_Execute takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit hero = LoadUnitHandle(udg_GenericHeroRespawnTable, id, 0)
local integer xp = LoadInteger(udg_GenericHeroRespawnTable, id, 1)
local integer lvl = LoadInteger(udg_GenericHeroRespawnTable, id, 2)
local location spawnLoc
local effect fx
if hero != null then
if IsPlayerInForce(GetOwningPlayer(hero), udg_SeedCarrier) then
set spawnLoc = GetRectCenter(gg_rct_Seed_Carrier_Spawn)
call ReviveHeroLoc(hero, spawnLoc, false)
call RemoveLocation(spawnLoc)
set fx = AddSpecialEffectTarget("war3mapImported\\Flamestrike Dark Blood II.mdx", hero, "origin")
call SetHeroXP(hero, xp - (lvl * 50), false)
else
if gg_unit_n00E_0823 != null then
set spawnLoc = GetUnitLoc(gg_unit_n00E_0823)
else
set spawnLoc = GetRectCenter(bj_mapInitialPlayableArea)
endif
call ReviveHeroLoc(hero, spawnLoc, false)
call RemoveLocation(spawnLoc)
set fx = AddSpecialEffectTarget("war3mapImported\\AncientExplode.mdx", hero, "origin")
call SetHeroXP(hero, xp - (lvl * 120), false)
endif
call SaveEffectHandle(udg_GenericHeroRespawnTable, id, 3, fx)
call TimerStart(t, 1.00, false, function HeroRespawn_Final)
endif
set hero = null
set spawnLoc = null
set fx = null
set t = null
endfunction
// === Stage 1: Apply XP penalty and schedule respawn ===
function HeroRespawn_PreDelay takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit hero = LoadUnitHandle(udg_GenericHeroRespawnTable, id, 0)
local integer lvl = LoadInteger(udg_GenericHeroRespawnTable, id, 2)
if hero != null then
call AddHeroXPSwapped(-100 * lvl, hero, false)
call TimerStart(t, 5.00, false, function HeroRespawn_Execute)
endif
set hero = null
endfunction
// === Conditions ===
function IsRespawnableHero takes unit u returns boolean
local integer id = GetUnitTypeId(u)
return id == 'H000' or id == 'H001' or id == 'Hapm' or id == 'Edem' or id == 'E000' or id == 'H00V' or id == 'Opgh' or id == 'Ogrh' or id == 'Hvwd' or id == 'Usyl'
endfunction
function Trig_Hero_Respawn_Conditions takes nothing returns boolean
return not IsUnitType(GetDyingUnit(), UNIT_TYPE_SUMMONED) and IsRespawnableHero(GetDyingUnit())
endfunction
// === Entry point ===
function Trig_Hero_Respawn_Actions takes nothing returns nothing
local unit dyingHero = GetDyingUnit()
local location deathLoc = GetUnitLoc(dyingHero)
local timer t = CreateTimer()
local integer id = GetHandleId(t)
local effect fx
// Death FX
set fx = AddSpecialEffect("Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", GetLocationX(deathLoc), GetLocationY(deathLoc))
call RemoveLocation(deathLoc)
// Store data for staged respawn
call SaveUnitHandle(udg_GenericHeroRespawnTable, id, 0, dyingHero)
call SaveInteger(udg_GenericHeroRespawnTable, id, 1, GetHeroXP(dyingHero))
call SaveInteger(udg_GenericHeroRespawnTable, id, 2, GetHeroLevel(dyingHero))
call SaveEffectHandle(udg_GenericHeroRespawnTable, id, 3, fx)
// Begin staged chain
call TimerStart(t, 1.00, false, function HeroRespawn_PreDelay)
set dyingHero = null
set deathLoc = null
set fx = null
set t = null
endfunction
// === Init ===
function InitTrig_Hero_Respawn takes nothing returns nothing
set gg_trg_Hero_Respawn = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(gg_trg_Hero_Respawn, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(gg_trg_Hero_Respawn, Condition(function Trig_Hero_Respawn_Conditions))
call TriggerAddAction(gg_trg_Hero_Respawn, function Trig_Hero_Respawn_Actions)
endfunction
globals
hashtable udg_OrangeHeroRespawnTable = InitHashtable()
endglobals
// === Delay stage 3: Clean up visual effect ===
function OrangeHeroRespawn_Final takes nothing returns nothing
local timer t = GetExpiredTimer()
local effect fx = LoadEffectHandle(udg_OrangeHeroRespawnTable, GetHandleId(t), 3)
if fx != null then
call DestroyEffect(fx)
endif
call FlushChildHashtable(udg_OrangeHeroRespawnTable, GetHandleId(t))
call DestroyTimer(t)
set fx = null
set t = null
endfunction
// === Delay stage 2: Respawn hero ===
function OrangeHeroRespawn_Execute takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit hero = LoadUnitHandle(udg_OrangeHeroRespawnTable, id, 0)
local integer xp = LoadInteger(udg_OrangeHeroRespawnTable, id, 1)
local integer lvl = LoadInteger(udg_OrangeHeroRespawnTable, id, 2)
local location spawnLoc
local effect fx
if hero != null then
if IsPlayerInForce(GetOwningPlayer(hero), udg_SeedCarrier) then
set spawnLoc = GetRectCenter(gg_rct_Seed_Carrier_Spawn)
call ReviveHeroLoc(hero, spawnLoc, false)
call RemoveLocation(spawnLoc)
set fx = AddSpecialEffectTarget("war3mapImported\\Flamestrike Dark Blood II.mdx", hero, "origin")
call SetHeroXP(hero, xp - (lvl * 50), false)
else
set spawnLoc = GetUnitLoc(gg_unit_n013_1260)
call ReviveHeroLoc(hero, spawnLoc, false)
call RemoveLocation(spawnLoc)
set fx = AddSpecialEffectTarget("war3mapImported\\Lightning Bolt Big.mdx", hero, "origin")
call SetHeroXP(hero, xp - (lvl * 120), false)
endif
// Store effect for cleanup
call SaveEffectHandle(udg_OrangeHeroRespawnTable, id, 3, fx)
call TimerStart(t, 1.00, false, function OrangeHeroRespawn_Final)
endif
set hero = null
set spawnLoc = null
endfunction
// === Delay stage 1: XP penalty and schedule respawn ===
function OrangeHeroRespawn_PreDelay takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit hero = LoadUnitHandle(udg_OrangeHeroRespawnTable, id, 0)
local integer lvl = LoadInteger(udg_OrangeHeroRespawnTable, id, 2)
if hero != null then
call AddHeroXPSwapped(-100 * lvl, hero, false)
endif
call TimerStart(t, 10.00, false, function OrangeHeroRespawn_Execute)
set hero = null
endfunction
// === Triggered on Orange hero death ===
function Trig_Orange_Hero_Respawn_Conditions takes nothing returns boolean
return GetOwningPlayer(GetDyingUnit()) == Player(5) and IsUnitType(GetDyingUnit(), UNIT_TYPE_HERO)
endfunction
function Trig_Orange_Hero_Respawn_Actions takes nothing returns nothing
local unit dyingHero = GetDyingUnit()
local location deathLoc = GetUnitLoc(dyingHero)
local timer t = CreateTimer()
local integer id = GetHandleId(t)
// Play death effect
call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", GetLocationX(deathLoc), GetLocationY(deathLoc)))
call RemoveLocation(deathLoc)
// Store hero and XP
call SaveUnitHandle(udg_OrangeHeroRespawnTable, id, 0, dyingHero)
call SaveInteger(udg_OrangeHeroRespawnTable, id, 1, GetHeroXP(dyingHero))
call SaveInteger(udg_OrangeHeroRespawnTable, id, 2, GetHeroLevel(dyingHero))
call TimerStart(t, 1.00, false, function OrangeHeroRespawn_PreDelay)
set dyingHero = null
set deathLoc = null
set t = null
endfunction
function InitTrig_Orange_Hero_Respawn takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerUnitEventSimple(t, Player(5), EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(t, Condition(function Trig_Orange_Hero_Respawn_Conditions))
call TriggerAddAction(t, function Trig_Orange_Hero_Respawn_Actions)
set t = null
endfunction
function Trig_ArchDaemon_Respawns_Copy_2_Conditions takes nothing returns boolean
if ( not ( GetUnitTypeId(GetDyingUnit()) == 'H00B' ) ) then
return false
endif
return true
endfunction
function Trig_ArchDaemon_Respawns_Copy_2_Func003C takes nothing returns boolean
if ( not ( IsPlayerInForce(Player(5), udg_SeedCarrier) == true ) ) then
return false
endif
return true
endfunction
function Trig_ArchDaemon_Respawns_Copy_2_Actions takes nothing returns nothing
call TriggerSleepAction( 20.00 )
if ( Trig_ArchDaemon_Respawns_Copy_2_Func003C() ) then
call ReviveHeroLoc( gg_unit_H00B_1259, GetRectCenter(gg_rct_Seed_Carrier_Spawn), false )
call AddSpecialEffectTargetUnitBJ( "origin", gg_unit_H00B_1259, "war3mapImported\\Flamestrike Dark Blood II.mdx" )
call SetHeroXP( gg_unit_H00B_1259, ( GetHeroXP(gg_unit_H00B_1259) - ( GetHeroLevel(gg_unit_H00B_1259) * 50 ) ), false )
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
else
call ReviveHeroLoc( gg_unit_H00B_1259, GetUnitLoc(gg_unit_n013_1260), false )
call SetHeroXP( gg_unit_H00B_1259, ( GetHeroXP(gg_unit_H00B_1259) - ( GetHeroLevel(gg_unit_H00B_1259) * 120 ) ), false )
call AddSpecialEffectTargetUnitBJ( "origin", gg_unit_H00B_1259, "war3mapImported\\Lightning Bolt Big.mdx" )
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
endif
endfunction
//===========================================================================
function InitTrig_ArchDaemon_Respawns_Copy_2 takes nothing returns nothing
set gg_trg_ArchDaemon_Respawns_Copy_2 = CreateTrigger( )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_ArchDaemon_Respawns_Copy_2, Player(5), EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( gg_trg_ArchDaemon_Respawns_Copy_2, Condition( function Trig_ArchDaemon_Respawns_Copy_2_Conditions ) )
call TriggerAddAction( gg_trg_ArchDaemon_Respawns_Copy_2, function Trig_ArchDaemon_Respawns_Copy_2_Actions )
endfunction
function GetSoloPlayer takes nothing returns player
local integer i = 0
loop
exitwhen i >= bj_MAX_PLAYERS
if (GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER) then
return Player(i)
endif
set i = i + 1
endloop
return null
endfunction
globals
timer udg_WeatherCycleTimer = null
weathereffect udg_CurrentWeather = null
endglobals
function RemoveCurrentWeather takes nothing returns nothing
if udg_CurrentWeather != null then
call RemoveWeatherEffect(udg_CurrentWeather)
set udg_CurrentWeather = null
endif
endfunction
function ChooseRandomWeather takes nothing returns string
local integer roll = GetRandomInt(1, 100)
if roll <= 50 then
return "" // Clear
endif
set roll = GetRandomInt(1, 4)
if roll == 1 then
return "RLhr" // Heavy Rain
elseif roll == 2 then
return "RAlr" // Light Rain
elseif roll == 3 then
return "FDrp" // White Fog
elseif roll == 4 then
return "FDbl" // Blue Fog
endif
return ""
endfunction
function WeatherCycleLoop takes nothing returns nothing
local string weatherId = ChooseRandomWeather()
call RemoveCurrentWeather()
if weatherId == "RLhr" then
set udg_CurrentWeather = AddWeatherEffect(gg_rct_GardenOverworld, 'RLhr')
elseif weatherId == "RAlr" then
set udg_CurrentWeather = AddWeatherEffect(gg_rct_GardenOverworld, 'RAlr')
elseif weatherId == "FDrp" then
set udg_CurrentWeather = AddWeatherEffect(gg_rct_GardenOverworld, 'FDrp')
elseif weatherId == "FDbl" then
set udg_CurrentWeather = AddWeatherEffect(gg_rct_GardenOverworld, 'FDbl')
endif
if udg_CurrentWeather != null then
call EnableWeatherEffect(udg_CurrentWeather, true)
endif
endfunction
function Start_Weather_Cycle takes nothing returns nothing
if udg_WeatherCycleTimer == null then
set udg_WeatherCycleTimer = CreateTimer()
endif
call TimerStart(udg_WeatherCycleTimer, 90.00, true, function WeatherCycleLoop)
endfunction
globals
destructable array udg_DestructList
integer udg_DestructIndex = 0
integer udg_DestructMax = 0
integer udg_DestructType1 = 'B004' // First replacement type
integer udg_DestructType2 = 'B005' // Second replacement type
timer udg_DestructReplaceTimer = null
endglobals
function ReplaceNextDestruct takes nothing returns nothing
local destructable d
local real x
local real y
local integer chosenType
local real angle
local real scale
local integer variation
if udg_DestructIndex >= udg_DestructMax then
call PauseTimer(udg_DestructReplaceTimer)
call DestroyTimer(udg_DestructReplaceTimer)
set udg_DestructReplaceTimer = null
return
endif
set d = udg_DestructList[udg_DestructIndex]
set x = GetDestructableX(d)
set y = GetDestructableY(d)
call RemoveDestructable(d)
set chosenType = udg_DestructType1
if GetRandomInt(0, 1) == 1 then
set chosenType = udg_DestructType2
endif
set angle = GetRandomReal(0.0, 360.0)
set scale = GetRandomReal(2.5, 4.0)
set variation = GetRandomInt(0, 1)
call CreateDestructable(chosenType, x, y, angle, scale, variation)
set udg_DestructIndex = udg_DestructIndex + 1
endfunction
function SaveAllDestructiblesEnum takes nothing returns nothing
set udg_DestructList[udg_DestructMax] = GetEnumDestructable()
set udg_DestructMax = udg_DestructMax + 1
endfunction
function SaveAllDestructibles takes nothing returns nothing
local rect r = GetPlayableMapRect()
call EnumDestructablesInRect(r, null, function SaveAllDestructiblesEnum)
call RemoveRect(r)
set r = null
set udg_DestructIndex = 0
set udg_DestructReplaceTimer = CreateTimer()
call TimerStart(udg_DestructReplaceTimer, 0.10, true, function ReplaceNextDestruct)
endfunction
function InitGlobalsX takes nothing returns nothing
if udg_TempPlayer == null then
set udg_TempPlayer = CreateForce()
endif
endfunction
function InitTrig_InitGlobalsX takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerAddAction(t, function InitGlobalsX)
endfunction
globals
hashtable udg_RespawnTable = InitHashtable()
integer udg_RespawnNextIndex = 0
rect array udg_RespawnRegions
endglobals
function ShouldRegisterUnit takes unit u returns boolean
local integer uID = GetUnitTypeId(u)
if uID == 0 or IsUnitType(u, UNIT_TYPE_SUMMONED) then
return false
endif
if (uID == 'n00U' or uID == 'n00O' or uID == 'n00H' or uID == 'n00D' or uID == 'n00I' or uID == 'U000' or uID == 'n00M' or uID == 'u00D' or uID == 'u00G' or uID == 'n01E' or uID == 'n01G' or uID == 'n01F') then
return false
endif
return true
endfunction
function RegisterRespawnSnapshot takes unit u returns nothing
local integer uid = GetHandleId(u)
if HaveSavedInteger(udg_RespawnTable, uid, 0) then
return // already registered
endif
call SaveInteger(udg_RespawnTable, uid, 0, GetUnitTypeId(u))
call SaveReal(udg_RespawnTable, uid, 1, GetUnitX(u))
call SaveReal(udg_RespawnTable, uid, 2, GetUnitY(u))
call SaveReal(udg_RespawnTable, uid, 3, GetUnitFacing(u))
call SavePlayerHandle(udg_RespawnTable, uid, 4, GetOwningPlayer(u))
endfunction
function RespawnUnitByHandle takes integer uid returns nothing
local integer uType = LoadInteger(udg_RespawnTable, uid, 0)
local real x = LoadReal(udg_RespawnTable, uid, 1)
local real y = LoadReal(udg_RespawnTable, uid, 2)
local real face = LoadReal(udg_RespawnTable, uid, 3)
local player p = LoadPlayerHandle(udg_RespawnTable, uid, 4)
if uType != 0 then
call CreateUnit(p, uType, x, y, face)
endif
call FlushChildHashtable(udg_RespawnTable, uid)
endfunction
function Respawn_Execute takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer uid = LoadInteger(udg_RespawnTable, GetHandleId(t), 999)
call RespawnUnitByHandle(uid)
call FlushChildHashtable(udg_RespawnTable, GetHandleId(t))
call DestroyTimer(t)
set t = null
endfunction
function Respawn_DelayedRemove takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = LoadUnitHandle(udg_RespawnTable, GetHandleId(t), 0)
if u != null and IsUnitType(u, UNIT_TYPE_DEAD) then
call RemoveUnit(u)
endif
call FlushChildHashtable(udg_RespawnTable, GetHandleId(t))
call DestroyTimer(t)
set u = null
set t = null
endfunction
function Respawn_Death takes nothing returns nothing
local unit u = GetDyingUnit()
local integer uid = GetHandleId(u)
local timer t
if not HaveSavedInteger(udg_RespawnTable, uid, 0) then
set u = null
return
endif
// Schedule respawn
set t = CreateTimer()
call SaveInteger(udg_RespawnTable, GetHandleId(t), 999, uid)
call TimerStart(t, 100.0, false, function Respawn_Execute)
set t = null
// Delay removal for proper death animation and item drop
set t = CreateTimer()
call SaveUnitHandle(udg_RespawnTable, GetHandleId(t), 0, u)
call TimerStart(t, 3.00, false, function Respawn_DelayedRemove)
set u = null
set t = null
endfunction
function Respawn_ScanNextRegion takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer index = LoadInteger(udg_RespawnTable, GetHandleId(t), 123)
local group g = CreateGroup()
local unit u
local rect scanRect = udg_RespawnRegions[index]
call GroupEnumUnitsInRect(g, scanRect, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
if ShouldRegisterUnit(u) then
call RegisterRespawnSnapshot(u)
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
call FlushChildHashtable(udg_RespawnTable, GetHandleId(t))
call DestroyTimer(t)
set g = null
set u = null
set scanRect = null
set t = null
endfunction
function Init_RespawnSystem takes nothing returns nothing
local integer index = 0
local timer t
loop
exitwhen index > 11
set t = CreateTimer()
call SaveInteger(udg_RespawnTable, GetHandleId(t), 123, index)
call TimerStart(t, 0.50 * index, false, function Respawn_ScanNextRegion)
set index = index + 1
endloop
set t = null
endfunction
function Setup_RespawnRegions takes nothing returns nothing
set udg_RespawnRegions[0] = gg_rct_S_Region_1
set udg_RespawnRegions[1] = gg_rct_S_Region_2
set udg_RespawnRegions[2] = gg_rct_S_Region_3
set udg_RespawnRegions[3] = gg_rct_S_Region_4
set udg_RespawnRegions[4] = gg_rct_S_Region_5
set udg_RespawnRegions[5] = gg_rct_S_Region_6
set udg_RespawnRegions[6] = gg_rct_S_Region_7
set udg_RespawnRegions[7] = gg_rct_S_Region_8
set udg_RespawnRegions[8] = gg_rct_S_Region_9
set udg_RespawnRegions[9] = gg_rct_S_Region_10
set udg_RespawnRegions[10] = gg_rct_S_Region_11
set udg_RespawnRegions[11] = gg_rct_S_Region_12
call Init_RespawnSystem()
endfunction
function InitTrig_RespawnSystem takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerUnitEventSimple(t, Player(8), EVENT_PLAYER_UNIT_DEATH)
call TriggerRegisterPlayerUnitEventSimple(t, Player(PLAYER_NEUTRAL_AGGRESSIVE), EVENT_PLAYER_UNIT_DEATH)
call TriggerAddAction(t, function Respawn_Death)
call TimerStart(CreateTimer(), 0.01, false, function Setup_RespawnRegions)
set t = null
endfunction
function Trig_Slasher_Spawns_from_pod_Conditions takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == 'n01F'
endfunction
function Trig_Slasher_Spawns_from_pod_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local location loc = GetUnitLoc(u)
local effect fx
// Spawn 3 slashers
call CreateNUnitsAtLoc(2, 'n01I', Player(15), loc, GetRandomReal(0, 360.00))
// Clean up
call RemoveLocation(loc)
// Null locals
set u = null
set fx = null
endfunction
//===========================================================================
function InitTrig_Slasher_Spawns_from_pod takes nothing returns nothing
set gg_trg_Slasher_Spawns_from_pod = CreateTrigger()
call TriggerRegisterPlayerUnitEventSimple(gg_trg_Slasher_Spawns_from_pod, Player(8), EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(gg_trg_Slasher_Spawns_from_pod, Condition(function Trig_Slasher_Spawns_from_pod_Conditions))
call TriggerAddAction(gg_trg_Slasher_Spawns_from_pod, function Trig_Slasher_Spawns_from_pod_Actions)
endfunction
function Trig_Randezvous_1_Copy_Func001C takes nothing returns boolean
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'H000' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'H00V' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'H001' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'Hapm' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'Edem' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'E000' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'Ogrh' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'Opgh' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'Hvwd' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'Usyl' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetEnteringUnit()) == 'H00B' ) ) then
return true
endif
return false
endfunction
function Trig_Randezvous_1_Copy_Conditions takes nothing returns boolean
if ( not Trig_Randezvous_1_Copy_Func001C() ) then
return false
endif
if ( not ( udg_PlayerEntered[GetConvertedPlayerId(GetOwningPlayer(GetEnteringUnit()))] == 0 ) ) then
return false
endif
return true
endfunction
function Trig_Randezvous_1_Copy_Func006C takes nothing returns boolean
if ( not ( CountPlayersInForceBJ(GetPlayersByMapControl(MAP_CONTROL_USER)) > 1 ) ) then
return false
endif
return true
endfunction
function Trig_Randezvous_1_Copy_Func007C takes nothing returns boolean
if ( not ( udg_PlayerRandezvous >= CountPlayersInForceBJ(GetPlayersByMapControl(MAP_CONTROL_USER)) ) ) then
return false
endif
return true
endfunction
function Trig_Randezvous_1_Copy_Actions takes nothing returns nothing
set udg_PlayerRandezvous = ( udg_PlayerRandezvous + 1 )
set udg_PlayerEntered[GetConvertedPlayerId(GetTriggerPlayer())] = 1
set udg_PlayerWaitRemain = ( CountPlayersInForceBJ(GetPlayersByMapControl(MAP_CONTROL_USER)) - udg_PlayerRandezvous )
if ( Trig_Randezvous_1_Copy_Func006C() ) then
call QuestMessageBJ( GetPlayersAll(), bj_QUESTMESSAGE_REQUIREMENT, ( "Waiting for Player :" + I2S(udg_PlayerWaitRemain) ) )
else
call DoNothing( )
endif
if ( Trig_Randezvous_1_Copy_Func007C() ) then
call TriggerExecute( gg_trg_OracleGreets )
else
call DoNothing( )
endif
endfunction
//===========================================================================
function InitTrig_Randezvous_1_Copy takes nothing returns nothing
set gg_trg_Randezvous_1_Copy = CreateTrigger( )
call DisableTrigger( gg_trg_Randezvous_1_Copy )
call TriggerRegisterEnterRectSimple( gg_trg_Randezvous_1_Copy, gg_rct_Final_Player_Check )
call TriggerAddCondition( gg_trg_Randezvous_1_Copy, Condition( function Trig_Randezvous_1_Copy_Conditions ) )
call TriggerAddAction( gg_trg_Randezvous_1_Copy, function Trig_Randezvous_1_Copy_Actions )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func003002 takes nothing returns nothing
call CameraSetEQNoiseForPlayer( GetEnumPlayer(), 3 )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func005002 takes nothing returns nothing
call CameraClearNoiseForPlayer( GetEnumPlayer() )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func007Func001A takes nothing returns nothing
call ExplodeUnitBJ( GetEnumUnit() )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func007C takes nothing returns boolean
if ( not ( udg_Rollencounter == 1 ) ) then
return false
endif
return true
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func008Func001A takes nothing returns nothing
call ExplodeUnitBJ( GetEnumUnit() )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func008C takes nothing returns boolean
if ( not ( udg_Rollencounter == 2 ) ) then
return false
endif
return true
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func009Func001A takes nothing returns nothing
call ExplodeUnitBJ( GetEnumUnit() )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func009C takes nothing returns boolean
if ( not ( udg_Rollencounter == 3 ) ) then
return false
endif
return true
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func010Func001A takes nothing returns nothing
call ExplodeUnitBJ( GetEnumUnit() )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func010C takes nothing returns boolean
if ( not ( udg_Rollencounter == 4 ) ) then
return false
endif
return true
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func011Func001A takes nothing returns nothing
call ExplodeUnitBJ( GetEnumUnit() )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func011C takes nothing returns boolean
if ( not ( udg_Rollencounter == 5 ) ) then
return false
endif
return true
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func012Func001A takes nothing returns nothing
call ExplodeUnitBJ( GetEnumUnit() )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func012C takes nothing returns boolean
if ( not ( udg_Rollencounter == 6 ) ) then
return false
endif
return true
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func013Func001A takes nothing returns nothing
call ExplodeUnitBJ( GetEnumUnit() )
endfunction
function Trig_ENC_SeedofCorruption_Copy_Func013C takes nothing returns boolean
if ( not ( udg_Rollencounter == 7 ) ) then
return false
endif
return true
endfunction
function Trig_ENC_SeedofCorruption_Copy_Actions takes nothing returns nothing
set udg_Rollencounter = GetRandomInt(1, 7)
call ForForce( GetPlayersAll(), function Trig_ENC_SeedofCorruption_Copy_Func003002 )
call TriggerSleepAction( 0.01 )
call ForForce( GetPlayersAll(), function Trig_ENC_SeedofCorruption_Copy_Func005002 )
call QuestMessageBJ( GetPlayersAll(), bj_QUESTMESSAGE_MISSIONFAILED, "TRIGSTR_5869" )
if ( Trig_ENC_SeedofCorruption_Copy_Func007C() ) then
call ForGroupBJ( GetUnitsInRectAll(gg_rct_SeedSpot1), function Trig_ENC_SeedofCorruption_Copy_Func007Func001A )
call TriggerSleepAction( 1.00 )
call CreateNUnitsAtLoc( 1, 'nfgo', Player(PLAYER_NEUTRAL_AGGRESSIVE), GetRectCenter(gg_rct_SeedSpot1), bj_UNIT_FACING )
call PingMinimapLocForForceEx( GetPlayersAll(), GetUnitLoc(GetLastCreatedUnit()), 60.00, bj_MINIMAPPINGSTYLE_ATTACK, 80.00, 0.00, 100 )
else
call DoNothing( )
endif
if ( Trig_ENC_SeedofCorruption_Copy_Func008C() ) then
call ForGroupBJ( GetUnitsInRectAll(gg_rct_SeedSpot_2), function Trig_ENC_SeedofCorruption_Copy_Func008Func001A )
call TriggerSleepAction( 1.00 )
call CreateNUnitsAtLoc( 1, 'nfgo', Player(PLAYER_NEUTRAL_AGGRESSIVE), GetRectCenter(gg_rct_SeedSpot_2), bj_UNIT_FACING )
call PingMinimapLocForForceEx( GetPlayersAll(), GetUnitLoc(GetLastCreatedUnit()), 60.00, bj_MINIMAPPINGSTYLE_SIMPLE, 80.00, 0.00, 100 )
else
call DoNothing( )
endif
if ( Trig_ENC_SeedofCorruption_Copy_Func009C() ) then
call ForGroupBJ( GetUnitsInRectAll(gg_rct_SeedSpot_3), function Trig_ENC_SeedofCorruption_Copy_Func009Func001A )
call TriggerSleepAction( 1.00 )
call CreateNUnitsAtLoc( 1, 'nfgo', Player(PLAYER_NEUTRAL_AGGRESSIVE), GetRectCenter(gg_rct_SeedSpot_3), bj_UNIT_FACING )
call PingMinimapLocForForceEx( GetPlayersAll(), GetUnitLoc(GetLastCreatedUnit()), 60.00, bj_MINIMAPPINGSTYLE_SIMPLE, 80.00, 0.00, 100 )
else
call DoNothing( )
endif
if ( Trig_ENC_SeedofCorruption_Copy_Func010C() ) then
call ForGroupBJ( GetUnitsInRectAll(gg_rct_SeedSpot_4), function Trig_ENC_SeedofCorruption_Copy_Func010Func001A )
call TriggerSleepAction( 1.00 )
call CreateNUnitsAtLoc( 1, 'nfgo', Player(PLAYER_NEUTRAL_AGGRESSIVE), GetRectCenter(gg_rct_SeedSpot_4), bj_UNIT_FACING )
call PingMinimapLocForForceEx( GetPlayersAll(), GetUnitLoc(GetLastCreatedUnit()), 60.00, bj_MINIMAPPINGSTYLE_SIMPLE, 80.00, 0.00, 100 )
else
call DoNothing( )
endif
if ( Trig_ENC_SeedofCorruption_Copy_Func011C() ) then
call ForGroupBJ( GetUnitsInRectAll(gg_rct_SeedSpot_5), function Trig_ENC_SeedofCorruption_Copy_Func011Func001A )
call TriggerSleepAction( 1.00 )
call CreateNUnitsAtLoc( 1, 'nfgo', Player(PLAYER_NEUTRAL_AGGRESSIVE), GetRectCenter(gg_rct_SeedSpot_5), bj_UNIT_FACING )
call PingMinimapLocForForceEx( GetPlayersAll(), GetUnitLoc(GetLastCreatedUnit()), 60.00, bj_MINIMAPPINGSTYLE_SIMPLE, 80.00, 0.00, 100 )
else
call DoNothing( )
endif
if ( Trig_ENC_SeedofCorruption_Copy_Func012C() ) then
call ForGroupBJ( GetUnitsInRectAll(gg_rct_SeedSpot_6), function Trig_ENC_SeedofCorruption_Copy_Func012Func001A )
call TriggerSleepAction( 1.00 )
call CreateNUnitsAtLoc( 1, 'nfgo', Player(PLAYER_NEUTRAL_AGGRESSIVE), GetRectCenter(gg_rct_SeedSpot_6), bj_UNIT_FACING )
call PingMinimapLocForForceEx( GetPlayersAll(), GetUnitLoc(GetLastCreatedUnit()), 60.00, bj_MINIMAPPINGSTYLE_SIMPLE, 80.00, 0.00, 100 )
else
call DoNothing( )
endif
if ( Trig_ENC_SeedofCorruption_Copy_Func013C() ) then
call ForGroupBJ( GetUnitsInRectAll(gg_rct_SeedSpot_7), function Trig_ENC_SeedofCorruption_Copy_Func013Func001A )
call TriggerSleepAction( 1.00 )
call CreateNUnitsAtLoc( 1, 'nfgo', Player(PLAYER_NEUTRAL_AGGRESSIVE), GetRectCenter(gg_rct_SeedSpot_7), bj_UNIT_FACING )
call PingMinimapLocForForceEx( GetPlayersAll(), GetUnitLoc(GetLastCreatedUnit()), 60.00, bj_MINIMAPPINGSTYLE_SIMPLE, 80.00, 0.00, 100 )
else
call DoNothing( )
endif
endfunction
//===========================================================================
function InitTrig_ENC_SeedofCorruption_Copy takes nothing returns nothing
set gg_trg_ENC_SeedofCorruption_Copy = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_ENC_SeedofCorruption_Copy, Player(0), "-enc3", true )
call TriggerAddAction( gg_trg_ENC_SeedofCorruption_Copy, function Trig_ENC_SeedofCorruption_Copy_Actions )
endfunction
function Trig_ENC_LightningStrike_Copy_Func002C takes nothing returns boolean
if ( not ( udg_IsMultiplayer == true ) ) then
return false
endif
return true
endfunction
function Trig_ENC_LightningStrike_Copy_Func004C takes nothing returns boolean
if ( not ( udg_AmbushPlayerTarget == Player(5) ) ) then
return false
endif
return true
endfunction
function Trig_ENC_LightningStrike_Copy_Func011A takes nothing returns nothing
call ExplodeUnitBJ( GetEnumUnit() )
endfunction
function Trig_ENC_LightningStrike_Copy_Actions takes nothing returns nothing
if ( Trig_ENC_LightningStrike_Copy_Func002C() ) then
set udg_AmbushPlayerTarget = ForcePickRandomPlayer(GetPlayersByMapControl(MAP_CONTROL_USER))
else
set udg_AmbushPlayerTarget = udg_SoloPlayer
endif
call TriggerSleepAction( 0.01 )
if ( Trig_ENC_LightningStrike_Copy_Func004C() ) then
set udg_AmbushHero = OffsetLocation(GetUnitLoc(gg_unit_H00B_1259), GetRandomReal(-1500.00, 1500.00), GetRandomReal(-1500.00, 1500.00))
set udg_AmbushHeroTarget = gg_unit_H00B_1259
else
set udg_AmbushHero = OffsetLocation(GetUnitLoc(udg_player[GetConvertedPlayerId(udg_AmbushPlayerTarget)]), GetRandomReal(-1500.00, 1500.00), GetRandomReal(-1500.00, 1500.00))
set udg_AmbushHeroTarget = udg_player[GetConvertedPlayerId(udg_AmbushPlayerTarget)]
endif
call TriggerSleepAction( 0.01 )
call AddSpecialEffectLocBJ( udg_AmbushHero, "war3mapImported\\Lightning Bolt Big.mdx" )
call CinematicFadeBJ( bj_CINEFADETYPE_FADEIN, 0.05, "ReplaceableTextures\\CameraMasks\\White_mask.blp", 100.00, 100.00, 100.00, 60.00 )
call TriggerSleepAction( 0.01 )
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
call PlaySoundBJ( gg_snd_lightning_189909 )
call ForGroupBJ( GetUnitsInRangeOfLocAll(60.00, udg_AmbushHero), function Trig_ENC_LightningStrike_Copy_Func011A )
call RemoveLocation(udg_AmbushHero)
endfunction
//===========================================================================
function InitTrig_ENC_LightningStrike_Copy takes nothing returns nothing
set gg_trg_ENC_LightningStrike_Copy = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_ENC_LightningStrike_Copy, Player(0), "-enc5", true )
call TriggerAddAction( gg_trg_ENC_LightningStrike_Copy, function Trig_ENC_LightningStrike_Copy_Actions )
endfunction
function Trig_Carrier_Dies_Copy_Func006C takes nothing returns boolean
if ( ( GetUnitTypeId(GetDyingUnit()) == 'H00V' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'H000' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'H001' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'Hapm' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'Edem' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'E000' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'Ogrh' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'Opgh' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'Hvwd' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'Usyl' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetDyingUnit()) == 'H00B' ) ) then
return true
endif
return false
endfunction
function Trig_Carrier_Dies_Copy_Conditions takes nothing returns boolean
if ( not ( IsUnitType(GetDyingUnit(), UNIT_TYPE_SUMMONED) == false ) ) then
return false
endif
if ( not ( udg_SeedCarried == 1 ) ) then
return false
endif
if ( not Trig_Carrier_Dies_Copy_Func006C() ) then
return false
endif
return true
endfunction
function Trig_Carrier_Dies_Copy_Func002Func001Func001Func003002 takes nothing returns nothing
call CameraSetEQNoiseForPlayer( GetEnumPlayer(), 5.00 )
endfunction
function Trig_Carrier_Dies_Copy_Func002Func001Func001Func010002 takes nothing returns nothing
call CameraClearNoiseForPlayer( GetEnumPlayer() )
endfunction
function Trig_Carrier_Dies_Copy_Func002Func001Func001Func014002 takes nothing returns nothing
call CameraSetEQNoiseForPlayer( GetEnumPlayer(), 5.00 )
endfunction
function Trig_Carrier_Dies_Copy_Func002Func001Func001Func021002 takes nothing returns nothing
call CameraClearNoiseForPlayer( GetEnumPlayer() )
endfunction
function Trig_Carrier_Dies_Copy_Func002Func001Func001C takes nothing returns boolean
if ( not ( udg_DarkVialFX == 2 ) ) then
return false
endif
return true
endfunction
function Trig_Carrier_Dies_Copy_Func002Func001C takes nothing returns boolean
if ( not ( udg_DarkVialFX == 1 ) ) then
return false
endif
return true
endfunction
function Trig_Carrier_Dies_Copy_Func002C takes nothing returns boolean
if ( not ( IsPlayerInForce(GetOwningPlayer(GetTriggerUnit()), udg_SeedCarrier) == true ) ) then
return false
endif
return true
endfunction
function Trig_Carrier_Dies_Copy_Actions takes nothing returns nothing
set udg_TempLoc = GetUnitLoc(GetDyingUnit())
if ( Trig_Carrier_Dies_Copy_Func002C() ) then
if ( Trig_Carrier_Dies_Copy_Func002Func001C() ) then
set udg_DarkVialFX = 2
else
if ( Trig_Carrier_Dies_Copy_Func002Func001Func001C() ) then
set udg_DarkVialFX = 0
call PlaySoundBJ( gg_snd_DarkBraam )
call TriggerSleepAction( 0.30 )
call ForForce( GetPlayersAll(), function Trig_Carrier_Dies_Copy_Func002Func001Func001Func014002 )
call AddSpecialEffectTargetUnitBJ( "origin", GetDyingUnit(), "Units\\Undead\\Abomination\\AbominationExplosion.mdl" )
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
call TriggerSleepAction( 0.20 )
call QuestMessageBJ( udg_SeedCarrier, bj_QUESTMESSAGE_DISCOVERED, "TRIGSTR_5900" )
call PlaySoundAtPointBJ( gg_snd_Blood_Splatter_Sound_Effect_X, 60.00, udg_TempLoc, 0 )
call CreateNUnitsAtLoc( 1, 'n01G', Player(8), udg_TempLoc, GetRandomReal(0, 360.00) )
call ForForce( GetPlayersAll(), function Trig_Carrier_Dies_Copy_Func002Func001Func001Func021002 )
else
call PlaySoundBJ( gg_snd_MeatSound )
call TriggerSleepAction( 0.30 )
call ForForce( GetPlayersAll(), function Trig_Carrier_Dies_Copy_Func002Func001Func001Func003002 )
call AddSpecialEffectTargetUnitBJ( "origin", GetDyingUnit(), "Units\\Undead\\Abomination\\AbominationExplosion.mdl" )
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
call TriggerSleepAction( 0.20 )
call QuestMessageBJ( udg_SeedCarrier, bj_QUESTMESSAGE_DISCOVERED, "TRIGSTR_5899" )
call PlaySoundAtPointBJ( gg_snd_Blood_Splatter_Sound_Effect_X, 60.00, udg_TempLoc, 0 )
call CreateNUnitsAtLoc( 1, 'n01E', Player(8), udg_TempLoc, GetRandomReal(0, 360.00) )
call ForForce( GetPlayersAll(), function Trig_Carrier_Dies_Copy_Func002Func001Func001Func010002 )
endif
endif
else
endif
call RemoveLocation(udg_TempLoc)
endfunction
//===========================================================================
function InitTrig_Carrier_Dies_Copy takes nothing returns nothing
set gg_trg_Carrier_Dies_Copy = CreateTrigger( )
call DisableTrigger( gg_trg_Carrier_Dies_Copy )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Carrier_Dies_Copy, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( gg_trg_Carrier_Dies_Copy, Condition( function Trig_Carrier_Dies_Copy_Conditions ) )
call TriggerAddAction( gg_trg_Carrier_Dies_Copy, function Trig_Carrier_Dies_Copy_Actions )
endfunction
globals
unit udg_DashCaster = null
real udg_DashDuration = 0.2
real udg_DashTotalDistance = 650.0
real udg_DashTimePassed = 0.0
real udg_DashAngle = 0.0
timer udg_DashTimer = null
location udg_DashTarget = null
endglobals
function EasedProgress takes real t returns real
if t < 0.5 then
return 2.0 * t * t
endif
return -1.0 + (4.0 - 2.0 * t) * t
endfunction
function DashUpdate takes nothing returns nothing
local real progress
local real eased
local real newX
local real newY
if udg_DashCaster == null or not IsUnitAliveBJ(udg_DashCaster) then
call PauseTimer(udg_DashTimer)
call DestroyTimer(udg_DashTimer)
set udg_DashTimer = null
call RemoveLocation(udg_DashTarget)
set udg_DashCaster = null
return
endif
set udg_DashTimePassed = udg_DashTimePassed + 0.03
set progress = udg_DashTimePassed / udg_DashDuration
if progress >= 1.0 then
call SetUnitTimeScale(udg_DashCaster, 1.0)
call SetUnitAnimation(udg_DashCaster, "walk")
call SetUnitFacing(udg_DashCaster, udg_DashAngle)
call PauseTimer(udg_DashTimer)
call DestroyTimer(udg_DashTimer)
set udg_DashTimer = null
call RemoveLocation(udg_DashTarget)
set udg_DashCaster = null
return
endif
set eased = EasedProgress(progress)
set newX = GetUnitX(udg_DashCaster) + (Cos(udg_DashAngle * bj_DEGTORAD) * udg_DashTotalDistance * 0.03 / udg_DashDuration)
set newY = GetUnitY(udg_DashCaster) + (Sin(udg_DashAngle * bj_DEGTORAD) * udg_DashTotalDistance * 0.03 / udg_DashDuration)
call SetUnitPosition(udg_DashCaster, newX, newY)
endfunction
function InitDash takes unit caster, location target returns nothing
local real angle
local sound whoosh
if udg_DashTimer != null then
call PauseTimer(udg_DashTimer)
call DestroyTimer(udg_DashTimer)
set udg_DashTimer = null
endif
set udg_DashCaster = caster
set udg_DashTarget = target
set udg_DashTimePassed = 0.0
set angle = Atan2(GetLocationY(target) - GetUnitY(caster), GetLocationX(target) - GetUnitX(caster))
set udg_DashAngle = angle * bj_RADTODEG
call SetUnitFacing(udg_DashCaster, udg_DashAngle + 10)
call SetUnitAnimationByIndex(caster, 1)
call SetUnitTimeScale(caster, 0.01)
set udg_DashTimer = CreateTimer()
call TimerStart(udg_DashTimer, 0.03, true, function DashUpdate)
endfunction
function DashCastCondition takes nothing returns boolean
return GetSpellAbilityId() == 'A06O'
endfunction
function DashCastAction takes nothing returns nothing
call InitDash(GetTriggerUnit(), GetSpellTargetLoc())
endfunction
function InitTrig_DashSystem takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function DashCastCondition))
call TriggerAddAction(t, function DashCastAction)
endfunction
globals
unit udg_BackDashCaster = null
real udg_BackDashDistance = 450.0
real udg_BackDashDuration = 0.2
real udg_BackDashTimePassed = 0.0
real udg_BackDashAngle = 0.0
timer udg_BackDashTimer = null
endglobals
// Easing function for smooth movement
function BackDashEase takes real t returns real
if t < 0.5 then
return 2.0 * t * t
endif
return -1.0 + (4.0 - 2.0 * t) * t
endfunction
// Periodic movement update
function BackDashUpdate takes nothing returns nothing
local real progress
local real eased
local real newX
local real newY
if udg_BackDashCaster == null or not IsUnitAliveBJ(udg_BackDashCaster) then
call PauseTimer(udg_BackDashTimer)
call DestroyTimer(udg_BackDashTimer)
set udg_BackDashTimer = null
set udg_BackDashCaster = null
return
endif
set udg_BackDashTimePassed = udg_BackDashTimePassed + 0.03
set progress = udg_BackDashTimePassed / udg_BackDashDuration
if progress >= 1.0 then
// Restore normal animation and end
call SetUnitTimeScale(udg_BackDashCaster, 1.0)
call SetUnitAnimation(udg_BackDashCaster, "throw")
call SetUnitFacing(udg_BackDashCaster, udg_BackDashAngle)
call PauseTimer(udg_BackDashTimer)
call DestroyTimer(udg_BackDashTimer)
set udg_BackDashTimer = null
set udg_BackDashCaster = null
return
endif
set eased = BackDashEase(progress)
set newX = GetUnitX(udg_BackDashCaster) + (Cos(udg_BackDashAngle * bj_DEGTORAD) * udg_BackDashDistance * 0.03 / udg_BackDashDuration)
set newY = GetUnitY(udg_BackDashCaster) + (Sin(udg_BackDashAngle * bj_DEGTORAD) * udg_BackDashDistance * 0.03 / udg_BackDashDuration)
call SetUnitPosition(udg_BackDashCaster, newX, newY)
endfunction
// Initializes and starts the backward dash
function StartBackDash takes unit caster, location target returns nothing
local real angle
local sound whoosh
set udg_BackDashCaster = caster
set udg_BackDashTimePassed = 0.0
set angle = Atan2(GetLocationY(target) - GetUnitY(caster), GetLocationX(target) - GetUnitX(caster))
set angle = angle + bj_PI // Reverse direction
set udg_BackDashAngle = angle * bj_RADTODEG
// Tilt unit slightly back
call SetUnitFacing(caster, udg_BackDashAngle - 10)
// Lock run animation
call SetUnitAnimationByIndex(caster, 2)
call SetUnitTimeScale(caster, 0.0)
// Start smooth dash
set udg_BackDashTimer = CreateTimer()
call TimerStart(udg_BackDashTimer, 0.03, true, function BackDashUpdate)
endfunction
function BackDashCondition takes nothing returns boolean
return GetSpellAbilityId() == 'A05T' // Replace with your Back Dash ability ID
endfunction
function BackDashAction takes nothing returns nothing
call StartBackDash(GetTriggerUnit(), GetSpellTargetLoc())
endfunction
function InitTrig_BackDashSystem takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function BackDashCondition))
call TriggerAddAction(t, function BackDashAction)
endfunction
function ShakeCameraForPlayer takes player p returns nothing
if GetLocalPlayer() == p then
call CameraSetSourceNoise(10.0, 1.00)
call CameraSetTargetNoise(10.0, 1.00)
endif
endfunction
function Trig_ArrowRain_Sound takes nothing returns nothing
local location targetLoc = GetSpellTargetLoc()
local unit caster = GetTriggerUnit()
local player p = GetOwningPlayer(caster)
local sound s = CreateSound("war3mapImported\\ArrowRain.wav", false, false, false, 10, 10, "")
// Play sound at target location
call SetSoundPosition(s, GetLocationX(targetLoc), GetLocationY(targetLoc), 0.0)
call SetSoundDistanceCutoff(s, 2500.0)
call SetSoundVolume(s, 127)
call SetSoundPitch(s, 0.95 + GetRandomReal(0.0, 0.1))
call StartSound(s)
call KillSoundWhenDone(s)
// Local camera shake for caster only
call ShakeCameraForPlayer(p)
// Clean up
call RemoveLocation(targetLoc)
endfunction
function Condition_ArrowRain takes nothing returns boolean
return GetSpellAbilityId() == 'A07D'
endfunction
function InitTrig_ArrowRain_Sound takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function Condition_ArrowRain))
call TriggerAddAction(t, function Trig_ArrowRain_Sound)
endfunction
globals
unit udg_WarriorLeapCaster = null
timer udg_WarriorLeapTimer = null
real udg_WarriorLeapDuration = 0.15
real udg_WarriorLeapDistance = 430.0
real udg_WarriorLeapHeight = 45.0
real udg_WarriorLeapTimePassed = 0.0
real udg_WarriorLeapAngle = 45.0
endglobals
function WarriorLeap_Update takes nothing returns nothing
local real t = udg_WarriorLeapTimePassed / udg_WarriorLeapDuration
local real easedX = Cos(udg_WarriorLeapAngle * bj_DEGTORAD)
local real easedY = Sin(udg_WarriorLeapAngle * bj_DEGTORAD)
local real x
local real y
local real zOffset
if udg_WarriorLeapCaster == null or not IsUnitAliveBJ(udg_WarriorLeapCaster) then
call PauseTimer(udg_WarriorLeapTimer)
call DestroyTimer(udg_WarriorLeapTimer)
set udg_WarriorLeapTimer = null
set udg_WarriorLeapCaster = null
return
endif
set udg_WarriorLeapTimePassed = udg_WarriorLeapTimePassed + 0.03
if t >= 1.0 then
call PauseTimer(udg_WarriorLeapTimer)
call DestroyTimer(udg_WarriorLeapTimer)
set udg_WarriorLeapTimer = null
call UnitRemoveAbility(udg_WarriorLeapCaster, 'Amrf') // Remove crow form
call SetUnitFlyHeight(udg_WarriorLeapCaster, 0.0, 9999.0)
call SetUnitTimeScale(udg_WarriorLeapCaster, 1.0)
call SetUnitAnimation(udg_WarriorLeapCaster, "stand")
set udg_WarriorLeapCaster = null
return
endif
set x = GetUnitX(udg_WarriorLeapCaster) + (udg_WarriorLeapDistance * easedX * 0.03 / udg_WarriorLeapDuration)
set y = GetUnitY(udg_WarriorLeapCaster) + (udg_WarriorLeapDistance * easedY * 0.03 / udg_WarriorLeapDuration)
set zOffset = 4 * udg_WarriorLeapHeight * t * (1.0 - t)
call SetUnitFlyHeight(udg_WarriorLeapCaster, zOffset, 0.0)
call SetUnitPosition(udg_WarriorLeapCaster, x, y)
call SetUnitAnimation(udg_WarriorLeapCaster, "attack")
endfunction
function WarriorLeap_Start takes unit caster, location target returns nothing
local real angle
if udg_WarriorLeapTimer != null then
call PauseTimer(udg_WarriorLeapTimer)
call DestroyTimer(udg_WarriorLeapTimer)
set udg_WarriorLeapTimer = null
endif
set udg_WarriorLeapCaster = caster
set udg_WarriorLeapTimePassed = 0.0
set angle = Atan2(GetLocationY(target) - GetUnitY(caster), GetLocationX(target) - GetUnitX(caster))
set udg_WarriorLeapAngle = angle * bj_RADTODEG
call UnitAddAbility(caster, 'Amrf') // Apply crow form
call UnitRemoveAbility(caster, 'Amrf')
call SetUnitFlyHeight(caster, 0.0, 9999.0)
call SetUnitFacing(caster, udg_WarriorLeapAngle)
call SetUnitAnimation(caster, "attack slam")
call SetUnitTimeScale(caster, 0.001) // Freeze animation
set udg_WarriorLeapTimer = CreateTimer()
call TimerStart(udg_WarriorLeapTimer, 0.03, true, function WarriorLeap_Update)
endfunction
function WarriorLeap_Condition takes nothing returns boolean
return GetSpellAbilityId() == 'A07E'
endfunction
function WarriorLeap_Action takes nothing returns nothing
call WarriorLeap_Start(GetTriggerUnit(), GetSpellTargetLoc())
endfunction
function InitTrig_WarriorLeap takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i >= bj_MAX_PLAYERS
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function WarriorLeap_Condition))
call TriggerAddAction(t, function WarriorLeap_Action)
endfunction
globals
constant integer ABILITY_MOMENTUM = 'S002' // Buff ability (hidden aura or dummy buff)
constant integer UNIT_DEMONHUNTER = 'E000'
constant integer UNIT_ECHO_DEMONHUNTER = 'Edem'
unit udg_MomentumUnit = null
endglobals
function RemoveMomentum takes nothing returns nothing
call UnitRemoveAbility(udg_MomentumUnit, ABILITY_MOMENTUM)
set udg_MomentumUnit = null
endfunction
function ApplyMomentumBurst takes unit u returns nothing
set udg_MomentumUnit = u
call UnitAddAbility(u, ABILITY_MOMENTUM)
call UnitMakeAbilityPermanent(u, false, ABILITY_MOMENTUM)
call TimerStart(CreateTimer(), 1.0, false, function RemoveMomentum)
endfunction
function MomentumBurst_Condition takes nothing returns boolean
local integer id = GetUnitTypeId(GetOrderedUnit())
local integer order = GetIssuedOrderId()
return (id == UNIT_DEMONHUNTER or id == UNIT_ECHO_DEMONHUNTER) and (order == OrderId("move") or order == OrderId("smart"))
endfunction
function MomentumBurst_Action takes nothing returns nothing
call ApplyMomentumBurst(GetOrderedUnit())
endfunction
function InitTrig_MomentumBurst takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i >= bj_MAX_PLAYERS
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function MomentumBurst_Condition))
call TriggerAddAction(t, function MomentumBurst_Action)
endfunction
globals
hashtable udg_VoidPulseTable = InitHashtable()
integer SPELLS_PER_PULSE = 5
endglobals
function VoidPulse_Trigger takes nothing returns nothing
local unit caster = GetTriggerUnit()
local integer unitId = GetUnitTypeId(caster)
local integer id = GetHandleId(caster)
local integer count = LoadInteger(udg_VoidPulseTable, id, 0)
local group g
local unit u
local real x = GetUnitX(caster)
local real y = GetUnitY(caster)
local real angle
// Only apply to Voidmage units
if unitId != 'Ogrh' and unitId != 'Opgh' then
return
endif
// Update cast count
set count = count + 1
call SaveInteger(udg_VoidPulseTable, id, 0, count)
if count >= SPELLS_PER_PULSE then
call SaveInteger(udg_VoidPulseTable, id, 0, 0) // reset counter
// Visual FX
call DestroyEffect(AddSpecialEffect("war3mapImported\\Arcane Explosion.mdx", x, y))
// Knockback all units around
set g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 420.0, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
if IsUnitAliveBJ(u) and u != caster and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
set angle = Atan2(GetUnitY(u) - y, GetUnitX(u) - x)
call SetUnitPosition(u, GetUnitX(u) + Cos(angle) * 60.0, GetUnitY(u) + Sin(angle) * 60.0)
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
endif
endfunction
function InitTrig_VoidPulse takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(t, function VoidPulse_Trigger)
endfunction
function Trig_Pulsating_organ_enters_Conditions takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == 'n01F'
endfunction
function Trig_Pulsating_organ_enters_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local location loc = GetUnitLoc(u)
call BlzSetUnitFacingEx(u, GetRandomReal(0.0, 360.0))
call SetTerrainTypeBJ(loc, 'Zdtr', -1, 1, 0)
call SetBlightRadiusLocBJ(true, Player(15), loc, 70.0)
call RemoveLocation(loc)
set loc = null
set u = null
endfunction
//===========================================================================
function InitTrig_Pulsating_organ_enters takes nothing returns nothing
set gg_trg_Pulsating_organ_enters = CreateTrigger()
call TriggerRegisterEnterRectSimple(gg_trg_Pulsating_organ_enters, GetPlayableMapRect())
call TriggerAddCondition(gg_trg_Pulsating_organ_enters, Condition(function Trig_Pulsating_organ_enters_Conditions))
call TriggerAddAction(gg_trg_Pulsating_organ_enters, function Trig_Pulsating_organ_enters_Actions)
endfunction
globals
constant integer ITEM_ID_PENANCE_ARMOR = 'I02Z'
constant integer ABIL_ID_PENANCE_TAG = 'A00F'
constant real PENANCE_BLEED_DAMAGE = 500.00
timer PenanceTimer = null
unit PenanceBearer = null
endglobals
function UnitHasAbility takes unit u, integer abilId returns boolean
return GetUnitAbilityLevel(u, abilId) > 0
endfunction
function Penance_BleedTick takes nothing returns nothing
if PenanceBearer != null and IsUnitAliveBJ(PenanceBearer) and UnitHasItemOfTypeBJ(PenanceBearer, ITEM_ID_PENANCE_ARMOR) then
call UnitDamageTarget(PenanceBearer, PenanceBearer, PENANCE_BLEED_DAMAGE, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl", PenanceBearer, "chest"))
else
// Stop bleeding if armor is removed or bearer is dead
call PauseTimer(PenanceTimer)
call DestroyTimer(PenanceTimer)
set PenanceTimer = null
set PenanceBearer = null
endif
endfunction
function Penance_CheckArmor takes nothing returns nothing
local unit u = GetTriggerUnit()
local item it
local integer i = 0
// Check for the armor
loop
exitwhen i >= bj_MAX_INVENTORY
set it = UnitItemInSlot(u, i)
if it != null and GetItemTypeId(it) == ITEM_ID_PENANCE_ARMOR then
if not UnitHasAbility(u, ABIL_ID_PENANCE_TAG) then
call UnitAddAbility(u, ABIL_ID_PENANCE_TAG)
endif
// Start bleed if not already running
if PenanceTimer == null then
set PenanceBearer = u
set PenanceTimer = CreateTimer()
call TimerStart(PenanceTimer, 1.00, true, function Penance_BleedTick)
endif
return
endif
set i = i + 1
endloop
// If no armor found but this unit is current bearer, stop bleed
if u == PenanceBearer then
call PauseTimer(PenanceTimer)
call DestroyTimer(PenanceTimer)
set PenanceTimer = null
set PenanceBearer = null
endif
endfunction
function InitTrig_PenanceArmor takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM)
call TriggerAddAction(t, function Penance_CheckArmor)
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DROP_ITEM)
call TriggerAddAction(t, function Penance_CheckArmor)
endfunction
function Trig_HideUI_Actions takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
call EnableUserUI(false)
endif
endfunction
function InitTrig_HideUI takes nothing returns nothing
set gg_trg_HideUI = CreateTrigger()
call TriggerRegisterPlayerChatEvent(gg_trg_HideUI, Player(0), "-hideui", true)
call TriggerRegisterPlayerChatEvent(gg_trg_HideUI, Player(1), "-hideui", true)
call TriggerRegisterPlayerChatEvent(gg_trg_HideUI, Player(2), "-hideui", true)
// Add more players as needed
call TriggerAddAction(gg_trg_HideUI, function Trig_HideUI_Actions)
endfunction