1. Are you planning to upload your awesome map to Hive? Please review the rules here.
    Dismiss Notice
  2. Find your way through the deepest dungeon in the 18th Mini Mapping Contest Poll.
    Dismiss Notice
  3. A brave new world lies beyond the seven seas. Join the 34th Modeling Contest today!
    Dismiss Notice
  4. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
Hive 3 Remoosed BETA - NOW LIVE. Go check it out at BETA Hive Workshop! Post your feedback in this new forum BETA Feedback.
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Trigger Viewer

(12)DivideAndConquerThirdAgev1.4.0.w3x
Variables
Variables
AllTriggers
Init/Map Stuff
Initialisation
AlteredMeleeInit
OtherStuff
SpellLibraries
Unit Event
Unit Event Config
Unit Event
Spell Fixes
Life Drain Fix
Finger of Death Fix
Anti Magic Shield Fix
Mana Shield Fix
Damage Engine
---------------------------
Damage Engine Config
Unit In Action
Is Unit Moving Config
Is Unit Moving
Unit In Action
Unit Inaction
GDD
GDD Variable Creator
GUI Friendly Damage Detection
GUI Knockback System [Paladon]
Knockback
Cast A Knockback
Get Knockback
Races
UniversalAbilityInit
UniversalAbilityInit
BloodElfRaceStuff
BEDemonHunterAbilities
GlaiveThrow
Chain Sword On
Chain Sword Loop
DestroyMana
DestroyMana
Ignite
Ignite
TheHunt
TheHunt
BloodMageAbilities
SanguineBolt
SanguineBolt
Dualcasting
DualPhoenixbolt
DualSanguineBolt
RangerCaptainAbilities
BurstingTarTrap
BurstingTarTrap
TrickShot
TrickShot
BloodKnightAbilities
LightsReckoning
LightsReckoning
SearingLight
SearingLight
BloodElfStuff
PhoenixFireSpawn
PhoenixFireStart
ASA Activate Deactivate
ASA Event
ASA Prevent
BH Event
Activate
Cancel
ArcaneDestruct
ManaSeeking
DivineAegis
HolyArmour
SeveringStride
NagaRaceStuff
NagaChampionAbilities
VenomSwipe
VenomSwipe
VenomSwipeOff
VenomSwipeDeath
RoyalGuard
RoyalGuardStart
RoyalGuard1
RoyalGuard2
RoyalGuard3
UndyingWill
UndyingWill
NagaEnchantressAbilities
TerrorOfTheTides
TerrorOfTheTides
DrownTheWeak
DrownTheWeak1
DrownTheWeak2
DrownTheWeak3
Dimebolt
Dimebolt
DimeboltRapid
MendingRapids
MendingRapids
MendingRapidsStop
IllidariDemonHunterAbilities
MindBomb
MindBomb
SoulSiphon
SoulSiphon
SpellNegation
SpellNegation
HighborneSorcerorAbilities
FeedTheHunger
FeedTheHunger
Ethereality
Ethereality
IcicleLance
IcicleLance
NagaThings
CoralReefStart
CoralReefEnd
PetrifyDamage
Shatter
DemonRaceStuff
AdremmelechToxophiliteAbilities
FlunctuatingDestiny
FlunctuatingDestiny
PentagramAura
PentagramAuraOn
PentagramAuraOff
PentagramAuraPeriodic
PentagramAuraDelete
DevilishPower
DevilishPowerAdd
DevilishPowerPeriodic
DevilishPowerKO
DemonEyes
DemonEyes
EredarAnnihilator
HandOfGuldan
HandOfGuldan
WildImpExpire
WildImpBoom
SoulLeech
SoulLeech
Soulstone
SoulstoneGroupAdd
SoulstonePeriodic
SoulstoneLv1KO
SoulstoneLv2KO
SoulstoneLv3KO
SacrificialPawn
SacrificialPawn
MoargOverlordAbilities
Intimidate
Intimidate
WildSlam
WildSlam
EarthshakingStomp
SOC Cast
SOC Loop
EmberKnightAbilities
ChaosEmbers
ChaosEmbers
TorrentialFlameAura
TorrentialFlameAuraOn
TorrentialFlameAuraOff
TorrentialFlameAuraPeriodic
TorrentialFlameAuraDelete
PyricBash
PyricBash
RagingFissure
RagingFissure
DemonThings
Zergling Double Up
Zergling Dies
Defilement
SeduceEvent
DrainEssence
PiercingGaze
ChaosOrcsRaceStuff
ChaosOrcWarlordAbilities
DemonsBlood
DemonsBlood
AxeFlurry
AxeFlurry
EphemeralBlaze
EphemeralBlaze
ChaosOrcBlademasterAbilities
CounterAttack
CounterAttack
BurningBlade
BurningBlade
ScentOfBlood
ScentOfBlood
ScentOfBloodLv2
ScentOfBloodLv3
UnholyArmour
UnholyArmourCast
UnholyArmour
MortalCoil
MortalCoil
MortalCoilBuffDetect
BatheInBlood
BatheInBlood
OgreMageRunes
OgreMageRunes
CorruptedRaceStuff
NightmareKeeperAbilities
Dissonance
Dissonance
ContradictionAura
ContradictionAura1
ContradictionAura2
ContradictionAura3
ThornyBinds
ThornyBinds1
ThornyBinds2
ThornyBinds3
SatyrWitchAbilities
PhantasmicAura
PhantasmicAura1
PhantasmicAura2
PhantasmicAura3
HandOfPain
HandOfPain
SatyrIncineratorAbilities
Singe
Singe
Hellfire
Hellfire
CauterisingFlame
CauterisingFlame
CauterisingFlameDummy
CleansingFires
CleansingFires
SkeletonKingAbilities
SendToTheVoid
SendToTheVoid
BeyondTheGrave
BeyondTheGrave
Abnegation
Abnegation
Purgatory
PurgatoryActive
PurgatoryPeriodic
PurgatoryKO
Purgatory1
PurgatoryTimerExpire
CorruptedStuff
CorruptedInitStuff
CorruptedBuildingTerrainSmall
CorruptedBuildingTerrainLarge
HelotSacrifice
InhabitBody
Retalliation
PassAdd
PassPeriodic
PassKO
MiasmaDeltaAdd
MiasmaDeltaPeriodic
MiasmaDeltaKO
BansheeTheta
DarkSpikesTauAdd
DarkSpikesTauPeriodic
DarkSpikesTauKO
TerrorOfTheSkies
Shriek
UmbralBloodAdd
UmbralBloodPeriodic
UmbralBloodKO
UnholyPresenceAdd
UnholyPresencePeriodic
UnholyPresenceKO
SwarmZeta
Defender
ManaSear
TasteForMagic
DefiledWaterAdd
DefiledWaterPeriodic
DefiledWaterKO
DefiledWaterRightClick
FireVulnerability
AbsorbTreeAdd
AbsorbTreePeriodic
AbsorbTreeKO
Wrath
CREEPRaceStuff
CREEPAIStuff
CREEPBuildingIntegers
CREEPBuildingIntegers
CREEPBuildingIntegersInit
CREEPAIGnollBrute
CREEPAIGnollOverseer
CREEPAIGnollWarden
CREEPAIGnollAssassin
CREEPAIHarpyRogue
CREEPAIHarpyWindwitch
CREEPAIHarpyStormhag
CREEPAIHarpyQueen
CREEPAICentaurImpaler
CREEPAICentaurSorceror
CREEPAICentaurKhan
CREEPAIDarkTrollShadowPriest
CREEPAIDarkTrollTrapper
CREEPAIDarkTrollHighPriest
CREEPAIDarkTrollWarlord
StormwindHumansRaceStuff
LionheartAbilities
ColossusSmash
ColossusSmash1
ColossusSmash2
ColossusSmash3
ColossusSmash4
LionsFang
LionsFang
PressTheAttack
PressTheAttack
BannerOfStormwind
BannerOfStormwind
CommanderAbilities
ShieldSlam
ShieldSlam
LastStand
LastStand
LastStandPeriodic
LastStandKO
StalwartAbilities
BindingBlade
BindingBlade
VeilOfLight
VeilOfLight
Abraxas
Abraxas
SageAbilities
CometStorm
CometStorm
DragonsBreath
DragonsBreath
ArcaneIntellect
ArcaneIntellect
TimeWarp
TimeWarp
HolyKnightAbilities
Fortify
Fortify
HolySword
HolySword
AuraMastery
AuraMasteryAdd
AuraMasteryPeriodic
AuraMasteryKO
StormwindHumanThings
SkyshipTurretsSpawn
SkyshipTurretsStart
Exorcism
HealingDischarge
Redemption
Kul'tirasRaceStuff
AdmiralAbilities
FrigateBarrage
SpawnFrigate
FrigateMovement
XMarksTheEnemy
XMarksTheEnemy1
XMarksTheEnemy2
XMarksTheEnemy3
SummonTheKraken
SummonTheKraken
TidesageAbilities
WakeOfTheStorm
WakeOfTheStorm
WaterStream
WaterStreamStart
WaterStream1
WaterStream2
WaterStream3
SwiftReinforcementWards
SwiftReinforcementWards
Whirlpool
WP spell init
WP spell cast
WP spell loop
HeartsbaneWitchAbilities
SoulManipulation
PossessAUnit
DurationCheck
SoulManipulation
WitheringHeart
WitheringHeartAdd
WitheringHeartPeriodic
WitheringHeartKO
InquisitorOfEmbersAbilities
SilverSmite
SilverSmite
AlchemicalFire
AlchemicalFire
InquisitorsVigor
InquisitorsVigor
InquisitorsVigorRampUp
InquisitorsVigorKO
WitchbaneCircle
WitchbaneCircle
Kul'tirasHumanThings
AdmiraltyShieldBash
SaberSlash
MortalStrikes
Plunder
Absorption
SeaSickness
Rebirth
NullifyingBellow
PotentGunpowder
Charge
NightsRest
NightsRestAttacked
BronzebeardDwarfRaceStuff
MountainKingAbilities
StormBolt
StormBoltLearn
StormBoltChargeup
StormBoltLine
StormBoltReset
KingsWarCry
KingsWarCry
ResoundingThunder
ResoundingThunderCast
ResoundingThunderAttack
Avatar2
Avatar2
Avatar2Off
Avatar2Death
StoneheartAbilities
SummonEarthElemental
EarthElementalTaunt
EarthShield
EarthShield1
EarthShield2
EarthShield3
StormAxe
StormAxe
StormAxeChainLightning
SetTotems
SetTotems
CounterstrikeTotem
StormstriderAbilities
StormstrikeEnchantment
StormstrikeEnchantment1
StormstrikeEnchantment2
StormstrikeEnchantment3
CrashLightning
CrashLightning
CrashLightningOff
CrashLightningDeath
SolidityAura
SolidityAuraOn
SolidityAuraOff
SolidityAuraPeriodic
SolidityAuraDelete
TheOncomingStorm
TheOncomingStorm
TheOncomingStormOff
TheOncomingStormDeath
Sharpshooter
DisruptionShot
DisruptionShot
ArmourslayerAura
ArmourslayerAuraOn
ArmourslayerAuraOff
ArmourslayerAuraPeriodic
ArmourslayerAuraDelete
Gamble
Gamble
DwarfRaceThings
StoneformAdd
StoneformPeriodic
StoneformKO
EnhancedStoneformResearch
EnhancedStoneform
AxeThrow
MightySwing
SiegeTankLoad
SiegeTankUnload
Dismantle
GuardianTowerLoad
GuardianTowerUnload
DropBombs
FlashOfLight
BlessingOfMightAdd
BlessingOfMightPeriodic
BlessingOfMightKO
Thrash
ThickHide
Debilitate
RuneBreak
BreakerRuneSpawn
BreakerRunePeriodic
RuneOfSicknessSpawn
RuneOfSicknessMiss
ShellRuneSpawn
ShellRuneOn
ShellRuneOff
ShellRunePeriodic
ShellRuneDelete
Salvage
//===========================================================================
// Customised Blizzard.j excerpt! ( define Jass2 functions that need to be in every map script )
//===========================================================================
function Custom_MeleeStartingHeroLimit takes nothing returns nothing
    local integer index

    set index = 0
    loop
        // max heroes per player
        call SetPlayerMaxHeroesAllowed(bj_MELEE_HERO_LIMIT, Player(index))

        // each player is restricted to a limit per hero type as well
	// Lordaeron Human Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Hamg', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hmkg', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hpal', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hblm', bj_MELEE_HERO_TYPE_LIMIT)

	//Blood Elf Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'E00E', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'H049', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'H020', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'N03J', bj_MELEE_HERO_TYPE_LIMIT)

	//Stormwind Human Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Hart', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hdgo', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Harf', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hant', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hhkl', bj_MELEE_HERO_TYPE_LIMIT)

	//Dwarf Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Hmbr', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hvwd', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hjai', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hlgr', bj_MELEE_HERO_TYPE_LIMIT)

	//Kul'tiras Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Hapm', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Odrt', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hpb1', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hgam', bj_MELEE_HERO_TYPE_LIMIT)

	//Orc Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Obla', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Ofar', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Otch', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Oshd', bj_MELEE_HERO_TYPE_LIMIT)

	//Chaos Orc Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Nbbc', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Opgh', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Othr', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Orkn', bj_MELEE_HERO_TYPE_LIMIT)

	//Undead Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Edem', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Ekee', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Emoo', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Ewar', bj_MELEE_HERO_TYPE_LIMIT)

	//Demon Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Npld', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Nklj', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Usyl', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Uanb', bj_MELEE_HERO_TYPE_LIMIT)

	//Black Empire Heroes





	//Shadow Elf Heroes





	//Night Elf Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Udea', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Udre', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Ulic', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Ucrl', bj_MELEE_HERO_TYPE_LIMIT)

	//Naga Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Hkal', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Eevi', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Ocbh', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Hvsh', bj_MELEE_HERO_TYPE_LIMIT)

	//Corrupt Night Elf Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'O03D', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Nmag', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Ekgg', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Efur', bj_MELEE_HERO_TYPE_LIMIT)

	//Neutral Heroes
        call ReducePlayerTechMaxAllowed(Player(index), 'Npbm', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Nbrn', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Nngs', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Nplh', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Nbst', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Nalc', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Ntin', bj_MELEE_HERO_TYPE_LIMIT)
        call ReducePlayerTechMaxAllowed(Player(index), 'Nfir', bj_MELEE_HERO_TYPE_LIMIT)

        set index = index + 1
        exitwhen index == bj_MAX_PLAYERS
    endloop
endfunction

//===========================================================================
// Starting Units for Human Players
//   - 1 Town Hall, placed at start location
//   - 5 Peasants, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsHuman takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY
    local unit     townHall = null

    if (doPreload) then
        call Preloader( "scripts\\HumanMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'htow', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'hpea', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'hpea', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'hpea', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'hpea', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'hpea', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'htow', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'hpea', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'hpea', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'hpea', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'hpea', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'hpea', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (townHall != null) then
        call UnitAddAbilityBJ('Amic', townHall)
        call UnitMakeAbilityPermanentBJ(true, 'Amic', townHall)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Hamg', 'Hmkg', 'Hpal', 'Hblm', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peasants.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Blood Elf Players
//   - 1 Vestibule, placed at start location
//   - 5 Engineers, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsBloodElf takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY
    local unit     townHall = null

    if (doPreload) then
        call Preloader( "scripts\\HumanMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'h01V', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'h000', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h000', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h000', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h000', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h000', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'h01V', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'h000', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h000', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h000', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h000', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h000', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'E00E', 'H049', 'H020', 'N03J', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peasants.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Stormwind Human Players
//   - 1 Municipal Centers, placed at start location
//   - 5 Bucolics, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsStormwind takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY
    local unit     townHall = null

    if (doPreload) then
        call Preloader( "scripts\\HumanMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'h0CT', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'h0C2', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C2', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C2', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C2', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C2', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'h0CT', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'h0C2', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C2', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C2', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C2', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C2', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Hart', 'Hdgo', 'Harf', 'Hant', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peasants.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Dwarf Players
//   - 1 Compound, placed at start location
//   - 5 Miners, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsDwarf takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY
    local unit     townHall = null

    if (doPreload) then
        call Preloader( "scripts\\HumanMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'h0D6', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'h0C7', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C7', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C7', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C7', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C7', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'h0D6', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'h0C7', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C7', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C7', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C7', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C7', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Hmbr', 'Hvwd', 'Hjai', 'Hlgr', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peasants.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Kul'tiras Players
//   - 1 Port Town, placed at start location
//   - 5 Sailors, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsKulTiras takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY
    local unit     townHall = null

    if (doPreload) then
        call Preloader( "scripts\\HumanMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'h0D7', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'h0C8', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C8', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C8', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C8', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C8', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Town Hall at the start location.
        set townHall = CreateUnitAtLoc(whichPlayer, 'h0D7', startLoc, bj_UNIT_FACING)
        
        // Spawn Peasants directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'h0C8', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C8', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C8', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C8', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'h0C8', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Hapm', 'Odrt', 'Hpb1', 'Hgam', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peasants.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Orc Players
//   - 1 Great Hall, placed at start location
//   - 5 Peons, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsOrc takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY

    if (doPreload) then
        call Preloader( "scripts\\OrcMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'ogre', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'opeo', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'opeo', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'opeo', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'opeo', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'opeo', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'ogre', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'opeo', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'opeo', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'opeo', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'opeo', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'opeo', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Obla', 'Ofar', 'Otch', 'Oshd', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peons.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Chaos Orc Players
//   - 1 Chaos Orc Hall, placed at start location
//   - 5 Chaos Orc Peons, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsChaosOrc takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY

    if (doPreload) then
        call Preloader( "scripts\\OrcMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'o02Y', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'ncpn', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ncpn', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ncpn', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ncpn', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ncpn', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'o02Y', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'ncpn', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ncpn', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ncpn', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ncpn', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ncpn', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Nbbc', 'Opgh', 'Othr', 'Orkn', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peons.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Undead Players
//   - 1 Necropolis, placed at start location
//   - 1 Haunted Gold Mine, placed on nearest gold mine
//   - 3 Acolytes, placed between start location and nearest gold mine
//   - 1 Ghoul, placed between start location and nearest gold mine
//   - Blight, centered on nearest gold mine, spread across a "large area"
//
function Custom_MeleeStartingUnitsUndead takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location nearTownLoc
    local location heroLoc
    local real     peonX
    local real     peonY
    local real     ghoulX
    local real     ghoulY

    if (doPreload) then
        call Preloader( "scripts\\UndeadMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Necropolis at the start location.
        call CreateUnitAtLoc(whichPlayer, 'unpl', startLoc, bj_UNIT_FACING)
        
        // Replace the nearest gold mine with a blighted version.
        set nearestMine = BlightGoldMineForPlayerBJ(nearestMine, whichPlayer)

        // Spawn Ghoul near the Necropolis.
        set nearTownLoc = MeleeGetProjectedLoc(startLoc, GetUnitLoc(nearestMine), 288, 0)
        set ghoulX = GetLocationX(nearTownLoc)
        set ghoulY = GetLocationY(nearTownLoc)
        set bj_ghoul[GetPlayerId(whichPlayer)] = CreateUnit(whichPlayer, 'ugho', ghoulX + 0.00 * unitSpacing, ghoulY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Spawn Acolytes near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'uaco', peonX + 0.00 * unitSpacing, peonY + 0.50 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'uaco', peonX + 0.65 * unitSpacing, peonY - 0.50 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'uaco', peonX - 0.65 * unitSpacing, peonY - 0.50 * unitSpacing, bj_UNIT_FACING)

        // Create a patch of blight around the gold mine.
        call SetBlightLoc(whichPlayer,nearMineLoc, 768, true)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Necropolis at the start location.
        call CreateUnitAtLoc(whichPlayer, 'unpl', startLoc, bj_UNIT_FACING)
        
        // Spawn Acolytes and Ghoul directly south of the Necropolis.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'uaco', peonX - 1.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'uaco', peonX - 0.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'uaco', peonX + 0.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ugho', peonX + 1.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Create a patch of blight around the start location.
        call SetBlightLoc(whichPlayer,startLoc, 768, true)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Udea', 'Udre', 'Ulic', 'Ucrl', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Acolytes.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Demon Players
//   - 1 Demon Hall, placed at start location
//   - 5 Demon Slaves, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsDemon takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location nearTownLoc
    local location heroLoc
    local real     peonX
    local real     peonY

    if (doPreload) then
        call Preloader( "scripts\\UndeadMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'o00W', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'u00Z', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'u00Z', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'u00Z', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'u00Z', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'u00Z', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Create a patch of blight around the gold mine.
        call SetBlightLoc(whichPlayer,nearMineLoc, 768, true)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'o00W', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'u00Z', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'u00Z', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'u00Z', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'u00Z', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'u00Z', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Create a patch of blight around the start location.
        call SetBlightLoc(whichPlayer,startLoc, 768, true)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Npld', 'Nklj', 'Usyl', 'Uanb', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peons.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Night Elf Players
//   - 1 Tree of Life, placed by nearest gold mine, already entangled
//   - 5 Wisps, placed between Tree of Life and nearest gold mine
//
function Custom_MeleeStartingUnitsNightElf takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local real     minTreeDist   = 3.50 * bj_CELLWIDTH
    local real     minWispDist   = 1.75 * bj_CELLWIDTH
    local unit     nearestMine
    local location nearMineLoc
    local location wispLoc
    local location heroLoc
    local real     peonX
    local real     peonY
    local unit     tree

    if (doPreload) then
        call Preloader( "scripts\\NightElfMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Tree of Life near the mine and have it entangle the mine.
        // Project the Tree's coordinates from the gold mine, and then snap
        // the X and Y values to within minTreeDist of the Gold Mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 650, 0)
        set nearMineLoc = MeleeGetLocWithinRect(nearMineLoc, GetRectFromCircleBJ(GetUnitLoc(nearestMine), minTreeDist))
        set tree = CreateUnitAtLoc(whichPlayer, 'etol', nearMineLoc, bj_UNIT_FACING)
        call IssueTargetOrder(tree, "entangleinstant", nearestMine)

        // Spawn Wisps at the start location.
        set wispLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set wispLoc = MeleeGetLocWithinRect(wispLoc, GetRectFromCircleBJ(GetUnitLoc(nearestMine), minWispDist))
        set peonX = GetLocationX(wispLoc)
        set peonY = GetLocationY(wispLoc)
        call CreateUnit(whichPlayer, 'ewsp', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ewsp', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ewsp', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ewsp', peonX + 0.58 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ewsp', peonX - 0.58 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Tree of Life at the start location.
        call CreateUnitAtLoc(whichPlayer, 'etol', startLoc, bj_UNIT_FACING)

        // Spawn Wisps directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'ewsp', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ewsp', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ewsp', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ewsp', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'ewsp', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Edem', 'Ekee', 'Emoo', 'Ewar', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Wisps.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Naga Players
//   - 1 Temple of Streams, placed at start location
//   - 5 Mur'gul Slaves, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsNaga takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY

    if (doPreload) then
        call Preloader( "scripts\\NightElfMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'nntt', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'nmpe', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'nmpe', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'nmpe', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'nmpe', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'nmpe', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'nntt', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'nmpe', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'nmpe', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'nmpe', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'nmpe', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'nmpe', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'Hkal', 'Eevi', 'Ocbh', 'Hvsh', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peons.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Corrupt Night Elf Players
//   - 1 Tree of Corruption, placed at start location
//   - 3 Satyr Helots, placed between start location and nearest gold mine
//   - 2 Vile Souls, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsCorruptNightElf takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY

    if (doPreload) then
        call Preloader( "scripts\\NightElfMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'nctl', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'o03N', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o03N', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o03N', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'e02H', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'e02H', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'nctl', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'o03N', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o03N', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o03N', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'e02H', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'e02H', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'O03D', 'Nmag', 'Ekgg', 'Efur', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peons.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for AI Corrupt Night Elf Players
//   - 1 Tree of Corruption, placed at start location
//   - 3 Satyr Helots, placed between start location and nearest gold mine
//   - 2 Vile Souls (AI), placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsCorruptNightElfAI takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY

    if (doPreload) then
        call Preloader( "scripts\\NightElfMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'nctl', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'o03N', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o03N', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o03N', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'e038', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'e038', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'nctl', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'o03N', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o03N', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o03N', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'e038', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'e038', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'O03D', 'Nmag', 'Ekgg', 'Efur', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peons.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Conglomeration of cReeps and Enemies Everywhere Practising vengeance, or CREEP Players
//   - 1 Creep Camp, placed at start location
//   - 3 Drudges, placed between start location and nearest gold mine
//
function Custom_MeleeStartingUnitsCREEP takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local boolean  useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
    local real     unitSpacing   = 64.00
    local unit     nearestMine
    local location nearMineLoc
    local location heroLoc
    local real     peonX
    local real     peonY

    if (doPreload) then
        call Preloader( "scripts\\NightElfMelee.pld" )
    endif

    set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
    if (nearestMine != null) then
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'o03W', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons near the mine.
        set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
        set peonX = GetLocationX(nearMineLoc)
        set peonY = GetLocationY(nearMineLoc)
        call CreateUnit(whichPlayer, 'o003', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o003', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o003', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be off to the side of the start location.
        set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
    else
        // Spawn Great Hall at the start location.
        call CreateUnitAtLoc(whichPlayer, 'o03W', startLoc, bj_UNIT_FACING)
        
        // Spawn Peons directly south of the town hall.
        set peonX = GetLocationX(startLoc)
        set peonY = GetLocationY(startLoc) - 224.00
        call CreateUnit(whichPlayer, 'o003', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o003', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
        call CreateUnit(whichPlayer, 'o003', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)

        // Set random hero spawn point to be just south of the start location.
        set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
    endif

    if (doHeroes) then
        // If the "Random Hero" option is set, start the player with a random hero.
        // Otherwise, give them a "free hero" token.
        if useRandomHero then
            call MeleeRandomHeroLoc(whichPlayer, 'ncnk', 'ngnv', 'ndtw', 'nhrq', heroLoc)
        else
            call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
        endif
    endif

    if (doCamera) then
        // Center the camera on the initial Peons.
        call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
        call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
    endif
endfunction

//===========================================================================
// Starting Units for Players Whose Race is Unknown
//   - 12 Sheep, placed randomly around the start location
//
function Custom_MeleeStartingUnitsUnknownRace takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
    local integer index

    if (doPreload) then
    endif

    set index = 0
    loop
        call CreateUnit(whichPlayer, 'nshe', GetLocationX(startLoc) + GetRandomReal(-256, 256), GetLocationY(startLoc) + GetRandomReal(-256, 256), GetRandomReal(0, 360))
        set index = index + 1
        exitwhen index == 12
    endloop

    if (doHeroes) then
        // Give them a "free hero" token, out of pity.
        call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
    endif

    if (doCamera) then
        // Center the camera on the initial sheep.
        call SetCameraPositionLocForPlayer(whichPlayer, startLoc)
        call SetCameraQuickPositionLocForPlayer(whichPlayer, startLoc)
    endif
endfunction

//===========================================================================
function Custom_MeleeStartingUnits takes nothing returns nothing
    local integer  index
    local player   indexPlayer
    local location indexStartLoc
    local race     indexRace

    call Preloader( "scripts\\SharedMelee.pld" )

    set index = 0
    loop
        set indexPlayer = Player(index)
        if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
            set indexStartLoc = GetStartLocationLoc(GetPlayerStartLocation(indexPlayer))
            set indexRace = GetPlayerRace(indexPlayer)

            // Create initial race-specific starting units
	    if (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM) and (GetPlayerHandicap (indexPlayer) <= 0.90 )) then
				call Custom_MeleeStartingUnitsCREEP(indexPlayer, indexStartLoc, true, true, true)
				call SetPlayerFlagBJ( PLAYER_STATE_GIVES_BOUNTY, true, indexPlayer )
            			if (GetPlayerController(indexPlayer) != MAP_CONTROL_COMPUTER) then
					call SetPlayerHandicap(indexPlayer, 1.00)
				endif
	    elseif (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM) and (GetRandomInt(1, 13) == 13 )) then
				call Custom_MeleeStartingUnitsCREEP(indexPlayer, indexStartLoc, true, true, true)
				call SetPlayerFlagBJ( PLAYER_STATE_GIVES_BOUNTY, true, indexPlayer )
				call PickMeleeAI(indexPlayer, "creep.ai", null, null)
            elseif (indexRace == RACE_HUMAN) then
			if (GetPlayerHandicap (indexPlayer) <= 0.60 ) then
				call Custom_MeleeStartingUnitsKulTiras(indexPlayer, indexStartLoc, true, true, true)
            			if (GetPlayerController(indexPlayer) != MAP_CONTROL_COMPUTER) then
					call SetPlayerHandicap(indexPlayer, 1.00)
				endif
			elseif (GetPlayerHandicap (indexPlayer) <= 0.70 ) then
				call Custom_MeleeStartingUnitsDwarf(indexPlayer, indexStartLoc, true, true, true)
            			if (GetPlayerController(indexPlayer) != MAP_CONTROL_COMPUTER) then
					call SetPlayerHandicap(indexPlayer, 1.00)
				endif
			elseif (GetPlayerHandicap (indexPlayer) <= 0.80 ) then
				call Custom_MeleeStartingUnitsStormwind(indexPlayer, indexStartLoc, true, true, true)
            			if (GetPlayerController(indexPlayer) != MAP_CONTROL_COMPUTER) then
					call SetPlayerHandicap(indexPlayer, 1.00)
				endif
			elseif (GetPlayerHandicap (indexPlayer) <= 0.90 ) then
				call Custom_MeleeStartingUnitsBloodElf(indexPlayer, indexStartLoc, true, true, true)
            			if (GetPlayerController(indexPlayer) != MAP_CONTROL_COMPUTER) then
					call SetPlayerHandicap(indexPlayer, 1.00)
				endif
			else
				if (GetRandomInt(1, 5) != 1 ) and (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM)) then
					if (GetRandomInt(1, 2) == 1 ) and (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM)) then
						if (GetRandomInt(1, 2) == 1 ) and (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM)) then
							call Custom_MeleeStartingUnitsBloodElf(indexPlayer, indexStartLoc, true, true, true)
            						if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
								call PickMeleeAI(indexPlayer, "bloodelf.ai", null, null)
							endif
						else
							call Custom_MeleeStartingUnitsStormwind(indexPlayer, indexStartLoc, true, true, true)
            						if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
								call PickMeleeAI(indexPlayer, "stormwind.ai", null, null)
							endif
						endif
					else
						if (GetRandomInt(1, 2) == 1 ) and (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM)) then
							call Custom_MeleeStartingUnitsDwarf(indexPlayer, indexStartLoc, true, true, true)
            						if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
								call PickMeleeAI(indexPlayer, "dwarf.ai", null, null)
							endif
						else
							call Custom_MeleeStartingUnitsKulTiras(indexPlayer, indexStartLoc, true, true, true)
            						if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
								call PickMeleeAI(indexPlayer, "kultiras.ai", null, null)
							endif
						endif
					endif
				else
					call Custom_MeleeStartingUnitsHuman(indexPlayer, indexStartLoc, true, true, true)
				endif
			endif
            elseif (indexRace == RACE_ORC) then
			if (GetPlayerHandicap (indexPlayer) <= 0.90 ) then
				call Custom_MeleeStartingUnitsChaosOrc(indexPlayer, indexStartLoc, true, true, true)
            			if (GetPlayerController(indexPlayer) != MAP_CONTROL_COMPUTER) then
					call SetPlayerHandicap(indexPlayer, 1.00)
				endif
			else
				if (GetRandomInt(1, 2) == 1 ) and (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM)) then
					call Custom_MeleeStartingUnitsChaosOrc(indexPlayer, indexStartLoc, true, true, true)
            				if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
						call PickMeleeAI(indexPlayer, "chaosorc.ai", null, null)
					endif
				else
					call Custom_MeleeStartingUnitsOrc(indexPlayer, indexStartLoc, true, true, true)
				endif
			endif
            elseif (indexRace == RACE_UNDEAD) then
			if (GetPlayerHandicap (indexPlayer) <= 0.90 ) then
				call Custom_MeleeStartingUnitsDemon(indexPlayer, indexStartLoc, true, true, true)
            			if (GetPlayerController(indexPlayer) != MAP_CONTROL_COMPUTER) then
					call SetPlayerHandicap(indexPlayer, 1.00)
				endif
			else
				if (GetRandomInt(1, 2) == 1 ) and (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM)) then
					call Custom_MeleeStartingUnitsDemon(indexPlayer, indexStartLoc, true, true, true)
            				if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
						call PickMeleeAI(indexPlayer, "demon.ai", null, null)
					endif
				else
					call Custom_MeleeStartingUnitsUndead(indexPlayer, indexStartLoc, true, true, true)
				endif
			endif
          elseif (indexRace == RACE_NIGHTELF) then
			if (GetPlayerHandicap (indexPlayer) <= 0.80 ) then
            			if (GetPlayerController(indexPlayer) != MAP_CONTROL_COMPUTER) then
					call Custom_MeleeStartingUnitsCorruptNightElfAI(indexPlayer, indexStartLoc, true, true, true)
					call SetPlayerHandicap(indexPlayer, 1.00)
				else
					call Custom_MeleeStartingUnitsCorruptNightElf(indexPlayer, indexStartLoc, true, true, true)
				endif
			elseif (GetPlayerHandicap (indexPlayer) <= 0.90 ) then
				call Custom_MeleeStartingUnitsNaga(indexPlayer, indexStartLoc, true, true, true)
            			if (GetPlayerController(indexPlayer) != MAP_CONTROL_COMPUTER) then
					call SetPlayerHandicap(indexPlayer, 1.00)
				endif
			else
				if (GetRandomInt(1, 3) != 1 ) and (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM)) then
					if (GetRandomInt(1, 2) == 1 ) and (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM)) then
						call Custom_MeleeStartingUnitsNaga(indexPlayer, indexStartLoc, true, true, true)
            					if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
							call PickMeleeAI(indexPlayer, "naga.ai", null, null)
						endif
					else
            					if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
							call Custom_MeleeStartingUnitsCorruptNightElfAI(indexPlayer, indexStartLoc, true, true, true)
							call PickMeleeAI(indexPlayer, "corruptelf.ai", null, null)
						else
							call Custom_MeleeStartingUnitsCorruptNightElf(indexPlayer, indexStartLoc, true, true, true)
						endif
					endif
				else
					call Custom_MeleeStartingUnitsNightElf(indexPlayer, indexStartLoc, true, true, true)
				endif
			endif
	    else
                call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
	    endif
        endif

        set index = index + 1
        exitwhen index == bj_MAX_PLAYERS
    endloop
    
endfunction

//===========================================================================
function Custom_MeleeStartingAI takes nothing returns nothing
    local integer index
    local player  indexPlayer
    local race    indexRace

    set index = 0
    loop
        set indexPlayer = Player(index)
        if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
            set indexRace = GetPlayerRace(indexPlayer)
            if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
                // Run a race-specific melee AI script.
		if (IsPlayerRacePrefSet(indexPlayer, RACE_PREF_RANDOM) and (GetPlayerHandicap (indexPlayer) <= 0.90 )) then
                	call PickMeleeAI(indexPlayer, "creep.ai", null, null)
			call SetPlayerHandicap(indexPlayer, 1.00)
                elseif (indexRace == RACE_HUMAN) then
			if (GetPlayerHandicap (indexPlayer) <= 0.60 ) then
                		call PickMeleeAI(indexPlayer, "kultiras.ai", null, null)
				call SetPlayerHandicap(indexPlayer, 1.00)
			elseif (GetPlayerHandicap (indexPlayer) <= 0.70 ) then
                		call PickMeleeAI(indexPlayer, "dwarf.ai", null, null)
				call SetPlayerHandicap(indexPlayer, 1.00)
			elseif (GetPlayerHandicap (indexPlayer) <= 0.80 ) then
                		call PickMeleeAI(indexPlayer, "stormwind.ai", null, null)
				call SetPlayerHandicap(indexPlayer, 1.00)
			elseif (GetPlayerHandicap (indexPlayer) <= 0.90 ) then
                		call PickMeleeAI(indexPlayer, "bloodelf.ai", null, null)
				call SetPlayerHandicap(indexPlayer, 1.00)
			else
                		call PickMeleeAI(indexPlayer, "human.ai", null, null)
			endif
                elseif (indexRace == RACE_ORC) then
			if (GetPlayerHandicap (indexPlayer) <= 0.90 ) then
                		call PickMeleeAI(indexPlayer, "chaosorc.ai", null, null)
				call SetPlayerHandicap(indexPlayer, 1.00)
			else
                		call PickMeleeAI(indexPlayer, "orc.ai", null, null)
			endif
                elseif (indexRace == RACE_UNDEAD) then
			if (GetPlayerHandicap (indexPlayer) <= 0.90 ) then
                		call PickMeleeAI(indexPlayer, "demon.ai", null, null)
				call SetPlayerHandicap(indexPlayer, 1.00)
			else
                		call PickMeleeAI(indexPlayer, "undead.ai", null, null)
			endif
                    call RecycleGuardPosition(bj_ghoul[index])
                elseif (indexRace == RACE_NIGHTELF) then
			if (GetPlayerHandicap (indexPlayer) <= 0.80 ) then
                		call PickMeleeAI(indexPlayer, "corruptelf.ai", null, null)
				call SetPlayerHandicap(indexPlayer, 1.00)
			elseif (GetPlayerHandicap (indexPlayer) <= 0.90 ) then
                		call PickMeleeAI(indexPlayer, "naga.ai", null, null)
				call SetPlayerHandicap(indexPlayer, 1.00)
			else
                		call PickMeleeAI(indexPlayer, "elf.ai", null, null)
			endif
                else
                    // Unrecognized race.
                endif
                call ShareEverythingWithTeamAI(indexPlayer)
            endif
        endif

        set index = index + 1
        exitwhen index == bj_MAX_PLAYERS
    endloop
endfunction

//===========================================================================
// Counts key structures owned by a player and his or her allies, including
// structures currently upgrading or under construction.
//
// Key structures: Town Hall, Vestibule, Municipal Center, Compound, Port Town, Great Hall, Chaos Orc Hall, Tree of Life, Temple of Streams, Tree of Corruption, Necropolis, Demon Hall
//

function LivingPlayerHallsFilter takes nothing returns boolean
    return (IsUnitAliveBJ(GetFilterUnit()) and IsUnitType(GetFilterUnit(),UNIT_TYPE_TOWNHALL))
endfunction

function CountLivingPlayerTownHalls takes player whichPlayer returns integer
    local group g
    local integer matchedCount
    local boolexpr b=Filter(function LivingPlayerHallsFilter)

    set g = CreateGroup()
    call GroupEnumUnitsOfPlayer(g, whichPlayer, b)
    set matchedCount = CountUnitsInGroup(g)
    call DestroyGroup(g)
    call DestroyBoolExpr(b)
    set b=null
    set g=null

    return matchedCount
endfunction

function Custom_MeleeGetAllyKeyStructureCount takes player whichPlayer returns integer
    local integer    playerIndex
    local player     indexPlayer
    local integer    keyStructs

    // Count the number of buildings controlled by all not-yet-defeated co-allies.
    set keyStructs = 0
    set playerIndex = 0
    loop
        set indexPlayer = Player(playerIndex)
        if (PlayersAreCoAllied(whichPlayer, indexPlayer)) then
            set keyStructs = keyStructs + CountLivingPlayerTownHalls(indexPlayer)
        endif
            
        set playerIndex = playerIndex + 1
        exitwhen playerIndex == bj_MAX_PLAYERS
    endloop

    return keyStructs
endfunction

//===========================================================================
function Custom_MeleePlayerIsCrippled takes player whichPlayer returns boolean
    local integer allyStructures    = MeleeGetAllyStructureCount(whichPlayer)
    local integer allyKeyStructures = Custom_MeleeGetAllyKeyStructureCount(whichPlayer)

    // Dead teams are not considered to be crippled.
    return (allyStructures > 0) and (allyKeyStructures <= 0)
endfunction

//===========================================================================
// Test each player to determine if anyone has become crippled.
//
function Custom_MeleeCheckForCrippledPlayers takes nothing returns nothing
    local integer    playerIndex
    local player     indexPlayer
    local force      crippledPlayers = CreateForce()
    local boolean    isNowCrippled
    local race       indexRace

    // The "finish soon" exposure of all players overrides any "crippled" exposure
    if bj_finishSoonAllExposed then
        return
    endif

    // Check each player to see if he or she has been crippled or uncrippled.
    set playerIndex = 0
    loop
        set indexPlayer = Player(playerIndex)
        set isNowCrippled = Custom_MeleePlayerIsCrippled(indexPlayer)

        if (not bj_playerIsCrippled[playerIndex] and isNowCrippled) then

            // Player became crippled; start their cripple timer.
            set bj_playerIsCrippled[playerIndex] = true
            call TimerStart(bj_crippledTimer[playerIndex], bj_MELEE_CRIPPLE_TIMEOUT, false, function MeleeCrippledPlayerTimeout)

            if (GetLocalPlayer() == indexPlayer) then
                // Use only local code (no net traffic) within this block to avoid desyncs.

                // Show the timer window.
                call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], true)

                // Display a warning message.
                call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, "|cffffcc00"+udg_RevealWarning+"|r")
            endif

        elseif (bj_playerIsCrippled[playerIndex] and not isNowCrippled) then

            // Player became uncrippled; stop their cripple timer.
            set bj_playerIsCrippled[playerIndex] = false
            call PauseTimer(bj_crippledTimer[playerIndex])

            if (GetLocalPlayer() == indexPlayer) then
                // Use only local code (no net traffic) within this block to avoid desyncs.

                // Hide the timer window for this player.
                call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)

                // Display a confirmation message if the player's team is still alive.
                if (MeleeGetAllyStructureCount(indexPlayer) > 0) then
                    if (bj_playerIsExposed[playerIndex]) then
                        call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNREVEALED"))
                    else
                        call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNCRIPPLED"))
                    endif
                endif
            endif

            // If the player granted shared vision, deny that vision now.
            call MeleeExposePlayer(indexPlayer, false)

        endif
            
        set playerIndex = playerIndex + 1
        exitwhen playerIndex == bj_MAX_PLAYERS
    endloop
endfunction

//===========================================================================
// Determine if the lost unit should result in any defeats or victories.
//
function Custom_MeleeCheckLostUnit takes unit lostUnit returns nothing
    local player lostUnitOwner = GetOwningPlayer(lostUnit)

    // We only need to check for mortality if this was the last building.
    if (GetPlayerStructureCount(lostUnitOwner, true) <= 0) then
        call MeleeCheckForLosersAndVictors()
    endif

    // Check if the lost unit has crippled or uncrippled the player.
    // (A team with 0 units is dead, and thus considered uncrippled.)
    call Custom_MeleeCheckForCrippledPlayers()
endfunction

//===========================================================================
// Determine if the gained unit should result in any defeats, victories,
// or cripple-status changes.
//
function Custom_MeleeCheckAddedUnit takes unit addedUnit returns nothing
    local player addedUnitOwner = GetOwningPlayer(addedUnit)

    // If the player was crippled, this unit may have uncrippled him/her.
    if (bj_playerIsCrippled[GetPlayerId(addedUnitOwner)]) then
        call Custom_MeleeCheckForCrippledPlayers()
    endif
endfunction

//===========================================================================
function Custom_MeleeTriggerActionConstructCancel takes nothing returns nothing
    call Custom_MeleeCheckLostUnit(GetCancelledStructure())
endfunction

//===========================================================================
function Custom_MeleeTriggerActionUnitDeath takes nothing returns nothing
    if (IsUnitType(GetDyingUnit(), UNIT_TYPE_STRUCTURE)) then
        call Custom_MeleeCheckLostUnit(GetDyingUnit())
    endif
endfunction

//===========================================================================
function Custom_MeleeTriggerActionUnitConstructionStart takes nothing returns nothing
    call Custom_MeleeCheckAddedUnit(GetConstructingStructure())
endfunction

//===========================================================================
function Custom_MeleeTriggerActionAllianceChange takes nothing returns nothing
    call MeleeCheckForLosersAndVictors()
    call Custom_MeleeCheckForCrippledPlayers()
endfunction

//===========================================================================
function MeleeInitVictoryDefeatCustomized takes nothing returns nothing
    local trigger trig
    local integer index
    local player indexPlayer

    // Create a timer window for the "finish soon" timeout period, it has no timer
    // because it is driven by real time (outside of the game state to avoid desyncs)
    set bj_finishSoonTimerDialog = CreateTimerDialog(null)

    // Set a trigger to fire when we receive a "finish soon" game event
    set trig = CreateTrigger()
    call TriggerRegisterGameEvent(trig , EVENT_GAME_TOURNAMENT_FINISH_SOON)
    call TriggerAddAction(trig , function MeleeTriggerTournamentFinishSoon)

    // Set a trigger to fire when we receive a "finish now" game event
    set trig = CreateTrigger()
    call TriggerRegisterGameEvent(trig , EVENT_GAME_TOURNAMENT_FINISH_NOW)
    call TriggerAddAction(trig , function MeleeTriggerTournamentFinishNow)

    // Set up each player's mortality code.
    set index = 0
    loop
        set indexPlayer = Player(index)

        // Make sure this player slot is playing.
        if ( GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING ) then
            set bj_meleeDefeated[index]=false
            set bj_meleeVictoried[index]=false

            // Create a timer and timer window in case the player is crippled.
            set bj_playerIsCrippled[index]=false
            set bj_playerIsExposed[index]=false
            set bj_crippledTimer[index]=CreateTimer()
            set bj_crippledTimerWindows[index]=CreateTimerDialog(bj_crippledTimer[index])
            call TimerDialogSetTitle(bj_crippledTimerWindows[index] , MeleeGetCrippledTimerMessage(indexPlayer))

            // Set a trigger to fire whenever a building is cancelled for this player.
            set trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(trig , indexPlayer , EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL , null)
            call TriggerAddAction(trig , function Custom_MeleeTriggerActionConstructCancel)

            // Set a trigger to fire whenever a unit dies for this player.
            set trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(trig , indexPlayer , EVENT_PLAYER_UNIT_DEATH , null)
            call TriggerAddAction(trig , function Custom_MeleeTriggerActionUnitDeath)

            // Set a trigger to fire whenever a unit begins construction for this player
            set trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(trig , indexPlayer , EVENT_PLAYER_UNIT_CONSTRUCT_START , null)
            call TriggerAddAction(trig , function Custom_MeleeTriggerActionUnitConstructionStart)

            // Set a trigger to fire whenever this player defeats-out
            set trig = CreateTrigger()
            call TriggerRegisterPlayerEvent(trig , indexPlayer , EVENT_PLAYER_DEFEAT)
            call TriggerAddAction(trig , function MeleeTriggerActionPlayerDefeated)

            // Set a trigger to fire whenever this player leaves
            set trig = CreateTrigger()
            call TriggerRegisterPlayerEvent(trig , indexPlayer , EVENT_PLAYER_LEAVE)
            call TriggerAddAction(trig , function MeleeTriggerActionPlayerLeft)

            // Set a trigger to fire whenever this player changes his/her alliances.
            set trig = CreateTrigger()
            call TriggerRegisterPlayerAllianceChange(trig , indexPlayer , ALLIANCE_PASSIVE)
            call TriggerRegisterPlayerStateEvent(trig , indexPlayer , PLAYER_STATE_ALLIED_VICTORY , EQUAL , 1)
            call TriggerAddAction(trig , function Custom_MeleeTriggerActionAllianceChange)
        else
            set bj_meleeDefeated[index]=true
            set bj_meleeVictoried[index]=false

            // Handle leave events for observers
            if ( IsPlayerObserver(indexPlayer) ) then
                // Set a trigger to fire whenever this player leaves
                set trig = CreateTrigger()
                call TriggerRegisterPlayerEvent(trig , indexPlayer , EVENT_PLAYER_LEAVE)
                call TriggerAddAction(trig , function MeleeTriggerActionPlayerLeft)
            endif
        endif

        set index = index + 1
        exitwhen index == bj_MAX_PLAYERS
    endloop

    // Test for victory / defeat at startup, in case the user has already won / lost.
    // Allow for a short time to pass first, so that the map can finish loading.
    call TimerStart(CreateTimer() , 2.0 , false , function Custom_MeleeTriggerActionAllianceChange)
endfunction
Name Type Is Array Initial Value
AB_Effects1 modelfile Yes
AB_Point3 location No
AB_Temp integer No
AbsorbTreeGroup group No
AdraToxoUnitGroup group No
AffinityVoidGroup group No
AfterDamageEvent real No
AMSAmount real Yes
AOEDamageEvent real No
ApostateGroup group No
ArmourSlayerGroup group No
ASA_Ability abilcode No
ASA_Group group No
ASA_LifeUse real No
AssassinGroup group No
AstroPlateGroup group No
AuraMasteryGroup group No
Avatar2Group group No
BarbarianGroup group No
BlackDragonGroup group No
BlessingOfMightGroup group No
BloodWardenGroup group No
BreakerRuneGroup group No
BrightlanceGroup group No
BurningBladeGroup group No
CargoEvent real No
CargoTransportGroup group Yes
CargoTransportUnit unit Yes
CenturionGroup group No
ChancellorHeroGroup group No
CheckDeathInList boolean Yes
CheckDeathList integer Yes
CheckDeathTimer timer No
ClearDamageEvent trigger No
CrashLightningGroup group No
CreepTempGroup group No
CreepTempLoc location No
CS integervar No
CS_Attacked unit Yes
CS_Attacking unit Yes
CS_Chance integer No
CS_Damage real Yes
CS_Dummy unit Yes
CS_Group group Yes
CS_Jumps integer Yes
CS_LEVEL integer No
CS_Off boolean Yes
CS_Point location Yes
CS_Skip integer No
CS_SpecialEffect effect Yes
CS_Speed real Yes
CS_Times integer No
CSmCaster unit No
DAMAGE_FACTOR_BRACERS real No
DAMAGE_FACTOR_ELUNES real No
DAMAGE_FACTOR_ETHEREAL real No
DamageBlockingAbility abilcode No
DamageEvent real No
DamageEventAmount real No
DamageEventAOE integer No
DamageEventAOEGroup group No
DamageEventLevel integer No
DamageEventOverride boolean No
DamageEventPrevAmt real No
DamageEventSource unit No
DamageEventsWasted integer No
DamageEventTarget unit No
DamageEventTrigger trigger No
DamageEventType integer No
DamageGroup group No
DamageModifierEvent real No
DamageTypeBlocked integer No
DamageTypeCriticalStrike integer No
DamageTypeExplosive integer No
DamageTypeHeal integer No
DamageTypeReduced integer No
DarkSpikesTauGroup group No
DeathEvent real No
DeathTimer timer No
DefiledWaterGroup group No
DetectRemoveAbility abilcode No
DetectTransformAbility abilcode No
DevilishPowerGroup group No
DmgEvBracers itemcode No
DmgEvMana real No
DmgEvManaMult real No
DmgEvMSlvl integer No
DmgEvRecursionN integer No
DmgEvRunning boolean No
DmgEvStarted boolean No
DmgEvTimer timer No
DmgEvTrig trigger No
DragonGroup group No
DragoonGroup group No
DummyUnit unit No
EmberKnightGroup group No
EnhancedDamageTarget unit No
ExecutionerGroup group No
FaithfulGroup group No
FelcrusherGroup group No
GDD__Integers integer Yes
GDD__LeftMapGroup group No
GDD__TriggerArray trigger Yes
GDD__UnitArray unit Yes
GDD_Damage real No
GDD_DamagedUnit unit No
GDD_DamageSource unit No
GDD_Event real No
GoliathGroup group No
HideDamageFrom boolean Yes
IsDamageSpell boolean No
IsUnitAlive boolean Yes
IsUnitBeingUnloaded boolean Yes
IsUnitNew boolean Yes
IsUnitPreplaced boolean Yes
IsUnitReincarnating boolean Yes
IsUnitRemoved boolean Yes
IsUnitTransforming boolean Yes
Jab_Caster unit No
Jab_Mod integer No
JabDamage integer No
JustCastSpell group No
KB_Angle real Yes
KB_Casters unit Yes
KB_CountBuffs integer No
KB_DestroyTrees boolean Yes
KB_EffectCounter integer Yes
KB_EffectCounter2 integer Yes
KB_EffectPoint location No
KB_Effects_1 string Yes
KB_Effects_2 string Yes
KB_GeneralIntegers integervar Yes
KB_Group group No
KB_KnockbackedUnits group No
KB_Levels integer Yes
KB_MaxDistance real Yes
KB_ReachedDistance real Yes
KB_ReducedReal real No
KB_ReduceSpeedReal real Yes
KB_SpecificSpeed real Yes
KB_StartPositions location Yes
KB_TempPoint location Yes
KB_TempReal real No
KB_TotalKnockUnits integer No
KB_Units unit Yes
KBA_Caster unit No
KBA_DestroyTrees boolean No
KBA_DistancePerLevel real No
KBA_Level integer No
KBA_ManaLeak integer No
KBA_SpecialEffects string Yes
KBA_Speed real No
KBA_StartingPosition location No
KBA_TargetUnit unit No
KillerOfUnit unit Yes
LastDamageHP real No
LastDmgPrevAmount real Yes
LastDmgPrevType integer Yes
LastDmgSource unit Yes
LastDmgTarget unit Yes
LastDmgValue real Yes
LastDmgWasSpell boolean Yes
LastStandGroup group No
LD_Ability abilcode No
LD_AbilityDrain abilcode No
LD_Life integer No
LD_SearchRange integer No
locCaster location No
MagiDummyGroup group No
MainStructureGroup group No
MCGroupCount integer Yes
MCRIndex integer No
MCS_AttachmentPoint1 string No
MCS_AttachmentPoint2 string No
MCS_Caster1 unit No
MCS_Caster2 unit Yes
MCS_curDuration real Yes
MCS_Deadboolean boolean Yes
MCS_Duration1 real No
MCS_Duration2 real Yes
MCS_Integer integer Yes
MCS_MindControlledGroup group No
MCS_Player player Yes
MCS_SfxAtEndString string No
MCS_SfxAtEndString2 string Yes
MCS_SfxAtStartString modelfile No
MCS_SfxContinous1 effect Yes
MCS_SfxContinous1String string No
MCS_SfxContinous2 effect Yes
MCS_SfxContinous2String string No
MCS_Target1 unit No
MCS_Target2 unit Yes
MCWIndex integer No
MiasmaDeltaGroup group No
NebulasHasteGroup group No
NextDamageOverride boolean No
NextDamageType integer No
OncomingStormGroup group No
p location No
P_Manaend real No
P_Manastart real No
P_Manatotal real No
ParagonAuraGroup group No
PartisanGroup group No
PassGroup group No
PentaAuraGroup group No
PurgatoryGroup group No
RectorGroup group No
RevealWarning string No You will be revealed to your opponents unless you build a town hall type building.
SalamderLGroup group No
SearingLight_Caster unit No
SearingLight_Mod integer No
SharpshooterGroup group No
ShellRuneGroup group No
ShellRuneMDGroup group No
ShifterGroup group No
SOC_Angle real Yes
SOC_AngleInteger integer Yes
SOC_AOE real No
SOC_Caster unit Yes
SOC_CasterPoint location Yes
SOC_Hit group Yes
SOC_Index integer Yes
SOC_Integer integer Yes
SOC_IntegerEnd integer No
SOC_KBCasterPoint location Yes
SOC_Range real No
SolidityAuraGroup group No
SoulStone1Group group No
SoulStone2Group group No
SoulStone3Group group No
SpellDamageAbility abilcode No
StarBinderHeroGroup group No
StoneformDwarfGroup group No
StormstriderGroup group No
SummonerOfUnit unit Yes
targetPoint location No
Temp_Group_1 group No
Temp_Int integer No
Temp_Point location No
Temp_Unit unit No
Temp_UnitGroup group No
tempAngle_Real real No
tempCaster unit No
tempDamage_Scaling_Total real No
tempDamage_Total real No
tempDuration_Total real No
TempForce force No
TempGroup group No
tempGroup group No
TempGroupArray group Yes
tempInt_Counter integer No
tempInt_Counter_2 integer No
TempInteger integer Yes
tempItem item No
tempKey integer No
tempLevel real No
TempLoc location No
tempPickedUnit unit No
TempPoint location No
tempPoint_Target location No
tempPoint_Temp location No
tempPoint_Whirlpool location No
tempPull_Intensity_Total real No
tempRange_Total real No
TempUnit unit No
TorrentialFlameGroup group No
u unit No
UDex integer No
UDexGen integer No
UDexLastRecycled integer No
UDexMax integer No
UDexNext integer Yes
UDexPrev integer Yes
UDexRecycle integer No
UDexUnits unit Yes
UDexWasted integer No
UmbralBloodGroup group No
UMovNext integer Yes
UMovPrev integer Yes
UnholyPresenceGroup group No
UnitDamageRegistered boolean Yes
UnitInAction boolean Yes
UnitInActionEvent real No
UnitIndexerEnabled boolean No
UnitIndexEvent real No
UnitMovementInterval real No
UnitMoving boolean Yes
UnitMovingEvent real No
UnitMovingX real Yes
UnitMovingY real Yes
UnitTypeEvent real No
UnitTypeOf unitcode Yes
VenomSwipeCaster group No
VoidElvenGroup group No
VoyagerGroup group No
WarlordGroup group No
WarlordGroupAcro group No
WarmasterAuraGroup group No
WitherHeartGroup group No
WorldMaxX real No
WorldMaxY real No
WP_Ability_Order string No
WP_Attack_Type attacktype No
WP_Damage_Base real No
WP_Damage_Bonus real No
WP_Damage_Scaling_Base real No
WP_Damage_Scaling_Bonus real No
WP_Damage_Scaling_Max real No
WP_Damage_Type damagetype No
WP_Dummy_Loop unit No
WP_Dummy_Scale_Factor real No
WP_Dummy_Whirlpool unit No
WP_Duration_Base real No
WP_Duration_Bonus real No
WP_Duration_Max real No
WP_Effect_Center string No
WP_Effect_Hit string No
WP_Group_Counter integer No
WP_Hashtable hashtable No
WP_Interval_Integer integer No
WP_Loop_Group group No
WP_Pull_Intensity_Base real No
WP_Pull_Intensity_Bonus real No
WP_Pull_Intensity_Max real No
WP_Pull_Interval integer No
WP_Range_Base real No
WP_Range_Bonus real No
WP_Range_Max real No
WP_Spell_ID abilcode No
WP_Spell_ID_2 abilcode No
WP_Unit_Type_Dummy unitcode No
WP_Unit_Type_Whirl_Dummy unitcode No
WP_Unit_Type_Whirl_Dummy_2 unitcode No
ZerglingCounter integer Yes
ZerglingDyingUnit unit No
ZerglingRallyPoint unit No
ZerglingTrainedUnit unit No
ZerglingTrainerPoint location No
AlteredMeleeInit
  Events
    Map initialization
  Conditions
  Actions
    Melee Game - Set starting resources (for all players)
    Melee Game - Give trained Heroes a Scroll of Town Portal (for all players)
    Melee Game - Use melee time of day (for all players)
    Melee Game - Remove creeps and critters from used start locations (for all players)
    Custom script: call Custom_MeleeStartingHeroLimit()
    Custom script: call Custom_MeleeStartingUnits()
    Custom script: call Custom_MeleeStartingAI()
    Custom script: call MeleeInitVictoryDefeatCustomized()
    Custom script: call DestroyTrigger( GetTriggeringTrigger() )
GUI Unit Event by Bribe, version 2.5.0.0
Unit Event Config
  Events
    Map initialization
  Conditions
  Actions
    -------- --------
    -------- Copy Unit Event Ability from Object Editor, then set DetectRemoveAbility to it as follows: --------
    -------- --------
    Set VariableSet DetectRemoveAbility = Unit Event Ability (Removal Detect)
    -------- --------
    -------- Paste it a second time, then set DetectTransformAbility to it as follows: --------
    -------- --------
    Set VariableSet DetectTransformAbility = Unit Event Ability (Transform Detect)
    -------- --------
    -------- Don't enable the following lines as they exist simply to make copying the system easier --------
    -------- --------
    Set VariableSet WorldMaxX = WorldMaxY
    Set VariableSet CargoTransportUnit[0] = (Random unit from CargoTransportGroup[0])
    Set VariableSet CheckDeathList[UDexMax] = UDexNext[UDexPrev[UDexLastRecycled]]
    Set VariableSet UDexUnits[UDex] = SummonerOfUnit[0]
    Countdown Timer - Pause CheckDeathTimer
    Set VariableSet UnitIndexEvent = (CargoEvent + (DeathEvent + UnitTypeEvent))
    Set VariableSet IsUnitAlive[0] = IsUnitBeingUnloaded[0]
    Set VariableSet IsUnitNew[0] = IsUnitReincarnating[0]
    Set VariableSet IsUnitRemoved[0] = UnitIndexerEnabled
    Set VariableSet KillerOfUnit[0] = No unit
    Set VariableSet UnitTypeOf[0] = No unit-type
    Set VariableSet CheckDeathInList[0] = False
    -------- One additional event to run right before Unit Indexer initializes, added 29 May 2017 for ZiBitheWand3r3r --------
    Set VariableSet UnitIndexEvent = -1.00
    -------- --------
    -------- Initialize Unit Event now that all the InitTrig_ functions have run --------
    -------- --------
    Set VariableSet IsUnitPreplaced[0] = True
    Custom script: call ExecuteFunc("UnitEventInit")
    Set VariableSet UnitIndexEvent = 3.00
    Set VariableSet IsUnitPreplaced[0] = IsUnitTransforming[0]
//===========================================================================
function UnitEventDestroyGroup takes integer i returns nothing
    if udg_CargoTransportGroup[i] != null then
        call DestroyGroup(udg_CargoTransportGroup[i])
        set udg_CargoTransportGroup[i] = null
    endif
endfunction
function UnitEventCheckAfter takes nothing returns nothing
    local integer i = 0
    loop
        set i = udg_CheckDeathList[i]
        exitwhen i == 0
        if udg_IsUnitNew[i] then
            //The unit was just created.
            set udg_IsUnitNew[i] = false
        elseif udg_IsUnitTransforming[i] then
           //Added 21 July 2017 to fix the issue re-adding this ability in the same instant
           set udg_UDex = i
           set udg_UnitTypeEvent = 0.00
           set udg_UnitTypeEvent = 1.00
           set udg_UnitTypeOf[i] = GetUnitTypeId(udg_UDexUnits[i]) //Set this afterward to give the user extra reference
           set udg_IsUnitTransforming[i] = false
           call UnitAddAbility(udg_UDexUnits[i], udg_DetectTransformAbility)
        elseif udg_IsUnitAlive[i] then
            //The unit has started reincarnating.
            set udg_IsUnitReincarnating[i] = true
            set udg_IsUnitAlive[i] = false
            set udg_UDex = i
            set udg_DeathEvent = 0.50
            set udg_DeathEvent = 0.00
        endif
        set udg_CheckDeathInList[i] = false
    endloop
    //Empty the list
    set udg_CheckDeathList[0] = 0
endfunction
function UnitEventCheckAfterProxy takes integer i returns nothing
    if udg_CheckDeathList[0] == 0 then
        call TimerStart(udg_CheckDeathTimer, 0.00, false, function UnitEventCheckAfter)
    endif
    if not udg_CheckDeathInList[i] then
        set udg_CheckDeathList[i] = udg_CheckDeathList[0]
        set udg_CheckDeathList[0] = i
        set udg_CheckDeathInList[i] = true
    endif
endfunction

function UnitEventOnUnload takes nothing returns nothing
    local integer i = udg_UDex
    call GroupRemoveUnit(udg_CargoTransportGroup[GetUnitUserData(udg_CargoTransportUnit[i])], udg_UDexUnits[i])
    set udg_IsUnitBeingUnloaded[i] = true
    set udg_CargoEvent = 0.00
    set udg_CargoEvent = 2.00
    set udg_CargoEvent = 0.00
    set udg_IsUnitBeingUnloaded[i] = false
    if not IsUnitLoaded(udg_UDexUnits[i]) or IsUnitType(udg_CargoTransportUnit[i], UNIT_TYPE_DEAD) or GetUnitTypeId(udg_CargoTransportUnit[i]) == 0 then
        set udg_CargoTransportUnit[i] = null
    endif
endfunction

function UnitEventOnDeath takes nothing returns boolean
    local integer pdex = udg_UDex
    set udg_UDex = GetUnitUserData(GetTriggerUnit())
    if udg_UDex != 0 then
        set udg_KillerOfUnit[udg_UDex] = GetKillingUnit() //Added 29 May 2017 for GIMLI_2
        set udg_IsUnitAlive[udg_UDex] = false
        set udg_DeathEvent = 0.00
        set udg_DeathEvent = 1.00
        set udg_DeathEvent = 0.00
        set udg_KillerOfUnit[udg_UDex] = null
        if udg_CargoTransportUnit[udg_UDex] != null then
            call UnitEventOnUnload()
        endif
    endif
    set udg_UDex = pdex
    return false
endfunction
 
function UnitEventOnOrder takes nothing returns boolean
    local integer pdex = udg_UDex
    local unit u = GetFilterUnit()
    local integer i = GetUnitUserData(u)
    if i > 0 then
        set udg_UDex = i
        if GetUnitAbilityLevel(u, udg_DetectRemoveAbility) == 0 then
            if not udg_IsUnitRemoved[i] then
                set udg_IsUnitRemoved[i] = true
                set udg_IsUnitAlive[i] = false
                set udg_SummonerOfUnit[i] = null
               
                //For backwards-compatibility:
                set udg_DeathEvent = 0.00
                set udg_DeathEvent = 3.00
                set udg_DeathEvent = 0.00
               
                //Fire deindex event for UDex:
                set udg_UnitIndexEvent = 0.00
                set udg_UnitIndexEvent = 2.00
                set udg_UnitIndexEvent = 0.00
               
                set udg_UDexNext[udg_UDexPrev[i]] = udg_UDexNext[i]
                set udg_UDexPrev[udg_UDexNext[i]] = udg_UDexPrev[i]
               
                // Recycle the index for later use
                set udg_UDexUnits[i] = null
                set udg_UDexPrev[i] = udg_UDexLastRecycled
                set udg_UDexLastRecycled = i
                call UnitEventDestroyGroup(i)
            endif
        elseif not udg_IsUnitAlive[i] then
            if not IsUnitType(u, UNIT_TYPE_DEAD) then
                set udg_IsUnitAlive[i] = true
                set udg_DeathEvent = 0.00
                set udg_DeathEvent = 2.00
                set udg_DeathEvent = 0.00
                set udg_IsUnitReincarnating[i] = false
            endif
        elseif IsUnitType(u, UNIT_TYPE_DEAD) then
            if udg_IsUnitNew[i] then
                //This unit was created as a corpse.
                set udg_IsUnitAlive[i] = false
                set udg_DeathEvent = 0.00
                set udg_DeathEvent = 1.00
                set udg_DeathEvent = 0.00
            elseif udg_CargoTransportUnit[i] == null or not IsUnitType(u, UNIT_TYPE_HERO) then
                //The unit may have just started reincarnating.
                call UnitEventCheckAfterProxy(i)
            endif
        elseif GetUnitAbilityLevel(u, udg_DetectTransformAbility) == 0 and not udg_IsUnitTransforming[i] then
            set udg_IsUnitTransforming[i] = true
            call UnitEventCheckAfterProxy(i)  //This block has been updated on 21 July 2017
        endif
        if udg_CargoTransportUnit[i] != null and not udg_IsUnitBeingUnloaded[i] and not IsUnitLoaded(u) or IsUnitType(u, UNIT_TYPE_DEAD) then
            call UnitEventOnUnload()
        endif
        set udg_UDex = pdex
    endif
    set u = null
    return false
endfunction
function UnitEventOnSummon takes nothing returns boolean
    local integer pdex = udg_UDex
    set udg_UDex = GetUnitUserData(GetTriggerUnit())
    if udg_IsUnitNew[udg_UDex] then
        set udg_SummonerOfUnit[udg_UDex] = GetSummoningUnit()
        set udg_UnitIndexEvent = 0.00
        set udg_UnitIndexEvent = 0.50
        set udg_UnitIndexEvent = 0.00
    endif
    set udg_UDex = pdex
    return false
endfunction
function UnitEventOnLoad takes nothing returns boolean
    local integer pdex = udg_UDex
    local integer i = GetUnitUserData(GetTriggerUnit())
    local integer index
    if i != 0 then
        set udg_UDex = i
        if udg_CargoTransportUnit[i] != null then
            call UnitEventOnUnload()
        endif
        //Loaded corpses do not issue an order when unloaded, therefore must
        //use the enter-region event method taken from Jesus4Lyf's Transport.
        if not udg_IsUnitAlive[i] then
            call SetUnitX(udg_UDexUnits[i], udg_WorldMaxX)
            call SetUnitY(udg_UDexUnits[i], udg_WorldMaxY)
        endif
       
        set udg_CargoTransportUnit[i] = GetTransportUnit()
        set index = GetUnitUserData(udg_CargoTransportUnit[i])
        if udg_CargoTransportGroup[index] == null then
            set udg_CargoTransportGroup[index] = CreateGroup()
        endif
        call GroupAddUnit(udg_CargoTransportGroup[index], udg_UDexUnits[i])
        set udg_CargoEvent = 0.00
        set udg_CargoEvent = 1.00
        set udg_CargoEvent = 0.00
        set udg_UDex = pdex
    endif
    return false
endfunction
function UnitEventEnter takes nothing returns boolean
    local integer pdex = udg_UDex
    local integer i = udg_UDexLastRecycled
    local unit u = GetFilterUnit()
    if udg_UnitIndexerEnabled and GetUnitAbilityLevel(u, udg_DetectRemoveAbility) == 0 then
        //Generate a unique integer index for this unit
        if i == 0 then
            set i = udg_UDexMax + 1
            set udg_UDexMax = i
        else
            set udg_UDexLastRecycled = udg_UDexPrev[i]
        endif
        //Link index to unit, unit to index
        set udg_UDexUnits[i] = u
        call SetUnitUserData(u, i)
       
        //For backwards-compatibility, add the unit to a linked list
        set udg_UDexNext[i] = udg_UDexNext[0]
        set udg_UDexPrev[udg_UDexNext[0]] = i
        set udg_UDexNext[0] = i
        set udg_UDexPrev[i] = 0

        set udg_CheckDeathInList[i] = false

        call UnitAddAbility(u, udg_DetectRemoveAbility)
        call UnitMakeAbilityPermanent(u, true, udg_DetectRemoveAbility)
        call UnitAddAbility(u, udg_DetectTransformAbility)
        set udg_UnitTypeOf[i] = GetUnitTypeId(u)
        set udg_IsUnitNew[i] = true
        set udg_IsUnitAlive[i] = true
        set udg_IsUnitRemoved[i] = false
        set udg_IsUnitReincarnating[i] = false
        set udg_IsUnitPreplaced[i] = udg_IsUnitPreplaced[0] //Added 29 May 2017 for Spellbound
        call UnitEventCheckAfterProxy(i)
       
        //Fire index event for UDex
        set udg_UDex = i
        set udg_UnitIndexEvent = 0.00
        set udg_UnitIndexEvent = 1.00
        set udg_UnitIndexEvent = 0.00
    else
        set udg_UDex = GetUnitUserData(u)
        if udg_CargoTransportUnit[udg_UDex] != null and not IsUnitLoaded(u) then
            //The unit was dead, but has re-entered the map.
            call UnitEventOnUnload()
        endif
    endif
    set udg_UDex = pdex
    set u = null
    return false
endfunction
//===========================================================================
function UnitEventInit takes nothing returns nothing
    local integer i = bj_MAX_PLAYER_SLOTS //update to make it work with 1.29
    local player p
    local trigger t = CreateTrigger()
    local trigger load = CreateTrigger()
    local trigger death = CreateTrigger()
    local trigger summon = CreateTrigger()
    local rect r = GetWorldBounds()
    local region re = CreateRegion()
    local boolexpr enterB = Filter(function UnitEventEnter)
    local boolexpr orderB = Filter(function UnitEventOnOrder)
    set udg_WorldMaxX = GetRectMaxX(r)
    set udg_WorldMaxY = GetRectMaxY(r)
    call RegionAddRect(re, r)
    call RemoveRect(r)
    call UnitEventDestroyGroup(0)
    call UnitEventDestroyGroup(1)
   
    set udg_CheckDeathList[0] = 0
    set udg_UnitIndexerEnabled = true
    call TriggerRegisterEnterRegion(CreateTrigger(), re, enterB)
    call TriggerAddCondition(load, Filter(function UnitEventOnLoad))
    call TriggerAddCondition(death, Filter(function UnitEventOnDeath))
    call TriggerAddCondition(summon, Filter(function UnitEventOnSummon))
    loop
        set i = i - 1
        set p = Player(i)
        call SetPlayerAbilityAvailable(p, udg_DetectRemoveAbility, false)
        call SetPlayerAbilityAvailable(p, udg_DetectTransformAbility, false)
        call TriggerRegisterPlayerUnitEvent(summon, p, EVENT_PLAYER_UNIT_SUMMON, null)
        call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, orderB)
        call TriggerRegisterPlayerUnitEvent(death, p, EVENT_PLAYER_UNIT_DEATH, null)
        call TriggerRegisterPlayerUnitEvent(load, p, EVENT_PLAYER_UNIT_LOADED, null)
        call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, p, enterB)
        exitwhen i == 0
    endloop
    set summon = null
    set death = null
    set load = null
    set re = null
    set enterB = null
    set orderB = null
    set p = null
    set r = null
    set t = null
endfunction
function InitTrig_Unit_Event takes nothing returns nothing
endfunction
Copy this trigger into your map if you want to fix the life drain abilitity. It comes with a potential weird side-effect: if you had already cast a damage over time ability on the damage target from the damage source before life draining, it will heal off of that damage over time ability as well. Without triggering life drain completely on your own, there is no way to prevent this. However, this issue does not affect the Dark Ranger since she only has that one damage-over-time ability.
Life Drain Fix
  Events
    Game - AfterDamageEvent becomes Equal to 1.00
  Conditions
    IsDamageSpell Equal to True
    (DamageEventSource has buff Drain Life (Caster)) Equal to True
    (DamageEventTarget has buff Drain Life (Target)) Equal to True
  Actions
    Unit - Set life of DamageEventSource to ((Life of DamageEventSource) + DamageEventAmount)
This is pretty easy to fix.
Finger of Death Fix
  Events
    Game - DamageModifierEvent becomes Equal to 1.00
  Conditions
    IsDamageSpell Equal to True
    (Current order of DamageEventSource) Equal to (Order(fingerofdeath))
  Actions
    Set VariableSet DamageEventType = DamageTypeExplosive
Requires you to copy the ability "Anti-Magic Shell (Fixed)" from Object Editor into your map. AMS cannot be configured to work with a damage detection system as it will always have ambiguous results and the shield will be popped or reduce damage to 0.00 before the damage event runs, so the ability is based off of Frost Armor with its only utility being triggered.
//TESH.scrollpos=12
//TESH.alwaysfold=0
constant function GetAMSBuffId takes nothing returns integer
    return 'Bams'
endfunction

constant function GetAMSAbilId takes nothing returns integer
    return 'A0QJ'
endfunction

constant function GetAMSShieldVal takes nothing returns real
    return 300.00
endfunction

function Trig_Anti_Magic_Shield_Fix_Actions takes nothing returns nothing
    local integer id = GetUnitUserData(udg_DamageEventTarget)
    local real shield = udg_AMSAmount[id]- udg_DamageEventAmount
    if shield <= 0.00 then
        set udg_DamageEventAmount = -shield
        set shield = 0.00
        call UnitRemoveAbility(udg_DamageEventTarget, GetAMSBuffId())
    else
        set udg_DamageEventAmount = 0.00
        if udg_DamageEventType == 0 then
            set udg_DamageEventType = udg_DamageTypeBlocked
        endif
    endif
    set udg_AMSAmount[id] = shield
endfunction

function Trig_Anti_Magic_Shield_Fix_Conditions takes nothing returns boolean
    if udg_IsDamageSpell then
        if GetUnitAbilityLevel(udg_DamageEventTarget, GetAMSBuffId()) > 0 then
            call Trig_Anti_Magic_Shield_Fix_Actions()
        else
            set udg_AMSAmount[GetUnitUserData(udg_DamageEventTarget)] = 0.00
        endif
    endif
    return false
endfunction

function AMS_Refresh_Conditions takes nothing returns boolean
    if GetSpellAbilityId() == GetAMSAbilId() then
        set udg_AMSAmount[GetUnitUserData(GetSpellTargetUnit())] = GetAMSShieldVal()
    endif
    return false
endfunction

function InitTrig_Anti_Magic_Shield_Fix takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_DamageModifierEvent", EQUAL, 4.00)
    call TriggerAddCondition(t, Condition(function Trig_Anti_Magic_Shield_Fix_Conditions))
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Filter(function AMS_Refresh_Conditions))
endfunction
DamageModifierEvent becoming Equal to 4.00 is a new event introduced in DamageEngine 3.5. It is the final phase of damage processing as it is built specifically to handle shields, and only runs if the damage is greater than 0.
Mana Shield Fix
  Events
    Game - DamageModifierEvent becomes Equal to 4.00
  Conditions
    (DamageEventTarget has buff Mana Shield) Equal to True
  Actions
    -------- Mana Shield handling. For it to work, you need to set the mana shield Damage Absorbed % --------
    -------- to 0.00 for Mana Shield (Neutral Hostile) and for all 3 levels of Mana Shield for the Naga Sea Witch. --------
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
      Then - Actions
        Set VariableSet DmgEvMana = (Mana of DamageEventTarget)
        -------- Get the shielding mana multiplier from the target unit based on the unit or hero ability ("multiplier" mana per HP) --------
        -------- If you have custom mana shield abilities or have modified the normal ones, add or configure those here. --------
        Set VariableSet DmgEvMSlvl = (Level of Mana Shield for DamageEventTarget)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            DmgEvMSlvl Equal to 0
          Then - Actions
            Set VariableSet DmgEvManaMult = 2.00
          Else - Actions
            Set VariableSet DmgEvManaMult = ((0.50 x (Real(DmgEvMSlvl))) + 0.50)
        Set VariableSet DmgEvMana = (DmgEvMana x DmgEvManaMult)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            DamageEventAmount Less than (DmgEvMana - 0.01)
          Then - Actions
            Set VariableSet DmgEvMana = (DmgEvMana - DamageEventAmount)
            Set VariableSet DamageEventAmount = 0.00
            Set VariableSet DmgEvMana = (DmgEvMana / DmgEvManaMult)
            -------- You can remove this damage type change if you want, it's mostly for the purpose of the test map. --------
            Set VariableSet DamageEventType = DamageTypeBlocked
          Else - Actions
            Set VariableSet DamageEventAmount = (DamageEventAmount - DmgEvMana)
            Set VariableSet DmgEvMana = 0.00
            Unit - Order DamageEventTarget to Neutral Sea Witch - Deactivate Mana Shield.
            -------- You can remove this damage type change if you want, it's mostly for the purpose of the test map. --------
            Set VariableSet DamageEventType = DamageTypeReduced
        Unit - Set mana of DamageEventTarget to DmgEvMana
      Else - Actions
Damage Engine Config
  Events
  Conditions
    (UDexUnits[UDex] is A structure) Equal to False
  Actions
    -------- - --------
    -------- This trigger's conditions let you filter out units you don't want detection for. --------
    -------- NOTE: By default, units with Locust will not pass the check. --------
    -------- TIP: The unit is called UDexUnits[UDex] and its custom value is UDex --------
    -------- - --------
    -------- Copy the Cheat Death Ability from Object Editor into your map and set the following variable respectively: --------
    -------- - --------
    Set VariableSet DamageBlockingAbility = Cheat Death Ability (+500,000)
    -------- - --------
    -------- Copy the Detect Spell Damage Ability from Object Editor into your map and set the following variable respectively: --------
    -------- - --------
    Set VariableSet SpellDamageAbility = Detect Spell Damage
    -------- - --------
    -------- You can add extra classifications here if you want to differentiate between your triggered damage --------
    -------- Use DamageTypeExplosive (or any negative value damage type) if you want a unit killed by that damage to explode --------
    -------- - --------
    Set VariableSet DamageTypeExplosive = -1
    Set VariableSet DamageTypeCriticalStrike = 1
    Set VariableSet DamageTypeHeal = 2
    Set VariableSet DamageTypeReduced = 3
    Set VariableSet DamageTypeBlocked = 4
    -------- - --------
    -------- Leave the next Set statement disabled if you modified the Spell Damage Reduction item ability to 1.67 reduction --------
    -------- Otherwise, if you removed that ability from Runed Bracers, you'll need to enable this line: --------
    -------- - --------
    Set VariableSet DmgEvBracers = Runed Bracers
    -------- - --------
    -------- Set the damage multiplication factor (1.00 being unmodified, increasing in damage over 1.00 and at 0 damage with 0.00) --------
    -------- NOTE. With the default values, Runed Bracers is reduces 33%, Elune's Grace reduces 20% and Ethereal increases 67% --------
    -------- - --------
    Set VariableSet DAMAGE_FACTOR_BRACERS = 0.67
    Set VariableSet DAMAGE_FACTOR_ELUNES = 0.80
    Set VariableSet DAMAGE_FACTOR_ETHEREAL = 1.67
    -------- - --------
    -------- Added 25 July 2017 to allow detection of things like Bash or Pulverize or AOE spread --------
    -------- - --------
    Set VariableSet DamageEventAOE = 1
    Set VariableSet DamageEventLevel = 1
    -------- - --------
    -------- Do not enable any of the following lines as they are simply variable declarations to make copying easier --------
    -------- - --------
    Set VariableSet AfterDamageEvent = (DamageEvent + (AOEDamageEvent + DamageModifierEvent))
    Set VariableSet ClearDamageEvent = (This trigger)
    Set VariableSet DamageEventAmount = DamageEventPrevAmt
    Set VariableSet DamageEventOverride = NextDamageOverride
    Set VariableSet DamageEventSource = DamageEventTarget
    Set VariableSet DamageEventTrigger = DmgEvTrig
    Set VariableSet DamageEventType = (LastDmgPrevType[0] + NextDamageType)
    Set VariableSet DamageEventsWasted = DmgEvRecursionN
    Set VariableSet DmgEvRunning = DmgEvStarted
    Set VariableSet IsDamageSpell = LastDmgWasSpell[0]
    Set VariableSet LastDamageHP = (Elapsed time for DmgEvTimer)
    Set VariableSet LastDmgPrevAmount[0] = LastDmgValue[0]
    Set VariableSet LastDmgSource[0] = LastDmgTarget[0]
    Set VariableSet HideDamageFrom[0] = False
    Set VariableSet UnitDamageRegistered[0] = False
    Unit Group - Add EnhancedDamageTarget to DamageEventAOEGroup
Is Unit Moving Config
  Events
  Conditions
    (Default movement speed of UDexUnits[UDex]) Not equal to 0.00
  Actions
    -------- Units who do not pass the above conditions will not be allowed to be registered by the system. --------
    -------- One can add exceptions such as with buildings who have the ability to uproot. --------
    -------- --------
    -------- Here you can configure how frequently the check occurs. --------
    -------- NOTES: This should not be lower than any movement systems in your map. --------
    -------- Slower checks improve performance, but I wouldn't slow it much more than this. --------
    -------- --------
    Set VariableSet UnitMovementInterval = 0.10
    -------- --------
    -------- Do not enable the following lines as they simply exist to make the variable copying easier --------
    Set VariableSet UnitMoving[UMovNext[UMovPrev[0]]] = False
    Set VariableSet UnitMovingEvent = (UnitMovingX[0] + UnitMovingY[0])
//TESH.scrollpos=0
//TESH.alwaysfold=0
function IsUnitMovementTracked takes integer i returns boolean
    return udg_UMovPrev[i] != 0 or udg_UMovNext[0] == i
endfunction

function UnitMovementRegister takes nothing returns boolean
    local integer i = udg_UDex
    if not IsUnitMovementTracked(i) and TriggerEvaluate(gg_trg_Is_Unit_Moving_Config) then
        set udg_UMovPrev[udg_UMovNext[0]] = i
        set udg_UMovNext[i] = udg_UMovNext[0]
        set udg_UMovNext[0] = i
        set udg_UnitMovingX[i] = GetUnitX(udg_UDexUnits[i])
        set udg_UnitMovingY[i] = GetUnitY(udg_UDexUnits[i])
    endif
    return false
endfunction

function UnitMovementUnregister takes nothing returns boolean
    local integer i = udg_UDex
    if IsUnitMovementTracked(i) then
        set udg_UnitMoving[i] = false
        set udg_UMovNext[udg_UMovPrev[i]] = udg_UMovNext[i]
        set udg_UMovPrev[udg_UMovNext[i]] = udg_UMovPrev[i]
        set udg_UMovPrev[i] = 0
    endif
    return false
endfunction

function RunUnitMovementEvent takes integer i, real e returns nothing
    local integer pdex = udg_UDex
    if e == 1.00 then
        set udg_UnitMoving[i] = true
    else
        set udg_UnitMoving[i] = false
    endif
    set udg_UDex = i
    set udg_UnitMovingEvent = e
    set udg_UnitMovingEvent = 0.00
    set udg_UDex = pdex
endfunction

//===========================================================================
// This function runs periodically to check if units are actually moving.
//
function UnitMovementTracker takes nothing returns nothing
    local integer i = 0
    local integer n
    local real x
    local real y
    loop
        set i = udg_UMovNext[i]
        exitwhen i == 0
        set x = GetUnitX(udg_UDexUnits[i])
        set y = GetUnitY(udg_UDexUnits[i])
        if x != udg_UnitMovingX[i] or y != udg_UnitMovingY[i] then
            set udg_UnitMovingX[i] = x
            set udg_UnitMovingY[i] = y
            if not udg_UnitMoving[i] then
                if GetUnitTypeId(udg_UDexUnits[i]) != 0 then
                    call RunUnitMovementEvent(i, 1.00)
                else
                    set n = udg_UDex
                    set udg_UDex = i
                    set i = udg_UMovPrev[i] //avoid skipping checks
                    call UnitMovementUnregister()
                    set udg_UDex = n
                endif
            endif
        elseif udg_UnitMoving[i] then
            call RunUnitMovementEvent(i, 2.00)
        endif
    endloop
endfunction

//===========================================================================
function InitTrig_Is_Unit_Moving takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
    call TriggerAddCondition(t, Filter(function UnitMovementRegister))
   
    set t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 2.00)
    call TriggerAddCondition(t, Filter(function UnitMovementUnregister))
   
    if gg_trg_Is_Unit_Moving_Config != null then
        call TriggerExecute(gg_trg_Is_Unit_Moving_Config)
    else
        call ExecuteFunc("Trig_Is_Unit_Moving_Config_Actions")
    endif
    call TimerStart(CreateTimer(), udg_UnitMovementInterval, true, function UnitMovementTracker)
endfunction

 
Unit In Action v 1.0.0.0
Addon to UnitEvent to simplify the AI experience of tracking which units can and cannot perform actions

UnitIndexEvent == 1.00 >> Created
DeathEvent == 2.00 >> Ressurrected
CargoEvent == 2.00 >> Unloaded from a transport
Unit In Action
  Events
    Game - UnitIndexEvent becomes Equal to 1.00
    Game - DeathEvent becomes Equal to 2.00
    Game - CargoEvent becomes Equal to 2.00
  Conditions
    UnitInAction[UDex] Equal to False
  Actions
    Set VariableSet UnitInAction[UDex] = True
    Set VariableSet UnitInActionEvent = 0.00
    Set VariableSet UnitInActionEvent = 1.00
    Set VariableSet UnitInActionEvent = 0.00
UnitIndexEvent == 2.00 >> Removed from game
DeathEvent == 0.50 >> Starts Reincarnating
DeathEvent == 1.00 >> Dies
CargoEvent == 1.00 >> Loaded into a transport
Unit Inaction
  Events
    Game - UnitIndexEvent becomes Equal to 2.00
    Game - DeathEvent becomes Equal to 0.50
    Game - DeathEvent becomes Equal to 1.00
    Game - CargoEvent becomes Equal to 1.00
  Conditions
    UnitInAction[UDex] Equal to True
  Actions
    Set VariableSet UnitInAction[UDex] = False
    Set VariableSet UnitInActionEvent = 0.00
    Set VariableSet UnitInActionEvent = 2.00
    Set VariableSet UnitInActionEvent = 0.00
GDD Variable Creator
  Events
  Conditions
  Actions
    Set VariableSet GDD_Event = 0.00
    Set VariableSet GDD_Damage = 0.00
    Set VariableSet GDD_DamagedUnit = No unit
    Set VariableSet GDD_DamageSource = No unit
    Set VariableSet GDD__TriggerArray[0] = (This trigger)
    Set VariableSet GDD__Integers[0] = 0
    Set VariableSet GDD__UnitArray[0] = No unit
    Set VariableSet GDD__LeftMapGroup = GDD__LeftMapGroup
// GUI-Friendly Damage Detection -- v1.2.1 -- by Weep
//    http:// www.thehelper.net/forums/showthread.php?t=137957
//
//    Requires: only this trigger and its variables.
//
// -- What? --
//    This snippet provides a leak-free, GUI-friendly implementation of an "any unit takes
//    damage" event.  It requires no JASS knowledge to use.
//
//    It uses the Game - Value Of Real Variable event as its method of activating other
//    triggers, and passes the event responses through a few globals.
//
// -- Why? --
//    The traditional GUI method of setting up a trigger than runs when any unit is damaged
//    leaks trigger events.  This snippet is easy to implement and removes the need to do
//    you own GUI damage detection setup.
//
// -- How To Implement --
//    0. Before you copy triggers that use GDD into a new map, you need to copy over GDD
//       with its GDD Variable Creator trigger, or there will be a problem: the variables
//       won't be automatically created correctly.
//
//    1. Be sure "Automatically create unknown variables while pasting trigger data" is
//       enabled in the World Editor general preferences.
//    2. Copy this trigger category ("GDD") and paste it into your map.
//       (Alternately: create the variables listed in the globals block below, create a
//       trigger named "GUI Friendly Damage Detection", and paste in this entire text.)
//    3. Create your damage triggers using Game - Value Of Real Variable as the event,
//       select GDD_Event as the variable, and leave the rest of the settings to the default
//       "becomes Equal to 0.00".
//       The event responses are the following variables:
//          GDD_Damage is the amount of damage, replacing Event Response - Damage Taken.
//          GDD_DamagedUnit is the damaged unit, replacing Event Response - Triggering Unit.
//              Triggering Unit can still be used, if you need to use waits.
//              Read the -- Notes -- section below for more info.
//          GDD_DamageSource is the damaging unit, replacing Event Response - Damage Source.
//
// -- Notes --
//    GDD's event response variables are not wait-safe; you can't use them after a wait in
//    a trigger.  If you need to use waits, Triggering Unit (a.k.a. GetTriggerUnit()) can
//    be used in place of GDD_DamageSource.  There is no usable wait-safe equivalent to
//    Event Damage or Damage Source; you'll need to save the values yourself.
//
//    Don't write any values to the variables used as the event responses, or it will mess
//    up any other triggers using this snippet for their triggering.  Only use their values.
//
//    This uses arrays, so can detect damage for a maximum of 8190 units at a time, and
//    cleans up data at a rate of 33.33 per second, by default.  This should be enough for
//    most maps, but if you want to change the rate, change the value returned in the
//    GDD_RecycleRate function at the top of the code, below.
//
//    By default, GDD will not register units that have Locust at the moment of their
//    entering the game, and will not recognize when they take damage (which can only
//    happen if the Locust ability is later removed from the unit.)  To allow a unit to have
//    Locust yet still cause GDD damage events if Locust is removed, you can either design
//    the unit to not have Locust by default and add it via triggers after creation, or
//    edit the GDD_Filter function at the top of the code, below.
//
// -- Credits --
//    Captain Griffin on wc3c.net for the research and concept of GroupRefresh.
//
//    Credit in your map not needed, but please include this README.
//
// -- Version History --
//    1.2.1: Minor code cleaning.  Added configuration functions.  Updated documentation.
//    1.2.0: Made this snippet work properly with recursive damage.
//    1.1.1: Added a check in order to not index units with the Locust ability (dummy units).
//           If you wish to check for damage taken by a unit that is unselectable, do not
//           give the unit-type Locust in the object editor; instead, add the Locust ability
//           'Aloc' via a trigger after its creation, then remove it.
//    1.1.0: Added a check in case a unit gets moved out of the map and back.
//    1.0.0: First release.


//===================================================================
// Configurables.
function GDD_RecycleRate takes nothing returns real //The rate at which the system checks units to see if they've been removed from the game
    return 0.03
endfunction

function GDD_Filter takes unit u returns boolean //The condition a unit has to pass to have it registered for damage detection
    return GetUnitAbilityLevel(u, 'Aloc') == 0 //By default, the system ignores Locust units, because they normally can't take damage anyway
endfunction

//===================================================================
// This is just for reference.
// If you use JassHelper, you could uncomment this section instead of creating the variables in the trigger editor.

// globals
//  real udg_GDD_Event = 0.
//  real udg_GDD_Damage = 0.
//  unit udg_GDD_DamagedUnit
//  unit udg_GDD_DamageSource
//  trigger array udg_GDD__TriggerArray
//  integer array udg_GDD__Integers
//  unit array udg_GDD__UnitArray
//  group udg_GDD__LeftMapGroup = CreateGroup()
// endglobals

//===================================================================
// System code follows.  Don't touch!
function GDD_Event takes nothing returns boolean
    local unit damagedcache = udg_GDD_DamagedUnit
    local unit damagingcache = udg_GDD_DamageSource
    local real damagecache = udg_GDD_Damage
    set udg_GDD_DamagedUnit = GetTriggerUnit()
    set udg_GDD_DamageSource = GetEventDamageSource()
    set udg_GDD_Damage = GetEventDamage()
    set udg_GDD_Event = 1.
    set udg_GDD_Event = 0.
    set udg_GDD_DamagedUnit = damagedcache
    set udg_GDD_DamageSource = damagingcache
    set udg_GDD_Damage = damagecache
    set damagedcache = null
    set damagingcache = null
    return false
endfunction

function GDD_AddDetection takes nothing returns boolean
//  if(udg_GDD__Integers[0] > 8190) then
//      call BJDebugMsg("GDD: Too many damage events!  Decrease number of units present in the map or increase recycle rate.")
//      ***Recycle rate is specified in the GDD_RecycleRate function at the top of the code.  Smaller is faster.***
//      return
//  endif
    if(IsUnitInGroup(GetFilterUnit(), udg_GDD__LeftMapGroup)) then
        call GroupRemoveUnit(udg_GDD__LeftMapGroup, GetFilterUnit())
    elseif(GDD_Filter(GetFilterUnit())) then
        set udg_GDD__Integers[0] = udg_GDD__Integers[0]+1
        set udg_GDD__UnitArray[udg_GDD__Integers[0]] = GetFilterUnit()
        set udg_GDD__TriggerArray[udg_GDD__Integers[0]] = CreateTrigger()
        call TriggerRegisterUnitEvent(udg_GDD__TriggerArray[udg_GDD__Integers[0]], udg_GDD__UnitArray[udg_GDD__Integers[0]], EVENT_UNIT_DAMAGED)
        call TriggerAddCondition(udg_GDD__TriggerArray[udg_GDD__Integers[0]], Condition(function GDD_Event))
    endif
    return false
endfunction

function GDD_PreplacedDetection takes nothing returns nothing
    local group g = CreateGroup()
    local integer i = 0
    loop
        call GroupEnumUnitsOfPlayer(g, Player(i), Condition(function GDD_AddDetection))
        set i = i+1
        exitwhen i == bj_MAX_PLAYER_SLOTS
    endloop
    call DestroyGroup(g)
    set g = null
endfunction

function GDD_GroupRefresh takes nothing returns nothing
// Based on GroupRefresh by Captain Griffen on wc3c.net
    if (bj_slotControlUsed[5063] == true) then
        call GroupClear(udg_GDD__LeftMapGroup)
        set bj_slotControlUsed[5063] = false
    endif
    call GroupAddUnit(udg_GDD__LeftMapGroup, GetEnumUnit())
endfunction

function GDD_Recycle takes nothing returns nothing
    if(udg_GDD__Integers[0] <= 0) then
        return
    elseif(udg_GDD__Integers[1] <= 0) then
        set udg_GDD__Integers[1] = udg_GDD__Integers[0]
    endif
    if(GetUnitTypeId(udg_GDD__UnitArray[udg_GDD__Integers[1]]) == 0) then
        call DestroyTrigger(udg_GDD__TriggerArray[udg_GDD__Integers[1]])
        set udg_GDD__TriggerArray[udg_GDD__Integers[1]] = null
        set udg_GDD__TriggerArray[udg_GDD__Integers[1]] = udg_GDD__TriggerArray[udg_GDD__Integers[0]]
        set udg_GDD__UnitArray[udg_GDD__Integers[1]] = udg_GDD__UnitArray[udg_GDD__Integers[0]]
        set udg_GDD__UnitArray[udg_GDD__Integers[0]] = null
        set udg_GDD__Integers[0] = udg_GDD__Integers[0]-1
    endif
    set udg_GDD__Integers[1] = udg_GDD__Integers[1]-1
endfunction

function GDD_LeaveMap takes nothing returns boolean
    local boolean cached = bj_slotControlUsed[5063]
    if(udg_GDD__Integers[2] < 64) then
        set udg_GDD__Integers[2] = udg_GDD__Integers[2]+1
    else
        set bj_slotControlUsed[5063] = true
        call ForGroup(udg_GDD__LeftMapGroup, function GDD_GroupRefresh)
        set udg_GDD__Integers[2] = 0
    endif
    call GroupAddUnit(udg_GDD__LeftMapGroup, GetFilterUnit())
    set bj_slotControlUsed[5063] = cached
    return false
endfunction

// ===========================================================================
function InitTrig_GUI_Friendly_Damage_Detection takes nothing returns nothing
    local region r = CreateRegion()
    call RegionAddRect(r, GetWorldBounds())
    call TriggerRegisterEnterRegion(CreateTrigger(), r, Condition(function GDD_AddDetection))
    call TriggerRegisterLeaveRegion(CreateTrigger(), r, Condition(function GDD_LeaveMap))
    call GDD_PreplacedDetection()
    call TimerStart(CreateTimer(), GDD_RecycleRate(), true, function GDD_Recycle)
    set r = null
endfunction
Knockback
  Events
    Unit - A unit Begins casting an ability
  Conditions
    (Ability being cast) Equal to Knockback (Dummy Spell)
  Actions
    -------- This are spell effects. They donĀ“t affect the knockback. --------
    Set VariableSet KB_EffectPoint = (Position of (Triggering unit))
    Set VariableSet KB_Group = (Units within 250.00 of KB_EffectPoint matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is Magic Immune) Equal to False) and ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True)))).)
    Destructible - Pick every destructible within 200.00 of KB_EffectPoint and do (Actions)
      Loop - Actions
        Destructible - Kill (Picked destructible)
    Special Effect - Create a special effect at AB_Point3 using AB_Effects1[AB_Temp]
    Special Effect - Destroy (Last created special effect)
    -------- The setting values --------
    Unit Group - Pick every unit in KB_Group and do (Actions)
      Loop - Actions
        Set VariableSet KBA_Caster = (Triggering unit)
        Set VariableSet KBA_TargetUnit = (Picked unit)
        Set VariableSet KBA_Level = (Level of (Ability being cast) for (Triggering unit))
        Set VariableSet KBA_StartingPosition = (Position of (Triggering unit))
        Set VariableSet KBA_Speed = 5.00
        Set VariableSet KBA_ManaLeak = 1
        Set VariableSet KBA_DistancePerLevel = 200.00
        Set VariableSet KBA_SpecialEffects[1] = Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
        Set VariableSet KBA_SpecialEffects[2] = Abilities\Spells\Human\Feedback\ArcaneTowerAttack.mdl
        Set VariableSet KBA_DestroyTrees = True
        Trigger - Run Cast_A_Knockback <gen> (checking conditions)
    Custom script: call RemoveLocation (udg_KB_EffectPoint)
    Custom script: call DestroyGroup (udg_KB_Group)
Cast A Knockback
  Events
  Conditions
  Actions
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (KBA_TargetUnit is in KB_KnockbackedUnits.) Equal to True
      Then - Actions
        Unit Group - Remove KBA_TargetUnit from KB_KnockbackedUnits.
        Set VariableSet KB_CountBuffs = (KB_CountBuffs - 1)
        For each (Integer KB_GeneralIntegers[2]) from 1 to KB_TotalKnockUnits, do (Actions)
          Loop - Actions
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                KB_Units[KB_GeneralIntegers[1]] Equal to KBA_TargetUnit
              Then - Actions
                Set VariableSet KB_GeneralIntegers[1] = KB_GeneralIntegers[2]
                Set VariableSet KB_GeneralIntegers[2] = KB_TotalKnockUnits
              Else - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            KB_TotalKnockUnits Greater than KB_GeneralIntegers[1]
          Then - Actions
            Set VariableSet KB_Levels[KB_GeneralIntegers[1]] = KB_Levels[KB_TotalKnockUnits]
            Set VariableSet KB_Units[KB_GeneralIntegers[1]] = KB_Units[KB_TotalKnockUnits]
            Set VariableSet KB_Angle[KB_GeneralIntegers[1]] = KB_Angle[KB_TotalKnockUnits]
            Set VariableSet KB_MaxDistance[KB_GeneralIntegers[1]] = KB_MaxDistance[KB_TotalKnockUnits]
            Set VariableSet KB_ReachedDistance[KB_GeneralIntegers[1]] = KB_ReachedDistance[KB_TotalKnockUnits]
            Set VariableSet KB_ReduceSpeedReal[KB_GeneralIntegers[1]] = KB_ReduceSpeedReal[KB_TotalKnockUnits]
            Set VariableSet KB_SpecificSpeed[KB_GeneralIntegers[1]] = KB_SpecificSpeed[KB_TotalKnockUnits]
            Set VariableSet KB_Effects_1[KB_GeneralIntegers[1]] = KB_Effects_1[KB_TotalKnockUnits]
            Set VariableSet KB_Effects_2[KB_GeneralIntegers[1]] = KB_Effects_2[KB_TotalKnockUnits]
            Set VariableSet KB_DestroyTrees[KB_GeneralIntegers[1]] = KB_DestroyTrees[KB_TotalKnockUnits]
            Set VariableSet KB_EffectCounter[KB_GeneralIntegers[1]] = KB_EffectCounter[KB_TotalKnockUnits]
            Set VariableSet KB_EffectCounter2[KB_GeneralIntegers[1]] = KB_EffectCounter2[KB_TotalKnockUnits]
            Set VariableSet KB_GeneralIntegers[1] = (KB_GeneralIntegers[1] - 1)
          Else - Actions
        Set VariableSet KB_Units[KB_TotalKnockUnits] = No unit
        Set VariableSet KB_TotalKnockUnits = (KB_TotalKnockUnits - 1)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            KB_CountBuffs Equal to 0
          Then - Actions
            Set VariableSet KB_TotalKnockUnits = 0
            Trigger - Turn off Get_Knockback <gen>
          Else - Actions
      Else - Actions
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        KB_CountBuffs Equal to 0
      Then - Actions
        Trigger - Turn on Get_Knockback <gen>
      Else - Actions
    Set VariableSet KB_CountBuffs = (KB_CountBuffs + 1)
    Set VariableSet KB_TotalKnockUnits = (KB_TotalKnockUnits + 1)
    Set VariableSet KB_Casters[KB_TotalKnockUnits] = KBA_Caster
    Set VariableSet KB_Levels[KB_TotalKnockUnits] = KBA_Level
    Set VariableSet KB_Units[KB_TotalKnockUnits] = KBA_TargetUnit
    Set VariableSet KB_StartPositions[KB_TotalKnockUnits] = KBA_StartingPosition
    Set VariableSet KB_TempPoint[KB_TotalKnockUnits] = (Position of KBA_TargetUnit)
    Set VariableSet KB_Angle[KB_TotalKnockUnits] = (Angle from KB_StartPositions[KB_TotalKnockUnits] to KB_TempPoint[KB_TotalKnockUnits])
    Set VariableSet KB_MaxDistance[KB_TotalKnockUnits] = (KBA_DistancePerLevel x (Real(KBA_Level)))
    Set VariableSet KB_ReachedDistance[KB_TotalKnockUnits] = 0.00
    Set VariableSet KB_ReduceSpeedReal[KB_GeneralIntegers[1]] = 0.00
    Set VariableSet KB_SpecificSpeed[KB_TotalKnockUnits] = KBA_Speed
    Set VariableSet KB_Effects_1[KB_TotalKnockUnits] = KBA_SpecialEffects[1]
    Set VariableSet KB_Effects_2[KB_TotalKnockUnits] = KBA_SpecialEffects[2]
    Set VariableSet KB_DestroyTrees[KB_TotalKnockUnits] = KBA_DestroyTrees
    Set VariableSet KB_EffectCounter[KB_GeneralIntegers[1]] = 0
    Set VariableSet KB_EffectCounter2[KB_GeneralIntegers[1]] = 0
    Unit Group - Add KBA_TargetUnit to KB_KnockbackedUnits
    Custom script: call RemoveLocation (udg_KBA_StartingPosition)
    Custom script: call RemoveLocation (udg_KB_TempPoint [udg_KB_TotalKnockUnits] )
    Custom script: call RemoveLocation (udg_KB_StartPositions [udg_KB_TotalKnockUnits] )
Get Knockback
  Events
    Time - Every 0.02 seconds of game time
  Conditions
  Actions
    For each (Integer KB_GeneralIntegers[1]) from 1 to KB_TotalKnockUnits, do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (KB_Units[KB_GeneralIntegers[1]] is in KB_KnockbackedUnits.) Equal to True
          Then - Actions
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                KB_ReachedDistance[KB_GeneralIntegers[1]] Greater than or equal to KB_MaxDistance[KB_GeneralIntegers[1]]
              Then - Actions
                Unit Group - Remove KB_Units[KB_GeneralIntegers[1]] from KB_KnockbackedUnits.
                Set VariableSet KB_CountBuffs = (KB_CountBuffs - 1)
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  If - Conditions
                    KB_TotalKnockUnits Greater than KB_GeneralIntegers[1]
                  Then - Actions
                    Set VariableSet KB_Levels[KB_GeneralIntegers[1]] = KB_Levels[KB_TotalKnockUnits]
                    Set VariableSet KB_Units[KB_GeneralIntegers[1]] = KB_Units[KB_TotalKnockUnits]
                    Set VariableSet KB_Angle[KB_GeneralIntegers[1]] = KB_Angle[KB_TotalKnockUnits]
                    Set VariableSet KB_MaxDistance[KB_GeneralIntegers[1]] = KB_MaxDistance[KB_TotalKnockUnits]
                    Set VariableSet KB_ReachedDistance[KB_GeneralIntegers[1]] = KB_ReachedDistance[KB_TotalKnockUnits]
                    Set VariableSet KB_ReduceSpeedReal[KB_GeneralIntegers[1]] = KB_ReduceSpeedReal[KB_TotalKnockUnits]
                    Set VariableSet KB_SpecificSpeed[KB_GeneralIntegers[1]] = KB_SpecificSpeed[KB_TotalKnockUnits]
                    Set VariableSet KB_Effects_1[KB_GeneralIntegers[1]] = KB_Effects_1[KB_TotalKnockUnits]
                    Set VariableSet KB_Effects_2[KB_GeneralIntegers[1]] = KB_Effects_2[KB_TotalKnockUnits]
                    Set VariableSet KB_DestroyTrees[KB_GeneralIntegers[1]] = KB_DestroyTrees[KB_TotalKnockUnits]
                    Set VariableSet KB_EffectCounter[KB_GeneralIntegers[1]] = KB_EffectCounter[KB_TotalKnockUnits]
                    Set VariableSet KB_EffectCounter2[KB_GeneralIntegers[1]] = KB_EffectCounter2[KB_TotalKnockUnits]
                    Set VariableSet KB_GeneralIntegers[1] = (KB_GeneralIntegers[1] - 1)
                  Else - Actions
                Set VariableSet KB_Units[KB_TotalKnockUnits] = No unit
                Set VariableSet KB_TotalKnockUnits = (KB_TotalKnockUnits - 1)
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  If - Conditions
                    KB_CountBuffs Equal to 0
                  Then - Actions
                    Set VariableSet KB_TotalKnockUnits = 0
                    Trigger - Turn off (This trigger)
                  Else - Actions
              Else - Actions
                Set VariableSet KB_ReducedReal = ((KB_SpecificSpeed[KB_GeneralIntegers[1]] / KB_MaxDistance[KB_GeneralIntegers[1]]) x KB_ReachedDistance[KB_GeneralIntegers[1]])
                Set VariableSet KB_ReduceSpeedReal[KB_GeneralIntegers[1]] = (KB_ReducedReal - (KB_ReduceSpeedReal[KB_GeneralIntegers[1]] x 0.10))
                Set VariableSet KB_TempReal = ((KB_SpecificSpeed[KB_GeneralIntegers[1]] - KB_ReduceSpeedReal[KB_GeneralIntegers[1]]) x 2.00)
                Set VariableSet KB_TempPoint[1] = (Position of KB_Units[KB_GeneralIntegers[1]])
                Set VariableSet KB_TempPoint[2] = (KB_TempPoint[1] offset by KB_TempReal towards KB_Angle[KB_GeneralIntegers[1]] degrees.)
                Set VariableSet KB_EffectCounter[KB_GeneralIntegers[1]] = (KB_EffectCounter[KB_GeneralIntegers[1]] + 1)
                Set VariableSet KB_EffectCounter2[KB_GeneralIntegers[1]] = (KB_EffectCounter2[KB_GeneralIntegers[1]] + 1)
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  If - Conditions
                    KB_DestroyTrees[KB_GeneralIntegers[1]] Equal to True
                  Then - Actions
                    Destructible - Pick every destructible within 200.00 of KB_TempPoint[2] and do (Actions)
                      Loop - Actions
                        Destructible - Kill (Picked destructible)
                  Else - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  If - Conditions
                    KB_EffectCounter[KB_GeneralIntegers[1]] Equal to 6
                  Then - Actions
                    Set VariableSet KB_EffectCounter[KB_GeneralIntegers[1]] = 0
                    Special Effect - Create a special effect at KB_TempPoint[1] using KB_Effects_1[KB_GeneralIntegers[1]]
                    Special Effect - Destroy (Last created special effect)
                  Else - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  If - Conditions
                    KB_EffectCounter2[KB_GeneralIntegers[1]] Equal to 8
                  Then - Actions
                    Set VariableSet KB_EffectCounter2[KB_GeneralIntegers[1]] = 0
                    Special Effect - Create a special effect at KB_TempPoint[1] using KB_Effects_2[KB_GeneralIntegers[1]]
                    Special Effect - Destroy (Last created special effect)
                  Else - Actions
                Unit - Move KB_Units[KB_GeneralIntegers[1]] instantly to KB_TempPoint[2]
                Unit - Set mana of KB_Units[KB_GeneralIntegers[1]] to ((Mana of KB_Units[KB_GeneralIntegers[1]]) - (Real(KBA_ManaLeak)))
                Custom script: call RemoveLocation (udg_KB_TempPoint[1])
                Custom script: call RemoveLocation (udg_KB_TempPoint[2])
                Set VariableSet KB_ReachedDistance[KB_GeneralIntegers[1]] = (KB_ReachedDistance[KB_GeneralIntegers[1]] + KB_TempReal)
          Else - Actions
UniversalAbilityInit
  Events
    Time - Elapsed game time is 0.00 seconds
  Conditions
  Actions
    -------- BloodElf --------
    Set VariableSet LD_Ability = Life Drain (Priest)(Blood Elf)
    Set VariableSet LD_AbilityDrain = Life Drain (Custom)(Priest Dummy)(Blood Elf Dummy)
    Set VariableSet LD_Life = 35
    Set VariableSet LD_SearchRange = 400
    Set VariableSet ASA_Ability = Crimson Arrows (Archer)(Blood Elf)
    Set VariableSet ASA_LifeUse = 8.00
    Player Group - Pick every player in (All players) and do (Actions)
      Loop - Actions
        -------- Races --------
        -------- Corrupted Night Elves --------
        Player - Make Vile Soul (AI)(Corrupted) Unavailable for training/construction by (Picked player)
        -------- Bronzebeard Dwarves --------
        Player - Disable Enhanced Stoneform (Miner)(Dwarves) for (Picked player)
        -------- Kul'tiras --------
        Player - Make Admiralty Royal Guard (Kul'tiras) Unavailable for training/construction by (Picked player)
        Player - Make Flibustier (Kul'tiras) Unavailable for training/construction by (Picked player)
        Player - Make Gryphon Ranger (Kul'tiras) Unavailable for training/construction by (Picked player)
        -------- Stormwind Humans --------
        Player - Make Half-Elf Ranger (Stormwind Humans) Unavailable for training/construction by (Picked player)
        Player - Make Justiciar (Stormwind Humans) Unavailable for training/construction by (Picked player)
        Player - Make Grand Justiciar (Stormwind Humans) Unavailable for training/construction by (Picked player)
        -------- Chaos Orcs --------
        Player - Make Ogre-Mage (Chaos Orcs) Unavailable for training/construction by (Picked player)
        -------- Blood Elves --------
        Player - Make Blood Knight Initiate (Blood Elf) Unavailable for training/construction by (Picked player)
    Custom script: call DestroyTrigger( GetTriggeringTrigger() )
Credits to -

Viikuna for the Cargo Hold ability that disable the attack of the unit.....
Chain Sword On
  Events
    Unit - A unit Is attacked
  Conditions
    (Level of Glaive Throw (Tirathon)(Blood Elf) for (Attacking unit)) Greater than or equal to 1
  Actions
    Set VariableSet CS_LEVEL = (Level of Glaive Throw (Tirathon)(Blood Elf) for (Attacking unit))
    Set VariableSet CS_Chance = (CS_LEVEL x 5)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Random integer number between 1 and 100) Less than or equal to CS_Chance
      Then - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            CS_Skip Equal to 0
          Then - Actions
            Trigger - Turn on Chain_Sword_Loop <gen>
          Else - Actions
        Set VariableSet CS_Times = (CS_Times + 1)
        Set VariableSet CS_Skip = (CS_Skip + 1)
        Set VariableSet CS_Off[CS_Times] = True
        Set VariableSet CS_Attacked[CS_Times] = (Attacked unit)
        Set VariableSet CS_Attacking[CS_Times] = (Attacking unit)
        Set VariableSet CS_Point[0] = (Position of CS_Attacking[CS_Times])
        Set VariableSet CS_Speed[CS_Times] = 8.00
        Set VariableSet CS_Damage[CS_Times] = (Real(CS_Chance))
        Set VariableSet CS_Jumps[CS_Times] = (CS_LEVEL + 2)
        Unit - Create 1.Dummy_For_Map for (Owner of CS_Attacking[CS_Times]) at CS_Point[0] facing (Facing of CS_Attacking[CS_Times]) degrees
        Set VariableSet CS_Dummy[CS_Times] = (Last created unit)
        Special Effect - Create a special effect attached to the chest (attachpoint) of CS_Dummy[CS_Times] using Local\IllidanMissile.mdx
        Set VariableSet CS_SpecialEffect[CS_Times] = (Last created special effect)
        Custom script: call RemoveLocation(udg_CS_Point[0])
      Else - Actions
Chain Sword Loop
  Events
    Time - Every 0.02 seconds of game time
  Conditions
  Actions
    For each (Integer CS) from 1 to CS_Times, do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            CS_Off[CS] Equal to True
          Then - Actions
            Set VariableSet CS_Point[1] = (Position of CS_Attacked[CS])
            Set VariableSet CS_Point[2] = (Position of CS_Dummy[CS])
            Set VariableSet CS_Point[3] = (CS_Point[2] offset by CS_Speed[CS] towards (Angle from CS_Point[2] to CS_Point[1]) degrees.)
            Unit - Make CS_Dummy[CS] face CS_Attacked[CS] over 0.02 seconds
            Unit - Move CS_Dummy[CS] instantly to CS_Point[3]
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (Distance between CS_Point[1] and CS_Point[2]) Less than or equal to 32.00
              Then - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  If - Conditions
                    CS_Jumps[CS] Equal to 0
                  Then - Actions
                    Set VariableSet CS_Skip = (CS_Skip - 1)
                    Set VariableSet CS_Off[CS] = False
                    Special Effect - Destroy CS_SpecialEffect[CS]
                    Unit - Add a 0.01 second Generic expiration timer to CS_Dummy[CS]
                    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      If - Conditions
                        CS_Skip Equal to 0
                      Then - Actions
                        Set VariableSet CS_Times = 0
                        Trigger - Turn off Chain_Sword_Loop <gen>
                      Else - Actions
                  Else - Actions
                    -------- We reduce the number of jumps --------
                    Set VariableSet CS_Jumps[CS] = (CS_Jumps[CS] - 1)
                    Unit - Cause CS_Attacking[CS] to damage CS_Attacked[CS], dealing ((Real((Agility of CS_Attacking[CS] (Include bonuses)))) x 2.00) damage of attack type Hero and damage type Shadow Strike
                    Special Effect - Create a special effect attached to the chest (attachpoint) of CS_Attacked[CS] using Abilities\Spells\Other\Stampede\StampedeMissileDeath.mdl
                    Special Effect - Destroy (Last created special effect)
                    Set VariableSet CS_Group[CS] = (Units within 325.00 of CS_Point[2] matching (((Owner of (Matching unit)) Not equal to (Owner of CS_Attacking[CS])) and (((Matching unit) Not equal to CS_Attacked[CS]) and (((Matching unit) is alive) Equal to True))).)
                    -------- We set it to not unit then set to the unit we want it . to be the next unit --------
                    Set VariableSet CS_Attacked[CS] = No unit
                    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      If - Conditions
                        Or - Any (Conditions) are true
                          Conditions
                            (Number of units in CS_Group[CS]) Equal to 0
                            CS_Jumps[CS] Equal to 0
                      Then - Actions
                        Set VariableSet CS_Attacked[CS] = CS_Attacking[CS]
                        Set VariableSet CS_Jumps[CS] = 0
                      Else - Actions
                        Set VariableSet CS_Attacked[CS] = (Random unit from CS_Group[CS])
                    Custom script: call DestroyGroup(udg_CS_Group[udg_CS])
              Else - Actions
            Custom script: call RemoveLocation(udg_CS_Point[1])
            Custom script: call RemoveLocation(udg_CS_Point[2])
            Custom script: call RemoveLocation(udg_CS_Point[3])
          Else - Actions
DestroyMana
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Destroy Mana (Tirathon)(Blood Elf)
  Actions
    Set VariableSet TempLoc = (Position of (Triggering unit))
    Set VariableSet Jab_Caster = (Triggering unit)
    Set VariableSet Jab_Mod = ((Level of Destroy Mana (Tirathon)(Blood Elf) for Jab_Caster) x 5)
    Unit - Set mana of (Target unit of ability being cast) to ((Percentage mana of (Target unit of ability being cast)) - (Real(Jab_Mod)))%
    Unit - Create 1.DumbDummy for (Owner of (Casting unit)) at TempLoc facing (Facing of (Target unit of ability being cast)) degrees
    Unit - Add Destroy Mana Silence (Blood Elf Dummy) to (Last created unit)
    Unit - Add a 0.20 second Generic expiration timer to (Last created unit)
    Unit - Order (Last created unit) to Neutral Fire Lord - Soul Burn.(Target unit of ability being cast)
    Custom script: call RemoveLocation (udg_TempLoc)
Ignite
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Ignite (Tirathon)(Blood Elf)
  Actions
    Set VariableSet TempLoc = (Position of (Casting unit))
    Unit - Create 1.DumbDummy for (Owner of (Casting unit)) at TempLoc facing (Facing of (Target unit of ability being cast)) degrees
    Unit - Add Ignite Dummy (Blood Elf Dummy) to (Last created unit)
    Unit - Set level of Ignite Dummy (Blood Elf Dummy) for (Last created unit) to (Level of Ignite (Tirathon)(Blood Elf) for (Triggering unit))
    Unit - Add a 0.20 second Generic expiration timer to (Last created unit)
    Unit - Order (Last created unit) to Human Blood Mage - Flame Strike.TempLoc
    Custom script: call RemoveLocation (udg_TempLoc)
TheHunt
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to The Hunt (Tirathon)(Blood Elf)
  Actions
    Custom script: local location TempPoint = GetUnitLoc(GetSpellTargetUnit())
    Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing (Real(((Agility of (Triggering unit) (Include bonuses)) x 7))) damage of attack type Chaos and damage type Normal
    Wait 0.50 game-time seconds
    Special Effect - Create a special effect attached to the origin (attachpoint) of (Triggering unit) using Abilities\Spells\Undead\Darksummoning\DarkSummonTarget.mdl
    Special Effect - Destroy (Last created special effect)
    Custom script: set udg_TempPoint = TempPoint
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Terrain pathing at TempPoint of type Walkability is off) Not equal to True
      Then - Actions
        Unit - Move (Casting unit) instantly to TempPoint
      Else - Actions
    Custom script: call RemoveLocation( udg_TempPoint )
    Custom script: call RemoveLocation( TempPoint )
    Custom script: set TempPoint = null
SanguineBolt
  Events
    Game - GDD_Event becomes Equal to 0
  Conditions
    (GDD_DamagedUnit has buff Mind Rot (Blood Elf Dummy)) Equal to True
    Or - Any (Conditions) are true
      Conditions
        (Unit-type of GDD_DamageSource) Equal to Blood Mage (Blood Elf)
        (Unit-type of GDD_DamageSource) Equal to DumbDummy
  Actions
    Set VariableSet SearingLight_Mod = (Level of Sanguine Bolt (Blood Mage)(Blood Elf) for GDD_DamageSource)
    Set VariableSet TempLoc = (Position of GDD_DamageSource)
    Unit - Remove Mind Rot (Blood Elf Dummy) buff from GDD_DamagedUnit
    Unit - Set life of GDD_DamageSource to ((Percentage life of GDD_DamageSource) + (Real(SearingLight_Mod)))%
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (GDD_DamagedUnit is alive) Equal to True
      Then - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (GDD_DamagedUnit is A Hero) Equal to False
          Then - Actions
            -------- Unit Only Stuff --------
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (Max HP of GDD_DamagedUnit) Greater than or equal to 110
              Then - Actions
                If ((Level of Sanguine Bolt (Blood Mage)(Blood Elf) for GDD_DamageSource) Less than or equal to 1) then do (Set Max HP of GDD_DamagedUnit to ((Max HP of GDD_DamagedUnit) - ((Max HP of GDD_DamagedUnit) / (Integer(100.00))))) else do (Do nothing)
                If ((Level of Sanguine Bolt (Blood Mage)(Blood Elf) for GDD_DamageSource) Equal to 2) then do (Set Max HP of GDD_DamagedUnit to ((Max HP of GDD_DamagedUnit) - ((Max HP of GDD_DamagedUnit) / (Integer(50.00))))) else do (Do nothing)
                If ((Level of Sanguine Bolt (Blood Mage)(Blood Elf) for GDD_DamageSource) Equal to 3) then do (Set Max HP of GDD_DamagedUnit to ((Max HP of GDD_DamagedUnit) - ((Max HP of GDD_DamagedUnit) / (Integer(33.34))))) else do (Do nothing)
              Else - Actions
          Else - Actions
            -------- Hero Only Stuff --------
            Unit - Create 1.Sanguine Bolt Hero Dummy (Blood Elf Dummy) for Neutral Hostile at TempLoc facing (Facing of GDD_DamageSource) degrees
            Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
            Unit - Order (Last created unit) to Attack.GDD_DamagedUnit
        -------- Exanguinate --------
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (Percentage life of GDD_DamageSource) Greater than (Percentage life of GDD_DamagedUnit)
          Then - Actions
            Unit - Create 1.DumbDummy for (Owner of GDD_DamageSource) at TempLoc facing (Facing of GDD_DamageSource) degrees
            Set VariableSet Temp_Unit = (Last created unit)
            Unit - Add Exanguinate Dummy (Blood Elf Dummy) to Temp_Unit
            Unit - Set level of Exanguinate Dummy (Blood Elf Dummy) for Temp_Unit to (Level of Sanguine Bolt (Blood Mage)(Blood Elf) for GDD_DamageSource)
            Unit - Add a 0.50 second Generic expiration timer to Temp_Unit
            Custom script: call IssueTargetOrderById(udg_Temp_Unit, 852565, udg_GDD_DamagedUnit)
            Unit - Create 1.DumbDummy for (Owner of GDD_DamageSource) at TempLoc facing (Facing of GDD_DamageSource) degrees
            Set VariableSet Temp_Unit = (Last created unit)
            Unit - Add Exanguinate Dummy Buff (Blood Elf Dummy) to Temp_Unit
            Unit - Set level of Exanguinate Dummy Buff (Blood Elf Dummy) for Temp_Unit to (Level of Sanguine Bolt (Blood Mage)(Blood Elf) for GDD_DamageSource)
            Unit - Add a 0.50 second Generic expiration timer to Temp_Unit
            Custom script: call IssueTargetOrderById(udg_Temp_Unit, 852565, udg_GDD_DamageSource)
          Else - Actions
      Else - Actions
    Custom script: call RemoveLocation (udg_TempLoc)
DualPhoenixbolt
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Phoenixbolt (Blood Mage)(Blood Elf)
    (Level of Dualcasting (Blood Mage)(Blood Elf) for (Triggering unit)) Greater than or equal to 1
  Actions
    Set VariableSet SearingLight_Mod = (Level of Dualcasting (Blood Mage)(Blood Elf) for (Triggering unit))
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Random integer number between 1 and 10) Less than or equal to SearingLight_Mod
      Then - Actions
        Set VariableSet TempLoc = (Position of (Casting unit))
        Set VariableSet TempPoint = (Target point of ability being cast)
        Unit - Create 1.DumbDummy for (Owner of (Casting unit)) at TempLoc facing (Facing of (Target unit of ability being cast)) degrees
        Unit - Add Phoenixbolt (Blood Mage)(Blood Elf Dummy)(Recast Dummy) to (Last created unit)
        Unit - Set level of Phoenixbolt (Blood Mage)(Blood Elf Dummy)(Recast Dummy) for (Last created unit) to SearingLight_Mod
        Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
        Unit - Order (Last created unit) to Neutral - Breath Of Frost.TempPoint
        Custom script: call RemoveLocation (udg_TempLoc)
        Custom script: call RemoveLocation (udg_TempPoint)
      Else - Actions
DualSanguineBolt
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Sanguine Bolt (Blood Mage)(Blood Elf)
    (Level of Dualcasting (Blood Mage)(Blood Elf) for (Triggering unit)) Greater than or equal to 1
  Actions
    Set VariableSet SearingLight_Mod = (Level of Dualcasting (Blood Mage)(Blood Elf) for (Triggering unit))
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Random integer number between 1 and 10) Less than or equal to SearingLight_Mod
      Then - Actions
        Set VariableSet TempLoc = (Position of (Casting unit))
        Unit - Create 1.DumbDummy for (Owner of (Casting unit)) at TempLoc facing (Facing of (Target unit of ability being cast)) degrees
        Unit - Add Sanguine Bolt (Blood Mage)(Blood Elf Dummy)(Recast Dummy) to (Last created unit)
        Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
        Unit - Order (Last created unit) to Human Mountain King - Storm Bolt.(Target unit of ability being cast)
        Custom script: call RemoveLocation (udg_TempLoc)
      Else - Actions
BurstingTarTrap
  Events
    Unit - A unit Dies
  Conditions
    (Unit-type of (Dying unit)) Equal to Bursting Tar Trap (Blood Elf)
  Actions
    Set VariableSet TempLoc = (Position of (Dying unit))
    Set VariableSet Temp_Group_1 = (Units within 500.00 of TempLoc matching ((((Matching unit) belongs to an enemy of (Owner of (Dying unit)).) Equal to True) and (((Matching unit) is dead) Equal to False)).)
    Special Effect - Create a special effect at TempLoc using Abilities\Spells\Other\Incinerate\FireLordDeathExplode.mdl
    Special Effect - Set Scale of (Last created special effect) to 2.50
    Special Effect - Set Alpha of (Last created special effect) to 127
    Special Effect - Destroy (Last created special effect)
    Unit Group - Pick every unit in Temp_Group_1 and do (Actions)
      Loop - Actions
        Unit - Cause (Triggering unit) to damage (Picked unit), dealing 175.00 damage of attack type Chaos and damage type Universal
    Custom script: call DestroyGroup(udg_Temp_Group_1)
    Custom script: call RemoveLocation (udg_TempLoc)
TrickShot
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Trick Shot (Ranger Captain)(Blood Elf)
  Actions
    Set VariableSet SearingLight_Caster = (Triggering unit)
    Set VariableSet SearingLight_Mod = ((Level of Trick Shot (Ranger Captain)(Blood Elf) for SearingLight_Caster) + 2)
    Player - Set the current research level of R041 (techcode) to (SearingLight_Mod - 2) for (Owner of (Triggering unit))
    Wait (Real(SearingLight_Mod)) seconds
    Player - Set the current research level of R041 (techcode) to 0 for (Owner of (Triggering unit))
LightsReckoning
  Events
    Unit - A unit Is issued an order with no target
  Conditions
    (Issued order) Equal to (Order(taunt))
    (Level of Light's Reckoning (Quihin)(Blood Elf) for (Triggering unit)) Greater than or equal to 1
  Actions
    Set VariableSet TempLoc = (Position of (Triggering unit))
    Unit - Create 1.DumbDummy for (Owner of (Triggering unit)) at TempLoc facing Default building facing degrees
    Unit - Add Howl of Terror (Light'sReckoningDummy)(Blood Elf Dummy) to (Last created unit)
    Unit - Add a 0.20 second Generic expiration timer to (Last created unit)
    Unit - Order (Last created unit) to Neutral Pit Lord - Howl Of Terror.
    Custom script: call RemoveLocation (udg_TempLoc)
SearingLight
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Searing Light (Quihin)(Blood Elf)
  Actions
    Set VariableSet Jab_Caster = (Triggering unit)
    Set VariableSet Jab_Mod = ((Level of Searing Light (Quihin)(Blood Elf) for Jab_Caster) x 100)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        ((Target unit of ability being cast) is Undead) Equal to True
      Then - Actions
        Unit - Cause Jab_Caster to damage (Target unit of ability being cast), dealing ((Real(Jab_Mod)) x 2.00) damage of attack type Chaos and damage type Universal
      Else - Actions
        Unit - Cause Jab_Caster to damage (Target unit of ability being cast), dealing ((Real(Jab_Mod)) x 1.00) damage of attack type Chaos and damage type Universal
PhoenixFireSpawn
  Events
    Unit - A unit enters (Playable map area)
  Conditions
    (Unit-type of (Triggering unit)) Equal to Phoenix (Blood Elf)
    (Current research level of R00H (techcode) for (Owner of (Triggering unit))) Greater than or equal to 1
  Actions
    Unit - Add Phoenix Fire (Phoenix)(Blood Elf) to (Triggering unit)
PhoenixFireStart
  Events
    Time - Elapsed game time is 0.50 seconds
  Conditions
  Actions
    Player Group - Pick every player in (All players) and do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (Current research level of R00H (techcode) for (Picked player)) Greater than or equal to 1
          Then - Actions
            Set VariableSet CreepTempGroup = (Units owned by (Picked player) matching ((Unit-type of (Matching unit)) Equal to Phoenix (Blood Elf)).)
            Unit Group - Pick every unit in CreepTempGroup and do (Actions)
              Loop - Actions
                Unit - Add Phoenix Fire (Phoenix)(Blood Elf) to (Picked unit)
            Custom script: call DestroyGroup(udg_CreepTempGroup)
          Else - Actions
Default melee game initialization for all players
ASA Activate Deactivate
  Events
    Unit - A unit Is issued an order with no target
  Conditions
  Actions
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Issued order) Equal to (Order(poisonarrows))
      Then - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (Life of (Triggering unit)) Greater than or equal to ASA_LifeUse
          Then - Actions
            Unit Group - Add (Triggering unit) to ASA_Group
          Else - Actions
            Wait 0.00 seconds
            Unit - Order (Triggering unit) to Neutral - Deactivate Poison Arrows.
      Else - Actions
ASA Event
  Events
    Game - GDD_Event becomes Greater than 0
  Conditions
    (GDD_DamagedUnit has buff Mind Rot (Blood Elf Dummy)) Equal to True
    (Unit-type of GDD_DamageSource) Equal to Farstrider (Blood Elf)
  Actions
    Unit - Remove Mind Rot (Blood Elf Dummy) buff from GDD_DamagedUnit
    Unit - Set life of GDD_DamageSource to ((Life of GDD_DamageSource) - ASA_LifeUse)
ASA Prevent
  Events
    Unit - A unit Is attacked
  Conditions
  Actions
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        ((Attacking unit) is in ASA_Group.) Equal to True
        (Life of (Attacking unit)) Greater than or equal to ASA_LifeUse
      Then - Actions
      Else - Actions
        Unit Group - Remove (Attacking unit) from ASA_Group.
        Unit - Order (Attacking unit) to Neutral - Deactivate Poison Arrows.
BH Event
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Blood Heal (Priest)(Blood Elf)
  Actions
    Unit - Set life of (Casting unit) to ((Life of (Casting unit)) - ASA_LifeUse)
Activate
  Events
    Unit - A unit Is attacked
  Conditions
    (Level of LD_Ability for (Triggering unit)) Greater than 0
    (Current research level of R00F (techcode) for (Triggering player)) Greater than 0
  Actions
    Set VariableSet Temp_Unit = (Triggering unit)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Integer((Percentage life of Temp_Unit))) Less than or equal to LD_Life
      Then - Actions
        Set VariableSet Temp_Point = (Position of Temp_Unit)
        Unit - Add LD_AbilityDrain to Temp_Unit
        Set VariableSet Temp_UnitGroup = (Units within (Real(LD_SearchRange)) of Temp_Point matching (((Matching unit) belongs to an enemy of (Owner of Temp_Unit).) Equal to True).)
        Unit Group - Pick every unit in Temp_UnitGroup and do (Actions)
          Loop - Actions
            Unit - Order Temp_Unit to Neutral Dark Ranger - Life Drain.(Picked unit)
        Custom script: call DestroyGroup( udg_Temp_UnitGroup )
        Custom script: call RemoveLocation( udg_Temp_Point )
        Custom script: set udg_Temp_Point = null
      Else - Actions
    Custom script: set udg_Temp_Unit = null
Cancel
  Events
    Unit - A unit Is issued an order targeting a point
    Unit - A unit Is issued an order with no target
  Conditions
    (String((Issued order))) Not equal to stop
    (Level of LD_Ability for Temp_Unit) Greater than 0
  Actions
    Set VariableSet Temp_Unit = (Triggering unit)
    Unit - Remove LD_AbilityDrain from Temp_Unit
    Custom script: set udg_Temp_Unit = null
ArcaneDestruct
  Events
    Unit - A unit Dies
  Conditions
    ((Unit-type of (Dying unit)) Equal to Arcane Golem (Blood Elf)) and ((Current research level of R00K (techcode) for (Owner of (Dying unit))) Not equal to 0)
  Actions
    Set VariableSet TempLoc = (Position of (Dying unit))
    Set VariableSet Temp_Group_1 = (Units within 300.00 of TempLoc matching ((((Matching unit) belongs to an enemy of (Owner of (Dying unit)).) Equal to True) and (((Matching unit) is dead) Equal to False)).)
    Special Effect - Create a special effect at TempLoc using Local\ArcaneDestruct.mdx
    Special Effect - Destroy (Last created special effect)
    Unit Group - Pick every unit in Temp_Group_1 and do (Actions)
      Loop - Actions
        Unit - Cause (Triggering unit) to damage (Picked unit), dealing 275.00 damage of attack type Chaos and damage type Normal
    Custom script: call DestroyGroup(udg_Temp_Group_1)
    Custom script: call RemoveLocation (udg_TempLoc)
ManaSeeking
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (Unit-type of GDD_DamageSource) Equal to Mana-seeking Tower (Blood Elf)
  Actions
    Set VariableSet P_Manastart = (Mana of GDD_DamagedUnit)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (GDD_DamagedUnit is A Hero) Equal to True
      Then - Actions
        Unit - Set mana of GDD_DamagedUnit to ((Mana of GDD_DamagedUnit) - 8.00)
        Set VariableSet P_Manaend = (Mana of GDD_DamagedUnit)
        Set VariableSet P_Manatotal = (P_Manastart - P_Manaend)
        Unit - Cause GDD_DamageSource to damage GDD_DamagedUnit, dealing P_Manatotal damage of attack type Chaos and damage type Universal
      Else - Actions
        Unit - Set mana of GDD_DamagedUnit to ((Mana of GDD_DamagedUnit) - 16.00)
        Set VariableSet P_Manaend = (Mana of GDD_DamagedUnit)
        Set VariableSet P_Manatotal = (P_Manastart - P_Manaend)
        Unit - Cause GDD_DamageSource to damage GDD_DamagedUnit, dealing P_Manatotal damage of attack type Chaos and damage type Universal
DivineAegis
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (Level of Divine Aegis (Champion)(Blood Elf) for GDD_DamagedUnit) Not equal to 0
    (Current research level of R004 (techcode) for (Owner of GDD_DamagedUnit)) Not equal to 0
    (Percentage life of GDD_DamagedUnit) Greater than or equal to 80.00
  Actions
    Trigger - Turn off (This trigger)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        GDD_Damage Greater than or equal to 9.00
      Then - Actions
        Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + 7.00)
      Else - Actions
        Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + (GDD_Damage - 2.00))
    Trigger - Turn on (This trigger)
HolyArmour
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (Level of Holy Armour (Blood Elf) for GDD_DamagedUnit) Not equal to 0
    (Current research level of R04W (techcode) for (Owner of GDD_DamagedUnit)) Not equal to 0
  Actions
    Trigger - Turn off (This trigger)
    Set VariableSet P_Manastart = (Mana of GDD_DamagedUnit)
    Unit - Set mana of GDD_DamagedUnit to ((Mana of GDD_DamagedUnit) - (GDD_Damage x 0.25))
    Set VariableSet P_Manaend = (Mana of GDD_DamagedUnit)
    Set VariableSet P_Manatotal = (P_Manastart - P_Manaend)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        P_Manatotal Less than or equal to 5.00
      Then - Actions
      Else - Actions
        Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + (GDD_Damage x 0.25))
    Trigger - Turn on (This trigger)
SeveringStride
  Events
    Game - GDD_Event becomes Equal to 0
  Conditions
    (Level of Severing Stride (Hawkstrider Knight)(Blood Elf) for GDD_DamageSource) Not equal to 0
    (Current research level of R00W (techcode) for (Owner of GDD_DamageSource)) Not equal to 0
    (Percentage life of GDD_DamageSource) Greater than or equal to 80.00
  Actions
    Trigger - Turn off (This trigger)
    Set VariableSet TempLoc = (Position of GDD_DamagedUnit)
    Set VariableSet Temp_Group_1 = (Units within 125.00 of TempLoc matching ((((Matching unit) belongs to an enemy of (Owner of GDD_DamageSource).) Equal to True) and (((Matching unit) is dead) Equal to False)).)
    Unit Group - Remove GDD_DamagedUnit from Temp_Group_1.
    Unit Group - Pick every unit in Temp_Group_1 and do (Actions)
      Loop - Actions
        Unit - Cause (Triggering unit) to damage (Picked unit), dealing 10.00 damage of attack type Normal and damage type Normal
    Custom script: call DestroyGroup(udg_Temp_Group_1)
    Custom script: call RemoveLocation (udg_TempLoc)
    Trigger - Turn on (This trigger)
VenomSwipe
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Venom Swipe (Naga Champion)(Naga)
  Actions
    Set VariableSet TempPoint = (Position of (Triggering unit))
    Set VariableSet TempLoc = (TempPoint offset by 150.00 towards (Facing of (Triggering unit)) degrees.)
    Set VariableSet Temp_Group_1 = (Units within 200.00 of TempLoc matching ((((Matching unit) is Magic Immune) Equal to False) and ((((Matching unit) is dead) Equal to False) and (((Matching unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True))).)
    Unit - Create 1.SuperCasterDummy for (Triggering player) at TempPoint facing Default building facing degrees
    Set VariableSet DummyUnit = (Last created unit)
    Unit - Add Venom Swipe Cast Poison Dummy (Naga Champion)(Naga)(Dummy) to DummyUnit
    Unit - Set level of Venom Swipe Cast Poison Dummy (Naga Champion)(Naga)(Dummy) for DummyUnit to (Level of Venom Swipe (Naga Champion)(Naga) for (Triggering unit))
    Unit - Add a 1.00 second Generic expiration timer to DummyUnit
    Unit Group - Pick every unit in Temp_Group_1 and do (Actions)
      Loop - Actions
        Set VariableSet TempUnit = (Picked unit)
        Unit - Cause (Triggering unit) to damage TempUnit, dealing (60.00 x (Real((Level of Venom Swipe (Naga Champion)(Naga) for (Triggering unit))))) damage of attack type Chaos and damage type Universal
        Unit - Order DummyUnit to Undead Necromancer - Unholy Frenzy.TempUnit
    Unit - Add Venom Swipe Caster (Naga Champion)(Naga)(Dummy) to DummyUnit
    Unit - Order DummyUnit to Human Priest - Inner Fire.(Triggering unit)
    Unit Group - Add (Triggering unit) to VenomSwipeCaster
    Unit - Add Slow Poison (Naga Champion)(Naga)(Dummy) to (Triggering unit)
    Custom script: call DestroyGroup(udg_Temp_Group_1)
    Custom script: call RemoveLocation (udg_TempLoc)
    Custom script: call RemoveLocation (udg_TempPoint)
VenomSwipeOff
  Events
    Time - Every 1.00 seconds of game time
  Conditions
    (Number of units in VenomSwipeCaster) Not equal to 0
  Actions
    Unit Group - Pick every unit in VenomSwipeCaster and do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            ((Picked unit) has buff Unholy Frenzy (Naga)(Caster)) Equal to False
          Then - Actions
            Unit Group - Remove (Picked unit) from VenomSwipeCaster.
            Unit - Remove Slow Poison (Naga Champion)(Naga)(Dummy) from (Picked unit)
          Else - Actions
VenomSwipeDeath
  Events
    Unit - A unit Dies
  Conditions
    ((Dying unit) is in VenomSwipeCaster.) Equal to True
  Actions
    Unit Group - Remove (Dying unit) from VenomSwipeCaster.
    Unit - Remove Slow Poison (Naga Champion)(Naga)(Dummy) from (Dying unit)
RoyalGuardStart
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Royal Guard (Naga Champion)(Naga)
  Actions
    Set VariableSet SearingLight_Mod = (Level of Royal Guard (Naga Champion)(Naga) for (Triggering unit))
    Set VariableSet TempLoc = (Position of (Triggering unit))
    Unit - Create 1.DumbDummy for (Owner of (Casting unit)) at TempLoc facing (Facing of (Target unit of ability being cast)) degrees
    Unit - Add Royal Guard Dummy (Naga Champion)(Naga)(Dummy) to (Last created unit)
    Unit - Set level of Royal Guard Dummy (Naga Champion)(Naga)(Dummy) for (Last created unit) to (Level of Royal Guard (Naga Champion)(Naga) for (Triggering unit))
    Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
    Unit - Order (Last created unit) to Human Priest - Inner Fire.(Triggering unit)
    Custom script: call RemoveLocation (udg_TempLoc)
RoyalGuard1
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (GDD_DamagedUnit has buff Inner Fire (Naga)(1)) Equal to True
  Actions
    Unit - Cause GDD_DamagedUnit to damage GDD_DamageSource, dealing (GDD_Damage x 0.05) damage of attack type Chaos and damage type Universal
    Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + (GDD_Damage x 0.10))
RoyalGuard2
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (GDD_DamagedUnit has buff Inner Fire (Naga)(2)) Equal to True
  Actions
    Unit - Cause GDD_DamagedUnit to damage GDD_DamageSource, dealing (GDD_Damage x 0.10) damage of attack type Chaos and damage type Universal
    Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + (GDD_Damage x 0.20))
RoyalGuard3
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (GDD_DamagedUnit has buff Inner Fire (Naga)(3)) Equal to True
  Actions
    Unit - Cause GDD_DamagedUnit to damage GDD_DamageSource, dealing (GDD_Damage x 0.15) damage of attack type Chaos and damage type Universal
    Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + (GDD_Damage x 0.30))
UndyingWill
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (Level of Undying Will (Naga Champion)(Naga) for GDD_DamagedUnit) Greater than or equal to 1
    (GDD_DamagedUnit has buff Rejuvenation (Naga)(Debuff)) Equal to False
    (Percentage life of GDD_DamagedUnit) Less than or equal to 10
  Actions
    Set VariableSet TempPoint = (Position of (Triggering unit))
    Unit - Create 1.SuperCasterDummy for (Triggering player) at TempPoint facing Default building facing degrees
    Set VariableSet DummyUnit = (Last created unit)
    Unit - Add Undying Will Debuff (Naga Champion)(Naga)(Dummy) to DummyUnit
    Unit - Add Undying Will Heal Dummy (Naga Champion)(Naga)(Dummy) to DummyUnit
    Unit - Order DummyUnit to Human Priest - Inner Fire.(Triggering unit)
    Unit - Order DummyUnit to Night Elf Druid Of The Claw - Rejuvenation.(Triggering unit)
    Unit - Add a 1.00 second Generic expiration timer to DummyUnit
    Custom script: call DestroyGroup(udg_Temp_Group_1)
    Custom script: call RemoveLocation (udg_TempPoint)
TerrorOfTheTides
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Terror of the Tides (Naga Enchantress)(Naga)
  Actions
    Set VariableSet TempPoint = (Target point of ability being cast)
    Set VariableSet TempLoc = (TempPoint offset by 200.00 towards 0.00 degrees.)
    Unit - Create 1.Whirlwind (Chaos Orcs) for (Owner of (Triggering unit)) at TempLoc facing Default building facing degrees
    Unit - Add Tornado Spin (Naga Enchantress)(Naga)(Dummy) to (Last created unit)
    Unit - Add a 45.00 second Generic expiration timer to (Last created unit)
    Custom script: call RemoveLocation (udg_TempLoc)
    Set VariableSet TempLoc = (TempPoint offset by 200.00 towards 120.00 degrees.)
    Unit - Create 1.Whirlwind (Chaos Orcs) for (Owner of (Triggering unit)) at TempLoc facing Default building facing degrees
    Unit - Add a 45.00 second Generic expiration timer to (Last created unit)
    Custom script: call RemoveLocation (udg_TempLoc)
    Set VariableSet TempLoc = (TempPoint offset by 200.00 towards 240.00 degrees.)
    Unit - Create 1.Whirlwind (Chaos Orcs) for (Owner of (Triggering unit)) at TempLoc facing Default building facing degrees
    Unit - Add a 45.00 second Generic expiration timer to (Last created unit)
    Custom script: call RemoveLocation (udg_TempLoc)
    Custom script: call RemoveLocation (udg_TempPoint)
DrownTheWeak1
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (GDD_DamagedUnit has buff Curse (1)(Naga)) Equal to True
  Actions
    Set VariableSet P_Manastart = (Mana of GDD_DamagedUnit)
    Unit - Set mana of GDD_DamagedUnit to ((Mana of GDD_DamagedUnit) - GDD_Damage)
    Set VariableSet P_Manaend = (Mana of GDD_DamagedUnit)
    Set VariableSet P_Manatotal = (P_Manastart - P_Manaend)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        P_Manatotal Less than or equal to 5.00
      Then - Actions
        Unit - Cause GDD_DamageSource to damage GDD_DamagedUnit, dealing (GDD_Damage x 0.33) damage of attack type Chaos and damage type Universal
      Else - Actions
        Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + (GDD_Damage x 0.70))
DrownTheWeak2
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (GDD_DamagedUnit has buff Curse (2)(Naga)) Equal to True
  Actions
    Set VariableSet P_Manastart = (Mana of GDD_DamagedUnit)
    Unit - Set mana of GDD_DamagedUnit to ((Mana of GDD_DamagedUnit) - GDD_Damage)
    Set VariableSet P_Manaend = (Mana of GDD_DamagedUnit)
    Set VariableSet P_Manatotal = (P_Manastart - P_Manaend)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        P_Manatotal Less than or equal to 5.00
      Then - Actions
        Unit - Cause GDD_DamageSource to damage GDD_DamagedUnit, dealing (GDD_Damage x 0.66) damage of attack type Chaos and damage type Universal
      Else - Actions
        Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + (GDD_Damage x 0.60))
DrownTheWeak3
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (GDD_DamagedUnit has buff Curse (3)(Naga)) Equal to True
  Actions
    Set VariableSet P_Manastart = (Mana of GDD_DamagedUnit)
    Unit - Set mana of GDD_DamagedUnit to ((Mana of GDD_DamagedUnit) - GDD_Damage)
    Set VariableSet P_Manaend = (Mana of GDD_DamagedUnit)
    Set VariableSet P_Manatotal = (P_Manastart - P_Manaend)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        P_Manatotal Less than or equal to 5.00
      Then - Actions
        Unit - Cause GDD_DamageSource to damage GDD_DamagedUnit, dealing (GDD_Damage x 1.00) damage of attack type Chaos and damage type Universal
      Else - Actions
        Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + (GDD_Damage x 0.50))
Dimebolt
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Dime Bolt (Naga Enchantress)(Naga)
  Actions
    Set VariableSet Jab_Caster = (Triggering unit)
    Set VariableSet Jab_Mod = (Level of Dime Bolt (Naga Enchantress)(Naga) for (Triggering unit))
    Set VariableSet TempPoint = (Position of (Casting unit))
    Set VariableSet TempLoc = (Target point of ability being cast)
    Set VariableSet Temp_Group_1 = (Units within 200.00 of TempLoc matching ((((Matching unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True) and (((Matching unit) is dead) Equal to False)).)
    Special Effect - Create a special effect at TempLoc using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
    Special Effect - Destroy (Last created special effect)
    Special Effect - Create a special effect at TempLoc using Abilities\Weapons\Bolt\BoltImpact.mdl
    Special Effect - Set Scale of (Last created special effect) to 2.00
    Special Effect - Destroy (Last created special effect)
    Unit Group - Pick every unit in Temp_Group_1 and do (Actions)
      Loop - Actions
        Unit - Cause (Triggering unit) to damage (Picked unit), dealing (50.00 x (Real(Jab_Mod))) damage of attack type Chaos and damage type Universal
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Random integer number between 1 and 3) Less than or equal to Jab_Mod
      Then - Actions
        Unit - Create 1.DumbDummy for (Owner of (Casting unit)) at TempPoint facing (Facing of (Target unit of ability being cast)) degrees
        Unit - Add Dime Bolt Dummy (Naga Enchantress)(Naga)(Dummy)(1) to (Last created unit)
        Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
        Unit - Order (Last created unit) to Neutral Dark Ranger - Silence.TempLoc
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (Random integer number between 1 and 3) Less than or equal to 1
          Then - Actions
            Unit - Create 1.DumbDummy for (Owner of (Casting unit)) at TempPoint facing (Facing of (Target unit of ability being cast)) degrees
            Unit - Add Dime Bolt Dummy (Naga Enchantress)(Naga)(Dummy)(2) to (Last created unit)
            Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
            Unit - Order (Last created unit) to Neutral Dark Ranger - Silence.TempLoc
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (Random integer number between 1 and 3) Less than or equal to 1
              Then - Actions
                Unit - Create 1.DumbDummy for (Owner of (Casting unit)) at TempPoint facing (Facing of (Target unit of ability being cast)) degrees
                Unit - Add Dime Bolt Dummy (Naga Enchantress)(Naga)(Dummy)(3) to (Last created unit)
                Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
                Unit - Order (Last created unit) to Neutral Dark Ranger - Silence.TempLoc
              Else - Actions
          Else - Actions
      Else - Actions
    Custom script: call DestroyGroup(udg_Temp_Group_1)
    Custom script: call RemoveLocation (udg_TempLoc)
    Custom script: call RemoveLocation (udg_TempPoint)
DimeboltRapid
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Dime Bolt Dummy (Naga Enchantress)(Naga)(Dummy)(2)
  Actions
    Set VariableSet Jab_Caster = (Triggering unit)
    Set VariableSet Jab_Mod = 1
    Set VariableSet TempPoint = (Position of (Casting unit))
    Set VariableSet TempLoc = (Target point of ability being cast)
    Set VariableSet Temp_Group_1 = (Units within 200.00 of TempLoc matching ((((Matching unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True) and (((Matching unit) is dead) Equal to False)).)
    Special Effect - Create a special effect at TempLoc using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
    Special Effect - Destroy (Last created special effect)
    Special Effect - Create a special effect at TempLoc using Abilities\Weapons\Bolt\BoltImpact.mdl
    Special Effect - Set Scale of (Last created special effect) to 2.00
    Special Effect - Destroy (Last created special effect)
    Unit Group - Pick every unit in Temp_Group_1 and do (Actions)
      Loop - Actions
        Unit - Cause (Triggering unit) to damage (Picked unit), dealing (50.00 x (Real(Jab_Mod))) damage of attack type Chaos and damage type Universal
    Custom script: call DestroyGroup(udg_Temp_Group_1)
    Custom script: call RemoveLocation (udg_TempLoc)
    Custom script: call RemoveLocation (udg_TempPoint)
MendingRapids
  Events
    Unit - A unit Spawns a summoned unit
  Conditions
    (Unit-type of (Summoned unit)) Equal to Mending Rapids (Naga)
  Actions
    Set VariableSet TempPoint = (Position of (Summoned unit))
    Special Effect - Create a special effect at TempPoint using Local\WaterBlast.mdx
    Special Effect - Set Scale of (Last created special effect) to 1.50
    Special Effect - Destroy (Last created special effect)
    Unit - Set level of Mending Rapids Dummy (Naga Enchantress)(Naga) for (Summoned unit) to (Level of Mending Rapids (Naga Enchantress)(Naga) for (Summoning unit))
    Custom script: call RemoveLocation (udg_TempPoint)
MendingRapidsStop
  Events
    Unit - A unit Dies
  Conditions
    (Unit-type of (Triggering unit)) Equal to Mending Rapids (Naga)
  Actions
    Set VariableSet TempPoint = (Position of (Triggering unit))
    Set VariableSet Temp_Group_1 = (Units within 600.00 of TempLoc matching ((((Matching unit) belongs to an enemy of (Owner of (Dying unit)).) Equal to False) and (((Matching unit) is dead) Equal to False)).)
    Special Effect - Create a special effect at TempPoint using Local\WaterBlast.mdx
    Unit Group - Pick every unit in Temp_Group_1 and do (Actions)
      Loop - Actions
        Unit - Remove Healing Ward Aura (Naga) buff from (Picked unit)
    Special Effect - Set Scale of (Last created special effect) to 1.50
    Special Effect - Destroy (Last created special effect)
    Custom script: call RemoveLocation (udg_TempPoint)
MindBomb
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    ((Triggering unit) has buff Slow (Naga)) Equal to True
  Actions
    Set VariableSet TempLoc = (Position of (Triggering unit))
    Set VariableSet Temp_Group_1 = (Units within 400.00 of TempLoc matching ((((Matching unit) is Magic Immune) Equal to False) and (((Matching unit) is dead) Equal to False)).)
    Special Effect - Create a special effect at TempLoc using Units\NightElf\Wisp\WispExplode.mdl
    Special Effect - Destroy (Last created special effect)
    Unit - Cause (Triggering unit) to damage (Triggering unit), dealing 100.00 damage of attack type Chaos and damage type Universal
    Unit Group - Pick every unit in Temp_Group_1 and do (Actions)
      Loop - Actions
        Unit - Cause (Triggering unit) to damage (Picked unit), dealing 200.00 damage of attack type Chaos and damage type Universal
    Unit - Remove Slow (Naga) buff from (Triggering unit)
    Custom script: call DestroyGroup(udg_Temp_Group_1)
    Custom script: call RemoveLocation (udg_TempLoc)
SoulSiphon
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Soul Siphon (Illidari Demon Hunter)(Naga)
  Actions
    Set VariableSet CSmCaster = (Triggering unit)
    Set VariableSet Jab_Caster = (Target unit of ability being cast)
    Unit - Set mana of CSmCaster to ((Mana of CSmCaster) - 1.00)
    Unit - Set mana of Jab_Caster to ((Mana of Jab_Caster) + 1.00)
    Set VariableSet P_Manastart = (Mana of Jab_Caster)
    Unit - Set mana of Jab_Caster to ((Mana of Jab_Caster) - (50.00 x (Real((Level of Soul Siphon (Illidari Demon Hunter)(Naga) for (Triggering unit))))))
    Set VariableSet P_Manaend = (Mana of Jab_Caster)
    Set VariableSet P_Manatotal = (P_Manastart - P_Manaend)
    Floating Text - Create floating text that reads (- + (String((Integer(P_Manatotal))))) above Jab_Caster with Z offset 0, using font size 10, color (0.00%, 0.00%, 70.00%), and 0% transparency
    Floating Text - Change (Last created floating text): Disable permanence
    Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
    Floating Text - Change the fading age of (Last created floating text) to 2.00 seconds
    Floating Text - Change the lifespan of (Last created floating text) to 4.00 seconds
    Custom script: call RemoveLocation (udg_TempLoc)
    Unit - Set life of CSmCaster to ((Life of CSmCaster) + (2.00 x P_Manatotal))
    Floating Text - Create floating text that reads (+ + (String((2 x (Integer(P_Manatotal)))))) above CSmCaster with Z offset 0, using font size 10, color (0.00%, 100.00%, 0.00%), and 0% transparency
    Floating Text - Change (Last created floating text): Disable permanence
    Floating Text - Set the velocity of (Last created floating text) to 32.00 towards 90.00 degrees
    Floating Text - Change the fading age of (Last created floating text) to 2.00 seconds
    Floating Text - Change the lifespan of (Last created floating text) to 4.00 seconds
SpellNegation
  Events
    Unit - A unit Learns a skill
  Conditions
    (Learned Hero Skill) Equal to Spell Negation (Illidari Demon Hunter)(Naga)
  Actions
    Unit - Add Spell Negation Reduction (Dummy)(Illidari Demon Hunter)(Naga) to (Triggering unit)
    Unit - Set level of Spell Negation Reduction (Dummy)(Illidari Demon Hunter)(Naga) for (Triggering unit) to (Level of Spell Negation (Illidari Demon Hunter)(Naga) for (Triggering unit))
FeedTheHunger
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (Unit-type of GDD_DamageSource) Equal to Highborne Sorceror (Naga)(Feed the Hunger)
  Actions
    Unit - Set mana of GDD_DamageSource to ((Mana of GDD_DamageSource) + (GDD_Damage x 0.20))
    Set VariableSet P_Manastart = (Mana of GDD_DamagedUnit)
    Unit - Set mana of GDD_DamagedUnit to ((Mana of GDD_DamagedUnit) - 15.00)
    Set VariableSet P_Manaend = (Mana of GDD_DamagedUnit)
    Set VariableSet P_Manatotal = (P_Manastart - P_Manaend)
    Unit - Cause GDD_DamageSource to damage GDD_DamagedUnit, dealing P_Manatotal damage of attack type Chaos and damage type Universal
Ethereality
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Ethereality (Highborne Sorceror)(Naga)
  Actions
    Set VariableSet TempLoc = (Target point of ability being cast)
    Set VariableSet TempPoint = (Position of (Triggering unit))
    Set VariableSet Temp_Group_1 = (Units within (125.00 + (75.00 x (Real((Level of Ethereality (Highborne Sorceror)(Naga) for (Triggering unit)))))) of TempLoc matching ((((Matching unit) is Magic Immune) Equal to False) and (((Matching unit) is dead) Equal to False)).)
    Unit - Create 1.SuperCasterDummy for (Triggering player) at TempPoint facing Default building facing degrees
    Set VariableSet DummyUnit = (Last created unit)
    Unit - Add Ethereality Banish (Highborne Sorceror)(Naga)(Dummy) to DummyUnit
    Unit - Set level of Ethereality Banish (Highborne Sorceror)(Naga)(Dummy) for DummyUnit to (Level of Ethereality (Highborne Sorceror)(Naga) for (Triggering unit))
    Unit - Add a 1.00 second Generic expiration timer to DummyUnit
    Unit Group - Pick every unit in Temp_Group_1 and do (Actions)
      Loop - Actions
        Set VariableSet TempUnit = (Picked unit)
        Unit - Order DummyUnit to Human Blood Mage - Banish.TempUnit
    Custom script: call DestroyGroup(udg_Temp_Group_1)
    Custom script: call RemoveLocation (udg_TempLoc)
    Custom script: call RemoveLocation (udg_TempPoint)
IcicleLance
  Events
    Game - GDD_Event becomes Equal to 0
  Conditions
    (GDD_DamagedUnit has buff Mind Rot (Blood Elf Dummy)) Equal to True
    Or - Any (Conditions) are true
      Conditions
        (Unit-type of GDD_DamageSource) Equal to Highborne Sorceror (Naga)
        (Unit-type of GDD_DamageSource) Equal to Highborne Sorceror (Naga)(Feed the Hunger)
  Actions
    Set VariableSet TempLoc = (Position of GDD_DamageSource)
    Unit - Remove Mind Rot (Blood Elf Dummy) buff from GDD_DamagedUnit
    Unit - Create 1.DumbDummy for (Owner of GDD_DamageSource) at TempLoc facing (Facing of GDD_DamageSource) degrees
    Set VariableSet Temp_Unit = (Last created unit)
    Unit - Add Icicle Lance Dummy (Highborne Sorceror)(Naga)(Dummy) to Temp_Unit
    Unit - Set level of Icicle Lance Dummy (Highborne Sorceror)(Naga)(Dummy) for Temp_Unit to (Level of Icicle Lance (Highborne Sorceror)(Naga) for GDD_DamageSource)
    Unit - Add a 0.50 second Generic expiration timer to Temp_Unit
    Unit - Order Temp_Unit to Undead Necromancer - Cripple.GDD_DamagedUnit
    Custom script: call RemoveLocation (udg_TempLoc)
CoralReefStart
  Events
    Unit - A unit Begins construction
  Conditions
    (Unit-type of (Constructing structure)) Equal to Coral Bed (Naga)
  Actions
    Unit - For (Constructing structure), Ability Coral Reef (Coral Bed)(Naga), Disable ability: True, Hide UI: True
CoralReefEnd
  Events
    Unit - A unit Finishes construction
  Conditions
    (Unit-type of (Constructed structure)) Equal to Coral Bed (Naga)
  Actions
    Unit - For (Constructed structure), Ability Coral Reef (Coral Bed)(Naga), Disable ability: False, Hide UI: False
PetrifyDamage
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (GDD_DamagedUnit has buff Stunned (Pause)(Petrify)(Naga)) Equal to True
  Actions
    Trigger - Turn off (This trigger)
    Unit - Cause GDD_DamageSource to damage GDD_DamagedUnit, dealing (GDD_Damage x 0.50) damage of attack type Chaos and damage type Universal
    Trigger - Turn on (This trigger)
Shatter
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (Level of Shatter (Naga) for GDD_DamageSource) Not equal to 0
    (Current research level of R05S (techcode) for (Owner of GDD_DamageSource)) Not equal to 0
    (GDD_DamagedUnit is Stunned) Equal to True
  Actions
    Trigger - Turn off (This trigger)
    Unit - Cause GDD_DamageSource to damage GDD_DamagedUnit, dealing (GDD_Damage x 0.50) damage of attack type Chaos and damage type Universal
    Trigger - Turn on (This trigger)
FlunctuatingDestiny
  Events
    Game - GDD_Event becomes Equal to 1.00
  Conditions
    (GDD_DamagedUnit has buff Unholy Frenzy (Demon)) Equal to True
  Actions
    Unit - Set life of GDD_DamagedUnit to ((Life of GDD_DamagedUnit) + (GDD_Damage / 2.00))
    Unit - Cause GDD_DamagedUnit to damage GDD_DamageSource, dealing (GDD_Damage x 0.25) damage of attack type Chaos and damage type Universal
PentagramAuraOn
  Events
    Game - UnitIndexEvent becomes Equal to 1.00
  Conditions
    (Unit-type of UDexUnits[UDex]) Equal to Adrammelech Toxophilite (Demon)
  Actions
    Unit Group - Add UDexUnits[UDex] to AdraToxoUnitGroup
please use UnitEvent to make this work
PentagramAuraOff
  Events
    Game - UnitIndexEvent becomes Equal to 2.00
  Conditions
    (Unit-type of UDexUnits[UDex]) Equal to Adrammelech Toxophilite (Demon)
  Actions
    Unit Group - Remove UDexUnits[UDex] from AdraToxoUnitGroup.
PentagramAuraPeriodic
  Events
    Time - Every 1.00 seconds of game time
  Conditions
    (Number of units in AdraToxoUnitGroup) Not equal to 0
  Actions
    Unit Group - Pick every unit in AdraToxoUnitGroup and do (Actions)
      Loop - Actions
        Set VariableSet TempUnit = (Picked unit)
        Set VariableSet TempLoc = (Position of TempUnit)
        Set VariableSet TempGroup = (Units within 900.00 of TempLoc.)
        Unit Group - Pick every unit in TempGroup and do (Actions)
          Loop - Actions
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (Level of Pentagram Aura (Adrammelech Toxophilite)(Demon) for TempUnit) Equal to 1
                ((Picked unit) has buff Devotion Aura (Demon)) Equal to False
              Then - Actions
                Unit - Add Pentagram Aura Dummy (Adremmalech Toxophilite)(Demon)(Dummy) to (Picked unit)
              Else - Actions
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (Level of Pentagram Aura (Adrammelech Toxophilite)(Demon) for TempUnit) Equal to 2
                ((Picked unit) has buff Devotion Aura (Demon)) Equal to False
              Then - Actions
                Unit - Set level of Pentagram Aura Dummy (Adremmalech Toxophilite)(Demon)(Dummy) for (Picked unit) to 2
              Else - Actions
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (Level of Pentagram Aura (Adrammelech Toxophilite)(Demon) for TempUnit) Equal to 3
                ((Picked unit) has buff Devotion Aura (Demon)) Equal to False
              Then - Actions
                Unit - Set level of Pentagram Aura Dummy (Adremmalech Toxophilite)(Demon)(Dummy) for (Picked unit) to 3
              Else - Actions
            Unit Group - Add (Picked unit) to PentaAuraGroup
        Custom script: call RemoveLocation(udg_TempLoc)
        Custom script: call DestroyGroup(udg_TempGroup)
PentagramAuraDelete
  Events
    Time - Every 1.00 seconds of game time
  Conditions
    (Number of units in PentaAuraGroup) Not equal to 0
  Actions
    Unit Group - Pick every unit in PentaAuraGroup and do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            ((Picked unit) has buff Devotion Aura (Demon)) Equal to False
          Then - Actions
            Unit - Remove Pentagram Aura Dummy (Adremmalech Toxophilite)(Demon)(Dummy) from (Picked unit)
            Unit Group - Remove (Picked unit) from PentaAuraGroup.
          Else - Actions
DevilishPowerAdd
  Events
    Unit - A unit Starts the effect of an ability
  Conditions
    (Ability being cast) Equal to Devilish Power (Adrammelech Toxophilite)(Demon)
  Actions
    Unit Group - Add (Target unit of ability being cast) to DevilishPowerGroup
    Unit - Remove Devilish Power Dummy 1 (Adrammelech Toxophilite)(Demon)(Dummy) from (Target unit of ability being cast)
    Unit - Remove Devilish Power Dummy 2 (Adrammelech Toxophilite)(Demon)(Dummy) from (Target unit of ability being cast)
    Unit - Remove Devilish Power Dummy 3 (Adrammelech Toxophilite)(Demon)(Dummy) from (Target unit of ability being cast)
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Level of Devilish Power (Adrammelech Toxophilite)(Demon) for (Triggering unit)) Equal to 1
      Then - Actions
        Unit - Add Devilish Power Dummy 1 (Adrammelech Toxophilite)(Demon)(Dummy) to (Target unit of ability being cast)
      Else - Actions
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Level of Devilish Power (Adrammelech Toxophilite)(Demon) for (Triggering unit)) Equal to 2
      Then - Actions
        Unit - Add Devilish Power Dummy 2 (Adrammelech Toxophilite)(Demon)(Dummy) to (Target unit of ability being cast)
      Else - Actions
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Level of Devilish Power (Adrammelech Toxophilite)(Demon) for (Triggering unit)) Equal to 3
      Then - Actions
        Unit - Add Devilish Power Dummy 3 (Adrammelech Toxophilite)(Demon)(Dummy) to (Target unit of ability being cast)
      Else - Actions
DevilishPowerPeriodic
  Events
    Time - Every 1.00 seconds of game time
  Conditions
    (Number of units in DevilishPowerGroup) Not equal to 0
  Actions
    Unit Group - Pick every unit in DevilishPowerGroup and do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            ((Picked unit) has buff Unholy Frenzy (Demon)) Equal to False
          Then - Actions
            Unit Group - Remove (Picked unit) from DevilishPowerGroup.
            Unit - Remove Devilish Power Dummy 1 (Adrammelech Toxophilite)(Demon)(Dummy) from (Picked unit)
            Unit - Remove Devilish Power Dummy 2 (Adrammelech Toxophilite)(Demon)(Dummy) from (Picked unit)
            Unit - Remove Devilish Power Dummy 3 (Adrammelech Toxophilite)(Demon)(Dummy) from (Picked unit)
          Else - Actions
DevilishPowerKO
  Events
    Unit - A unit Dies
  Conditions
    ((Dying unit) is in DevilishPowerGroup.) Equal to True