1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  5. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  6. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  7. The results are out! Check them out.
    Dismiss Notice
  8. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  9. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  10. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Trigger Viewer

Triggered Incinerate v1.2.w3x
Variables
The Spell
Triggered Incinerate by AGD
The Spell
Incinerate SpellsList
Triggered Incinerate
Debug
Test Map Debug
Variable Creator
TI Variable Creator
-
Required System
Damage Engine by Bribe
Requirement
Unit Indexer
---------------------------
Damage Engine Config
Damage Engine
-
MapSetup
Init
Enter map-specific custom script code below. This text will be included in the map script after variables are declared and before any trigger code.

		
Name Type Is Array Initial Value
AfterDamageEvent real No
ClearDamageEvent trigger 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
DamageEventOverride boolean No
DamageEventPrevAmt real No
DamageEventSource unit No
DamageEventsWasted integer No
DamageEventTarget unit No
DamageEventTrigger trigger No
DamageEventType integer No
DamageModifierEvent real No
DamageTypeBlocked integer No
DamageTypeCriticalStrike integer No
DamageTypeExplosive integer No
DamageTypeHeal integer No
DamageTypeReduced integer No
DmgEvBracers itemcode No
DmgEvRecursionN integer No
DmgEvRunning boolean No
DmgEvStarted boolean No
DmgEvTimer timer No
DmgEvTrig trigger No
GDD__LeftMapGroup group No
HideDamageFrom boolean Yes
IsDamageSpell boolean No
LastDamageHP real No
LastDmgPrevAmount real Yes
LastDmgPrevType integer Yes
LastDmgSource unit Yes
LastDmgTarget unit Yes
LastDmgValue real Yes
LastDmgWasSpell boolean Yes
NextDamageOverride boolean No
NextDamageType integer No
SourceName string No
SpellDamageAbility abilcode No
TargetName string No
TempInt integer No
TempKey integer No
TI_Allies boolean No
TI_AllowSpellAsTrigger boolean No
TI_AT attacktype Yes
TI_AttachPoint string Yes
TI_AttackType attacktype No
TI_DamageCapBase real Yes
TI_DamageCapPerLevel real Yes
TI_DamageStackBase real No
TI_DamageStackPerLevel real No
TI_DamageType damagetype No
TI_DCapBase real No
TI_DCapPerLevel real No
TI_DPABase real Yes
TI_DPAPerLevel real Yes
TI_DT damagetype Yes
TI_DummyID integer Yes
TI_DurationBase real Yes
TI_DurationPerLevel real Yes
TI_DurBase real No
TI_DurPerLevel real No
TI_EffectAttachment string No
TI_EffectModel1 string No
TI_EffectModel2 string No
TI_EXAOEBase real No
TI_EXAOEPerLevel real No
TI_ExplodeAOEBase real Yes
TI_ExplodeAOEPerLevel real Yes
TI_ExplodeSmallDAOEBase real Yes
TI_ExplodeSmallDAOEPerLev real Yes
TI_ExplodeSmallDFactorBase real Yes
TI_ExplodeSmallDFactorPerLev real Yes
TI_EXSmallAOEBase real No
TI_EXSmallAOEPerLevel real No
TI_EXSmallDamageFactorBase real No
TI_EXSmallDamageFactorPerLevel real No
TI_Hash hashtable No
TI_Illusions boolean No
TI_IsUnitAlly boolean Yes
TI_IsUnitIllusion boolean Yes
TI_IsUnitMagicImmune boolean Yes
TI_IsUnitMechanical boolean Yes
TI_IsUnitStructure boolean Yes
TI_MagicImmune boolean No
TI_Mechanicals boolean No
TI_SFXModel1 string Yes
TI_SFXModel2 string Yes
TI_Spell abilcode No
TI_SpellAsTrigger boolean Yes
TI_SpellID abilcode Yes
TI_SpellIndex integer No
TI_Structures boolean No
TI_TempGroup group No
TI_Trig trigger No
UDex integer No
UDexGen integer No
UDexNext integer Yes
UDexPrev integer Yes
UDexRecycle integer No
UDexUnits unit Yes
UDexWasted integer No
UnitDamageRegistered boolean Yes
UnitIndexerEnabled boolean No
UnitIndexEvent real No
UnitIndexLock integer Yes
Incinerate SpellsList
  Events
  Conditions
  Actions
    -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
    -------- |||||||||||||||||||||||||||||||||||||||| INCINERATE SPELLS LIST |||||||||||||||||||||||||||||||||||||||| --------
    -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
    -------- --------
    -------- If you want to add a slot for an incinerate spell, copy one of these --------
    -------- spell blocks and paste it next to the last block. Then you can freely --------
    -------- configure the stats of the spell. --------
    -------- --------
    -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
    -------- ||||| Incinerate Spell 1 ||||| --------
    -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
    -------- --------
    -------- [ Activation spell ] --------
    Set TI_Spell = Incinerate
    -------- [ Determines if spells can trigger incinerate ] --------
    Set TI_AllowSpellAsTrigger = False
    -------- [ Damage increase per attack ] --------
    Set TI_DamageStackBase = 8.00
    Set TI_DamageStackPerLevel = 2.00
    -------- [ Duration of the stack damage ] --------
    Set TI_DurBase = 8.00
    Set TI_DurPerLevel = 0.00
    -------- [ Limit of the damage stacking (Value of 0 means no stacking limit) ] --------
    Set TI_DCapBase = 500.00
    Set TI_DCapPerLevel = 0.00
    -------- [ Full damage area/radius of the explosion ] --------
    Set TI_EXAOEBase = 150.00
    Set TI_EXAOEPerLevel = 0.00
    -------- [ Small damage area/radius of the explosion ] --------
    Set TI_EXSmallAOEBase = 250.00
    Set TI_EXSmallAOEPerLevel = 0.00
    -------- [ Explosion's small damage factor ] --------
    Set TI_EXSmallDamageFactorBase = 0.60
    Set TI_EXSmallDamageFactorPerLevel = 0.00
    -------- [ Attack type of the spell ] --------
    Set TI_AttackType = Hero
    -------- [ Damage type of the spell ] --------
    Set TI_DamageType = Magic
    -------- [ Damage stacking SFX model ] --------
    Set TI_EffectModel1 = Abilities\Spells\Other\Incinerate\IncinerateBuff.mdl
    -------- [ Explosion SFX model ] --------
    Set TI_EffectModel2 = Abilities\Spells\Other\Incinerate\FireLordDeathExplode.mdl
    -------- [ Damage stacking SFX attachment point ] --------
    Set TI_EffectAttachment = chest
    -------- [ The following determines the type of units allowed as the spell's target ] --------
    Set TI_Structures = False
    Set TI_Mechanicals = False
    Set TI_MagicImmune = False
    Set TI_Allies = True
    Set TI_Illusions = True
    -------- [ It's possible that this script was compiled first before TI_InitSpellIndex in which case normal function call won't work. ] --------
    -------- [ Therefore we use ExecuteFunc. ] --------
    Custom script: call ExecuteFunc( "TI_InitSpellIndex" )
    -------- --------
    -------- --------
    -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
    -------- ||||| Incinerate Spell 2 ||||| --------
    -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
    -------- --------
    -------- [ Activation spell ] --------
    Set TI_Spell = Fury Swipe
    -------- [ Determines if spells can trigger incinerate ] --------
    Set TI_AllowSpellAsTrigger = False
    -------- [ Damage increase per attack ] --------
    Set TI_DamageStackBase = 10.00
    Set TI_DamageStackPerLevel = 5.00
    -------- [ Duration of the stack damage ] --------
    Set TI_DurBase = 8.00
    Set TI_DurPerLevel = 0.00
    -------- [ Limit of the damage stacking (Value of 0 means no stacking limit) ] --------
    Set TI_DCapBase = 0.00
    Set TI_DCapPerLevel = 0.00
    -------- [ Full damage area/radius of the explosion ] --------
    Set TI_EXAOEBase = 0.00
    Set TI_EXAOEPerLevel = 0.00
    -------- [ Small damage area/radius of the explosion ] --------
    Set TI_EXSmallAOEBase = 0.00
    Set TI_EXSmallAOEPerLevel = 0.00
    -------- [ Explosion's small damage factor ] --------
    Set TI_EXSmallDamageFactorBase = 0.00
    Set TI_EXSmallDamageFactorPerLevel = 0.00
    -------- [ Attack type of the spell ] --------
    Set TI_AttackType = Hero
    -------- [ Damage type of the spell ] --------
    Set TI_DamageType = Normal
    -------- [ Damage stacking SFX model ] --------
    Set TI_EffectModel1 = Abilities\Spells\NightElf\BattleRoar\RoarTarget.mdl
    -------- [ Explosion SFX model ] --------
    Set TI_EffectModel2 = Objects\Spawnmodels\Undead\UndeadBlood\UndeadBloodNecromancer.mdl
    -------- [ Damage stacking SFX attachment point ] --------
    Set TI_EffectAttachment = overhead
    -------- [ The following determines the type of units allowed as the spell's target ] --------
    Set TI_Structures = False
    Set TI_Mechanicals = False
    Set TI_MagicImmune = True
    Set TI_Allies = True
    Set TI_Illusions = True
    -------- [ It's possible that this script was compiled first before TI_InitSpellIndex in which case normal function call won't work. ] --------
    -------- [ Therefore we use ExecuteFunc. ] --------
    Custom script: call ExecuteFunc( "TI_InitSpellIndex" )
    -------- --------
    -------- --------






timerkey Child keys

0 - Index
1 - Target
//TESH.scrollpos=284
//TESH.alwaysfold=0
///////////////////////////////////////////////////////////////////////////////////////////////////////
//===================================================================================================//
//============================= ***    ****   ***   ****   *   *  **** ==============================//
//============================= *  *   *     *   *  *   *  ** **  *    ==============================//
//============================= ***    ***   *****  *   *  * * *  ***  ==============================//
//============================= *  *   *     *   *  *   *  *   *  *    ==============================//
//============================= *   *  ****  *   *  ****   *   *  **** ==============================//
//===================================================================================================//
///////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                   //
// *****************************                                                                     //
// * Triggered Incinerate v1.2 *                                                                     //
// *          by: AGD          *                                                                     //
// *****************************                                                                     //
//                                                                                                   //
// Credits:                                                                                          //
// - Bribe ( Damage Engine )                                                                         //
//                                                                                                   //
//                                                                                                   //
// How to Import:                                                                                    //
// - Copy the dummy model in the import manager                                                      //
// - Copy the dummy unit                                                                             //
// - Copy the custom abilities                                                                       //
// - Copy the "Triggered Incinerate by AGD" trigger category                                         //
//                                                                                                   //
// But first, check "automatically create unknown variables while pasting trigger data" so that the  //
// "TI Variable Creator" will create the necessary variables in your map.                            //
//                                                                                                   //
//                                                                                                   //
// Spell Summary:                                                                                    //
//                                                                                                   //
// The spell's effect is passive. It activates everytime the unit deals damage to its target. This   //
// spell causes the unit to deal increasing damage (additionally) per attack. The damage stacking    //
// has a duration after which if the target takes no damage from a unit with incinerate spell, it    //
// will be reset back to zero. Upon the target unit's death, it will explode and deal damage equal   //
// to the damage stacked to a certain AOE.                                                           //
//                                                                                                   //
//                                                                                                   //
// Spell Info (Please Read):                                                                         //
//                                                                                                   //
// For those who don't know yet, the Incinerate spell of Fire Lord which was made by Blizzard is     //
// actually buggy if you're not using the original spell ( i.e. if you're using a custom ability     //
// based on that spell ). In this case, even if you change the stats of the custom spell, the stats  //
// of the original spell will persist and it's almost impossible or atleast difficult to make        //
// many incinerate spells with different stats and sometimes you will be forced to use triggers to   //
// do this.                                                                                          //
//                                                                                                   //
// For this reason I made this spell hoping that this will help you with your difficulties regarding //
// the buggy Incinerate. In this spell, you can make as many incinerate spells as you like, all with //
// different stats and spellIDs. The spell's effects is also not limited by the unit's weapon type   //
// which, unlike Blizzard's Incinerate, will only work with missile attacks. And lastly, one         //
// POSSIBLE advantage of this sytem is that it works together with other buff placers and orb        //
// effects.                                                                                          //
//                                                                                                   //
// Please share your feedback and suggestions about this spell at Hive Workshop or you can PM AGD    //
// at Hive. Please also report bugs and glitches if you found some.                                  //
//                                                                                                   //
//                                                                                                   //
// Note: If you use this resource in your map, please don't forget to give credits to AGD. And if    //
//       you're having problem regarding how to import or in configuring the spell, you can PM him   //
//       or post your comment at Hive Workshop.                                                      //
//                                                                                                   //
//                                                                                                   //
///////////////////////////////////////////////////////////////////////////////////////////////////////
//===================================================================================================//
//===================================================================================================//
//===================================================================================================//
///////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////
// This function indexes the spell's stats listed //
// in the Incinerate spells list one by one       //
////////////////////////////////////////////////////
function TI_InitSpellIndex takes nothing returns nothing

    local integer i = udg_TI_SpellIndex + 1

    set udg_TI_SpellID[i] = udg_TI_Spell
    set udg_TI_SpellAsTrigger[i] = udg_TI_AllowSpellAsTrigger
    set udg_TI_DPABase[i] = udg_TI_DamageStackBase
    set udg_TI_DPAPerLevel[i] = udg_TI_DamageStackPerLevel
    set udg_TI_DurationBase[i] = udg_TI_DurBase
    set udg_TI_DurationPerLevel[i] = udg_TI_DurPerLevel
    set udg_TI_DamageCapBase[i] = udg_TI_DCapBase
    set udg_TI_DamageCapPerLevel[i] = udg_TI_DCapPerLevel
    set udg_TI_ExplodeAOEBase[i] = udg_TI_EXAOEBase
    set udg_TI_ExplodeAOEPerLevel[i] = udg_TI_EXAOEPerLevel
    set udg_TI_ExplodeSmallDAOEBase[i] = udg_TI_EXSmallAOEBase
    set udg_TI_ExplodeSmallDAOEPerLev[i] = udg_TI_EXSmallAOEPerLevel
    set udg_TI_ExplodeSmallDFactorBase[i] = udg_TI_EXSmallDamageFactorBase
    set udg_TI_ExplodeSmallDFactorPerLev[i] = udg_TI_EXSmallDamageFactorPerLevel
    set udg_TI_AT[i] = udg_TI_AttackType
    set udg_TI_DT[i] = udg_TI_DamageType
    set udg_TI_SFXModel1[i] = udg_TI_EffectModel1
    set udg_TI_SFXModel2[i] = udg_TI_EffectModel2
    set udg_TI_AttachPoint[i] = udg_TI_EffectAttachment
    set udg_TI_IsUnitStructure[i] = udg_TI_Structures
    set udg_TI_IsUnitMechanical[i] = udg_TI_Mechanicals
    set udg_TI_IsUnitMagicImmune[i] = udg_TI_MagicImmune
    set udg_TI_IsUnitAlly[i] = udg_TI_Allies
    set udg_TI_IsUnitIllusion[i] = udg_TI_Illusions

    set udg_TI_SpellIndex = i

endfunction


/////////////////////////////////////////////////////
// This function filters unwanted units from being //
// affected by the spell                           //
/////////////////////////////////////////////////////
function TI_TargetFilter takes unit target, player p, integer i returns boolean
    return ( ( not IsUnitType( target, UNIT_TYPE_STRUCTURE ) ) or udg_TI_IsUnitStructure[i] ) and ( ( not IsUnitType( target, UNIT_TYPE_MECHANICAL ) ) or udg_TI_IsUnitMechanical[i] ) and ( ( not IsUnitType( target, UNIT_TYPE_MAGIC_IMMUNE ) ) or udg_TI_IsUnitMagicImmune[i] ) and ( IsUnitEnemy( target, p ) or udg_TI_IsUnitAlly[i] ) and ( ( not IsUnitIllusion( target ) ) or udg_TI_IsUnitIllusion[i] )
endfunction


/////////////////////////////////////////////////////
// This function debuffs the target unit when not  //
// damaged for a certain duration                  //
/////////////////////////////////////////////////////
function TI_Debuff takes nothing returns nothing

    local timer t           = GetExpiredTimer()
    local integer timerkey  = GetHandleId( t )
    local integer i         = LoadInteger( udg_TI_Hash, timerkey, 0 )
    local unit u            = LoadUnitHandle( udg_TI_Hash, timerkey, 1 )
    local integer key       = GetHandleId( u )
    local string I          = I2S( i )

    call DestroyEffect( LoadEffectHandle( udg_TI_Hash, key, StringHash( "SFX" + I ) ) )
    call DestroyTimer( t )
    call SaveBoolean( udg_TI_Hash, key, i, false )
    call SaveReal( udg_TI_Hash, key, StringHash( "Damage" + I ), 0 )
    call FlushChildHashtable( udg_TI_Hash, timerkey )

    set t = null
    set u = null
    set I = null

endfunction


//////////////////////////////////////////////////////
// This function triggers the dead unit's explosion //
//////////////////////////////////////////////////////
function TI_Incinerate takes nothing returns boolean

    local unit dying        = GetTriggerUnit()
    local integer key       = GetHandleId( dying )
    local real x            = GetUnitX( dying )
    local real y            = GetUnitY( dying )
    local integer i         = 0
    local unit target
    local player p
    local real dx
    local real dy
    local real damage
    local real smalldfactor
    local unit buffplacer
    local string I

    loop

        set i = i + 1
        set I = I2S( i )

        if LoadBoolean( udg_TI_Hash, key, i ) then

            set damage = LoadReal( udg_TI_Hash, key, StringHash( "Damage" + I ) )
            set smalldfactor = LoadReal( udg_TI_Hash, key, StringHash( "SmallDFactor" + I ) )
            set buffplacer = LoadUnitHandle( udg_TI_Hash, key, StringHash( "BuffPlacer" + I ) )
            set p = GetOwningPlayer( buffplacer )
            call SaveReal( udg_TI_Hash, key, StringHash( "Damage" + I ), 0 )
            call DestroyEffect( LoadEffectHandle( udg_TI_Hash, key, StringHash( "SFX" + I ) ) )
            call DestroyEffect( AddSpecialEffect( udg_TI_SFXModel2[i], x, y ) )
            call GroupEnumUnitsInRange( udg_TI_TempGroup, x, y, LoadReal( udg_TI_Hash, key, StringHash( "SmallDAOE" + I ) ), null )

            loop

                set target = FirstOfGroup( udg_TI_TempGroup )
                exitwhen target == null
                call GroupRemoveUnit( udg_TI_TempGroup, target )
                set dx = GetUnitX( target ) - x
                set dy = GetUnitY( target ) - y

                if ( target != buffplacer ) and TI_TargetFilter( target, p, i ) then

                    if SquareRoot( dx*dx + dy*dy ) > LoadReal( udg_TI_Hash, key, StringHash( "AOE" + I ) ) then

                        call UnitDamageTarget( buffplacer, target, damage*smalldfactor, true, false, udg_TI_AT[i], udg_TI_DT[i], null )

                    else

                        call UnitDamageTarget( buffplacer, target, damage, true, false, udg_TI_AT[i], udg_TI_DT[i], null )

                    endif

                endif

            endloop

        endif

        exitwhen i == udg_TI_SpellIndex

    endloop

    call FlushChildHashtable( udg_TI_Hash, key )

    set dying = null
    set buffplacer = null
    set p = null
    set I = null

    return false

endfunction


///////////////////////////////////////////////////////////
// This function checks if the level of incinerate spell //
// for the damage source is greater than zero in order   //
// run the main actions of the spell.                    //
///////////////////////////////////////////////////////////
function TI_MainAction takes nothing returns boolean

    local trigger trig   = GetTriggeringTrigger()
    local integer key    = GetHandleId( udg_DamageEventTarget )
    local integer i      = 0
    local integer level
    local integer timerkey
    local real dcap
    local string I

    loop

        set i = i + 1
        set level = GetUnitAbilityLevel( udg_DamageEventSource, udg_TI_SpellID[i] )

        if level > 0 then

            if not udg_IsDamageSpell or udg_TI_SpellAsTrigger[i] then

                set I = I2S( i )
                set dcap = udg_TI_DamageCapBase[i] + udg_TI_DamageCapPerLevel[i]*level

                if TI_TargetFilter( udg_DamageEventTarget, GetOwningPlayer( udg_DamageEventSource ), i ) then

                    call DestroyEffect( LoadEffectHandle( udg_TI_Hash, key, StringHash( "SFX" + I ) ) )
                    call SaveEffectHandle( udg_TI_Hash, key, StringHash( "SFX" + I ), AddSpecialEffectTarget( udg_TI_SFXModel1[i], udg_DamageEventTarget, udg_TI_AttachPoint[i] ) )
                    call DestroyTimer( LoadTimerHandle( udg_TI_Hash, key, StringHash( "Timer" + I ) ) )
                    call SaveTimerHandle( udg_TI_Hash, key, StringHash( "Timer" + I ), CreateTimer() )
                    set timerkey = GetHandleId( LoadTimerHandle( udg_TI_Hash, key, StringHash( "Timer" + I ) ) )
                    call SaveUnitHandle( udg_TI_Hash, timerkey, 1, udg_DamageEventTarget )
                    call SaveUnitHandle( udg_TI_Hash, key, StringHash( "BuffPlacer" + I ), udg_DamageEventSource )
                    call SaveReal( udg_TI_Hash, key, StringHash( "Damage" + I ), LoadReal( udg_TI_Hash, key, StringHash( "Damage" + I ) ) + udg_TI_DPABase[i] + udg_TI_DPAPerLevel[i]*level )
                    call SaveReal( udg_TI_Hash, key, StringHash( "AOE" + I ), udg_TI_ExplodeAOEBase[i] + udg_TI_ExplodeAOEPerLevel[i]*level )
                    call SaveReal( udg_TI_Hash, key, StringHash( "SmallDAOE" + I ), udg_TI_ExplodeSmallDAOEBase[i] + udg_TI_ExplodeSmallDAOEPerLev[i]*level )
                    call SaveReal( udg_TI_Hash, key, StringHash( "SmallDFactor" + I  ), udg_TI_ExplodeSmallDFactorBase[i] + udg_TI_ExplodeSmallDFactorPerLev[i]*level )
                    call SaveInteger( udg_TI_Hash, timerkey, 0, i )
                    call SaveBoolean( udg_TI_Hash, key, i, true )

                    if dcap != 0 then

                        if LoadReal( udg_TI_Hash, key, StringHash( "Damage" + I ) ) > dcap then

                            call SaveReal( udg_TI_Hash, key, StringHash( "Damage" + I ), dcap )

                        endif

                    endif

                    call DisableTrigger( trig )
                    call UnitDamageTarget( udg_DamageEventSource, udg_DamageEventTarget, udg_DamageEventAmount + LoadReal( udg_TI_Hash, key, StringHash( "Damage" + I ) ), true, false, udg_TI_AT[i], udg_TI_DT[i], null )
                    call EnableTrigger( trig )
                    set udg_DamageEventAmount = 0
                    call TimerStart( LoadTimerHandle( udg_TI_Hash, key, StringHash( "Timer" + I ) ), udg_TI_DurationBase[i] + udg_TI_DurationPerLevel[i]*level, false, function TI_Debuff )

                endif

            endif

        endif

        exitwhen i == udg_TI_SpellIndex

    endloop

    set trig = null
    set I = null

    return false

endfunction


/////////////////////////////
// Initialization function //
/////////////////////////////
function InitTrig_Triggered_Incinerate takes nothing returns nothing

    local trigger t1  = CreateTrigger()
    local trigger t2  = CreateTrigger()
    set udg_TI_Hash   = InitHashtable()

    call TriggerRegisterAnyUnitEventBJ( t1, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( t1, Filter( function TI_Incinerate ) )
    call TriggerRegisterVariableEvent( t2, "udg_DamageEvent", EQUAL, 1 )
    call TriggerAddCondition( t2, Filter( function TI_MainAction ) )
    call ExecuteFunc( "Trig_Incinerate_SpellsList_Actions" )

endfunction


//////////////////////
//******************//
//** End of Spell **//
//******************//
//////////////////////
Test Map Debug
  Events
    Game - DamageEvent becomes Equal to 1.00
  Conditions
    DamageEventAmount Greater than 0.00
  Actions
    For each (Integer TempInt) from 1 to TI_SpellIndex, do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (Level of TI_SpellID[TempInt] for DamageEventSource) Greater than 0
          Then - Actions
            Custom script: set udg_TempKey = GetHandleId( udg_DamageEventTarget )
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (DamageEventSource is A Hero) Equal to True
              Then - Actions
                Set SourceName = (Proper name of DamageEventSource)
              Else - Actions
                Set SourceName = (Name of DamageEventSource)
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (DamageEventTarget is A Hero) Equal to True
              Then - Actions
                Set TargetName = (Proper name of DamageEventTarget)
              Else - Actions
                Set TargetName = (Name of DamageEventTarget)
            Game - Display to Player Group - Player 1 (Red) the text: (SourceName + ( stacked + ((String((Load (Key (Damage + (String(TempInt)))) of TempKey from TI_Hash))) + ( damage to + (TargetName + .)))))
          Else - Actions
TI Variable Creator
  Events
  Conditions
  Actions
    Set TI_AT[0] = Chaos
    Set TI_AttachPoint[0] =
    Set TI_DPABase[0] = 0.00
    Set TI_DPAPerLevel[0] = 0.00
    Set TI_DT[0] = Unknown
    Set TI_DamageCapBase[0] = 0.00
    Set TI_DamageCapPerLevel[0] = 0.00
    Set TI_DurationBase[0] = 0.00
    Set TI_DurationPerLevel[0] = 0.00
    Set TI_ExplodeAOEBase[0] = 0.00
    Set TI_ExplodeAOEPerLevel[0] = 0.00
    Set TI_ExplodeSmallDAOEBase[0] = 0.00
    Set TI_ExplodeSmallDAOEPerLev[0] = 0.00
    Set TI_ExplodeSmallDFactorBase[0] = 0.00
    Set TI_ExplodeSmallDFactorPerLev[0] = 0.00
    Set TI_Hash = (Last created hashtable)
    Set TI_IsUnitAlly[0] = False
    Set TI_IsUnitIllusion[0] = False
    Set TI_IsUnitMechanical[0] = False
    Set TI_IsUnitMagicImmune[0] = False
    Set TI_IsUnitStructure[0] = False
    Set TI_SFXModel1[0] =
    Set TI_SFXModel2[0] =
    Set TI_SpellAsTrigger[0] = False
    Set TI_SpellIndex = 0
    Set TI_SpellID[0] = (Ability being cast)
    Set TI_TempGroup = (Last created unit group)
Delete Unit Indexer if you already have it in your map.
Unit Indexer gives you an array-safe (1-8190) custom value for units, eliminating the need for hashtables to store unit-specific data.
Just use "Set MyArrayData[(Custom value of Unit)] = (Some data)".
--------
If you want to get the unit assigned to an index (reverse lookup) use "UDexUnits[(Index)]".
--------
If you want to detect when an index is created or when it is released, use "UnitIndexEvent Equal to 1.00" (created) or "UnitIndexEvent Equal to 2.00" (released). The index being created/released is called "UDex".
--------
You can enable/disable Unit Indexer to protect some of your undesirable units from being indexed like this:

Trigger - Turn off Unit Indexer <gen>
Unit - Create 1 Dummy for (Triggering player) at TempPoint facing 0.00 degrees
Trigger - Turn on Unit Indexer <gen>
--------
If you want to use a Map Initialization trigger that uses custom value of units, to make sure that UnitIndexer initializes first, use the event "UnitIndexEvent Equal to 3.00". Otherwise the custom value of units may be zero.
--------
Advanced:
--------
If you want to lock the index of a unit, use "Set UnitIndexLock[(Index)] = (UnitIndexLock[(Index)] + 1)". This will prevent the index from being recycled. If you want to unlock it and allow it to be recycled, run the Unit Indexer <gen> trigger.

Note: Make sure if you add a lock that you will eventually remove the lock, otherwise the index will never be recycled.
Unit Indexer
  Events
    Map initialization
  Conditions
  Actions
    Custom script: call ExecuteFunc("InitializeUnitIndexer")
    Custom script: endfunction
    Custom script:
    Custom script: function ClearUnitIndex takes nothing returns nothing
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        (Custom value of UDexUnits[UDex]) Equal to 0
      Then - Actions
        Set UnitIndexLock[UDex] = (UnitIndexLock[UDex] - 1)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            UnitIndexLock[UDex] Equal to 0
          Then - Actions
            Set UDexNext[UDexPrev[UDex]] = UDexNext[UDex]
            Set UDexPrev[UDexNext[UDex]] = UDexPrev[UDex]
            Set UDexPrev[UDex] = 0
            Set UnitIndexEvent = 0.00
            Set UnitIndexEvent = 2.00
            Set UnitIndexEvent = 0.00
            Set UDexUnits[UDex] = No unit
            Set UDexNext[UDex] = UDexRecycle
            Set UDexRecycle = UDex
          Else - Actions
      Else - Actions
    Custom script: endfunction
    Custom script:
    Custom script: function IndexUnit takes nothing returns boolean
    Custom script: local integer pdex = udg_UDex
    Custom script: local integer ndex
    -------- - --------
    -------- You can customize the following block - if conditions are false the (Matching unit) won't be indexed. --------
    -------- - --------
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        UnitIndexerEnabled Equal to True
        (Custom value of (Matching unit)) Equal to 0
      Then - Actions
        Set UDexWasted = (UDexWasted + 1)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            UDexWasted Equal to 32
          Then - Actions
            Set UDexWasted = 0
            Set UDex = UDexNext[0]
            Custom script: loop
            Custom script: exitwhen udg_UDex == 0
            Custom script: set ndex = udg_UDexNext[udg_UDex]
            Custom script: call ClearUnitIndex()
            Custom script: set udg_UDex = ndex
            Custom script: endloop
          Else - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            UDexRecycle Equal to 0
          Then - Actions
            Set UDex = (UDexGen + 1)
            Set UDexGen = UDex
          Else - Actions
            Set UDex = UDexRecycle
            Set UDexRecycle = UDexNext[UDex]
        Set UDexUnits[UDex] = (Matching unit)
        Unit - Set the custom value of UDexUnits[UDex] to UDex
        Set UDexPrev[UDexNext[0]] = UDex
        Set UDexNext[UDex] = UDexNext[0]
        Set UDexNext[0] = UDex
        Set UnitIndexLock[UDex] = 1
        Set UnitIndexEvent = 0.00
        Set UnitIndexEvent = 1.00
        Set UnitIndexEvent = 0.00
        Custom script: set udg_UDex = pdex
      Else - Actions
    Custom script: return false
    Custom script: endfunction
    Custom script:
    Custom script: function InitializeUnitIndexer takes nothing returns nothing
    Custom script: local integer i = 16
    Custom script: local boolexpr b = Filter(function IndexUnit)
    Custom script: local region re = CreateRegion()
    Custom script: local trigger t = GetTriggeringTrigger()
    Custom script: local rect r = GetWorldBounds()
    Custom script: call RegionAddRect(re, r)
    Custom script: call TriggerRegisterEnterRegion(t, re, b)
    Custom script: call TriggerClearActions(t)
    Custom script: call TriggerAddAction(t, function ClearUnitIndex)
    Set UnitIndexerEnabled = True
    Custom script: loop
    Custom script: set i = i - 1
    Custom script: call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, Player(i), b)
    Custom script: exitwhen i == 0
    Custom script: endloop
    Custom script: call RemoveRect(r)
    Custom script: set re = null
    Custom script: set r = null
    Custom script: set t = null
    Custom script: set b = null
    Set UnitIndexEvent = 3.00
    Set UnitIndexEvent = 0.00
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 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 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 DamageTypeExplosive = -1
    Set DamageTypeCriticalStrike = 1
    Set DamageTypeHeal = 2
    Set DamageTypeReduced = 3
    Set 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 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 DAMAGE_FACTOR_BRACERS = 0.67
    Set DAMAGE_FACTOR_ELUNES = 0.80
    Set DAMAGE_FACTOR_ETHEREAL = 1.67
    -------- - --------
    -------- Do not enable any of the following lines as they are simply variable declarations to make copying easier --------
    -------- - --------
    Set AfterDamageEvent = (DamageEvent + DamageModifierEvent)
    Set ClearDamageEvent = (This trigger)
    Set DamageEventAmount = DamageEventPrevAmt
    Set DamageEventOverride = NextDamageOverride
    Set DamageEventSource = DamageEventTarget
    Set DamageEventTrigger = DmgEvTrig
    Set DamageEventType = (LastDmgPrevType[0] + NextDamageType)
    Set DamageEventsWasted = DmgEvRecursionN
    Set DmgEvRunning = DmgEvStarted
    Set IsDamageSpell = LastDmgWasSpell[0]
    Set LastDamageHP = (Elapsed time for DmgEvTimer)
    Set LastDmgPrevAmount[0] = LastDmgValue[0]
    Set LastDmgSource[0] = LastDmgTarget[0]
    Set HideDamageFrom[0] = False
    Set UnitDamageRegistered[0] = False
//TESH.scrollpos=262
//TESH.alwaysfold=0
//===========================================================================
// Damage Engine lets you detect, amplify, block or nullify damage. It even
// lets you detect if the damage was physical or from a spell. Just reference
// DamageEventAmount/Source/Target or the boolean IsDamageSpell, to get the
// necessary damage event data.
//
// - Detect damage: use the event "DamageEvent Equal to 1.00"
// - To change damage before it's dealt: use the event "DamageModifierEvent Equal to 1.00"
// - Detect damage after it was applied, use the event "AfterDamageEvent Equal to 1.00"
// - Detect spell damage: use the condition "IsDamageSpell Equal to True"
// - Detect zero-damage: use the event "DamageEvent Equal to 2.00" (an AfterDamageEvent will not fire for this)
//
// You can specify the DamageEventType before dealing triggered damage. To prevent an already-improbable error, I recommend running the trigger "ClearDamageEvent (Checking Conditions)" after dealing triggered damage from within a damage event:
// - Set NextDamageType = DamageTypeWhatever
// - Unit - Cause...
// - Trigger - Run ClearDamageEvent (Checking Conditions)
//
// You can modify the DamageEventAmount and the DamageEventType from a "DamageModifierEvent Equal to 1.00" trigger.
// - If the amount is modified to negative, it will count as a heal.
// - If the amount is set to 0, no damage will be dealt.
//
// If you need to reference the original in-game damage, use the variable "DamageEventPrevAmt".
//
//===========================================================================
// Programming note about "integer i" and "udg_DmgEvRecursionN": integer i
// ranges from -1 upwards. "udg_DmgEvRecursionN" ranges from 0 upwards.
// "integer i" is always 1 less than "udg_DmgEvRecursionN"
//
function DmgEvResetVars takes nothing returns nothing
    local integer i = udg_DmgEvRecursionN - 2
    set udg_DmgEvRecursionN = i + 1
    if i >= 0 then
        set udg_DamageEventPrevAmt  = udg_LastDmgPrevAmount[i]
        set udg_DamageEventAmount   = udg_LastDmgValue[i]
        set udg_DamageEventSource   = udg_LastDmgSource[i]
        set udg_DamageEventTarget   = udg_LastDmgTarget[i]
        set udg_IsDamageSpell       = udg_LastDmgWasSpell[i]
        set udg_DamageEventType     = udg_LastDmgPrevType[i]
    endif
endfunction

function CheckDamagedLifeEvent takes boolean clear returns nothing
    if clear then
        set udg_NextDamageOverride = false
        set udg_NextDamageType = 0
    endif
    if udg_DmgEvTrig != null then
        call DestroyTrigger(udg_DmgEvTrig)
        set udg_DmgEvTrig = null
       
        if udg_IsDamageSpell then
            call SetWidgetLife(udg_DamageEventTarget, RMaxBJ(udg_LastDamageHP, 0.41))
            if udg_LastDamageHP <= 0.405 then
                if udg_DamageEventType < 0 then
                    call SetUnitExploded(udg_DamageEventTarget, true)
                endif
                //Kill the unit
                call DisableTrigger(udg_DamageEventTrigger)
                call UnitDamageTarget(udg_DamageEventSource, udg_DamageEventTarget, -999, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
                call EnableTrigger(udg_DamageEventTrigger)
            endif
        elseif GetUnitAbilityLevel(udg_DamageEventTarget, udg_DamageBlockingAbility) > 0 then
            call UnitRemoveAbility(udg_DamageEventTarget, udg_DamageBlockingAbility)
            call SetWidgetLife(udg_DamageEventTarget, udg_LastDamageHP)
        endif
        if udg_DamageEventAmount != 0.00 and not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
            set udg_AfterDamageEvent = 0.00
            set udg_AfterDamageEvent = 1.00
            set udg_AfterDamageEvent = 0.00
        endif
        call DmgEvResetVars()
    endif
endfunction
   
function DmgEvOnExpire takes nothing returns nothing
    set udg_DmgEvStarted = false
    call CheckDamagedLifeEvent(true)
endfunction

function PreCheckDamagedLifeEvent takes nothing returns boolean
    call CheckDamagedLifeEvent(true)
    return false
endfunction

function OnUnitDamage takes nothing returns boolean
    local boolean override = udg_DamageEventOverride
    local integer i = udg_DmgEvRecursionN - 1
    local string s
    local real prevAmount
    local real life
    local real prevLife
    local unit u
    call CheckDamagedLifeEvent(false) //in case the unit state event failed and the 0.00 second timer hasn't yet expired
    if i >= 0 then
        if i < 16 then
            set udg_LastDmgPrevAmount[i]= udg_DamageEventPrevAmt
            set udg_LastDmgValue[i]     = udg_DamageEventAmount
            set udg_LastDmgSource[i]    = udg_DamageEventSource
            set udg_LastDmgTarget[i]    = udg_DamageEventTarget
            set udg_LastDmgWasSpell[i]  = udg_IsDamageSpell
            set udg_LastDmgPrevType[i]  = udg_DamageEventType
        else
            //set s = "WARNING: Recursion error when dealing damage! Make sure when you deal damage from within a DamageEvent trigger, do it like this:\n\n"
            //set s = s + "Trigger - Turn off (This Trigger)\n"
            //set s = s + "Unit - Cause...\n"
            //set s = s + "Trigger - Turn on (This Trigger)"
           
            //Delete the next couple of lines to disable the in-game recursion crash warnings
            //call ClearTextMessages()
            //call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.00, 0.00, 999.00, s)
            return false
        endif
    endif
    set udg_DmgEvRecursionN     = i + 2
    set u                       = GetTriggerUnit()
    set prevAmount              = GetEventDamage()
    set udg_DamageEventSource   = GetEventDamageSource()
   
    set udg_DamageEventAmount   = prevAmount
    set udg_DamageEventTarget   = u
   
    set udg_DamageEventType     = udg_NextDamageType
    set udg_NextDamageType      = 0
    set udg_DamageEventOverride = udg_NextDamageOverride
    set udg_NextDamageOverride  = false
   
    if prevAmount == 0.00 then
        if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
            set udg_DamageEventPrevAmt = 0.00
            set udg_DamageEvent = 0.00
            set udg_DamageEvent = 2.00
            set udg_DamageEvent = 0.00
        endif
        call DmgEvResetVars()
    else
        if not udg_DmgEvStarted then
            set udg_DmgEvStarted = true
            call TimerStart(udg_DmgEvTimer, 0.00, false, function DmgEvOnExpire)
        endif
        set udg_IsDamageSpell = prevAmount < 0.00
        if udg_IsDamageSpell then
            set prevAmount = -udg_DamageEventAmount
            set life = 1.00
            if IsUnitType(u, UNIT_TYPE_ETHEREAL) and not IsUnitType(u, UNIT_TYPE_HERO) then
                set life = life*udg_DAMAGE_FACTOR_ETHEREAL //1.67
            endif
            if GetUnitAbilityLevel(u, 'Aegr') > 0 then
                set life = life*udg_DAMAGE_FACTOR_ELUNES //0.80
            endif
            if udg_DmgEvBracers != 0 and IsUnitType(u, UNIT_TYPE_HERO) then
                //Inline of UnitHasItemOfTypeBJ without the potential handle ID leak.
                set i = 6
                loop
                    set i = i - 1
                    if GetItemTypeId(UnitItemInSlot(u, i)) == udg_DmgEvBracers then
                        set life = life*udg_DAMAGE_FACTOR_BRACERS //0.67
                        exitwhen true
                    endif
                    exitwhen i == 0
                endloop
            endif
            set udg_DamageEventAmount = prevAmount*life
        endif
        set udg_DamageEventPrevAmt = prevAmount
        set udg_DamageModifierEvent = 0.00
        if not udg_DamageEventOverride then
            set udg_DamageModifierEvent = 1.00
            if not udg_DamageEventOverride then
                set udg_DamageModifierEvent = 2.00
                set udg_DamageModifierEvent = 3.00
            endif
        endif
        set udg_DamageEventOverride = override
        if udg_DamageEventAmount > 0.00 then
            set udg_DamageModifierEvent = 4.00
        endif
        set udg_DamageModifierEvent = 0.00
        if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
            set udg_DamageEvent = 0.00
            set udg_DamageEvent = 1.00
            set udg_DamageEvent = 0.00
        endif
        call CheckDamagedLifeEvent(true) //in case the unit state event failed from a recursive damage event
       
        //All events have run and the damage amount is finalized.
        set life = GetWidgetLife(u)
        set udg_DmgEvTrig = CreateTrigger()
        call TriggerAddCondition(udg_DmgEvTrig, Filter(function PreCheckDamagedLifeEvent))
        if not udg_IsDamageSpell then
            if udg_DamageEventAmount != prevAmount then
                set life = life + prevAmount - udg_DamageEventAmount
                if GetUnitState(u, UNIT_STATE_MAX_LIFE) < life then
                    set udg_LastDamageHP = life - prevAmount
                    call UnitAddAbility(u, udg_DamageBlockingAbility)
                endif
                call SetWidgetLife(u, RMaxBJ(life, 0.42))
            endif
            call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, LESS_THAN, RMaxBJ(0.41, life - prevAmount/2.00))
        else
            set udg_LastDamageHP = GetUnitState(u, UNIT_STATE_MAX_LIFE)
            set prevLife = life
            if life + prevAmount*0.75 > udg_LastDamageHP then
                set life = RMaxBJ(udg_LastDamageHP - prevAmount/2.00, 1.00)
                call SetWidgetLife(u, life)
                set life = (life + udg_LastDamageHP)/2.00
            else
                set life = life + prevAmount*0.50
            endif
            set udg_LastDamageHP = prevLife - (prevAmount - (prevAmount - udg_DamageEventAmount))
            call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, GREATER_THAN, life)
        endif
        set u = null
    endif
    return false
endfunction

function CreateDmgEvTrg takes nothing returns nothing
    set udg_DamageEventTrigger = CreateTrigger()
    call TriggerAddCondition(udg_DamageEventTrigger, Filter(function OnUnitDamage))
endfunction

function SetupDmgEv takes nothing returns boolean
    local integer i = udg_UDex
    local unit u
    if udg_UnitIndexEvent == 1.00 then
        set u = udg_UDexUnits[i]
        if GetUnitAbilityLevel(u, 'Aloc') == 0 and TriggerEvaluate(gg_trg_Damage_Engine_Config) then
            set udg_UnitDamageRegistered[i] = true
            call TriggerRegisterUnitEvent(udg_DamageEventTrigger, u, EVENT_UNIT_DAMAGED)
            call UnitAddAbility(u, udg_SpellDamageAbility)
            call UnitMakeAbilityPermanent(u, true, udg_SpellDamageAbility)
        endif
        set u = null
    else
        set udg_HideDamageFrom[i] = false
        if udg_UnitDamageRegistered[i] then
            set udg_UnitDamageRegistered[i] = false
            set udg_DamageEventsWasted = udg_DamageEventsWasted + 1
            if udg_DamageEventsWasted == 32 then //After 32 registered units have been removed...
                set udg_DamageEventsWasted = 0
               
                //Rebuild the mass EVENT_UNIT_DAMAGED trigger:
                call DestroyTrigger(udg_DamageEventTrigger)
                call CreateDmgEvTrg()
                set i = udg_UDexNext[0]
                loop
                    exitwhen i == 0
                    if udg_UnitDamageRegistered[i] then
                        call TriggerRegisterUnitEvent(udg_DamageEventTrigger, udg_UDexUnits[i], EVENT_UNIT_DAMAGED)
                    endif
                    set i = udg_UDexNext[i]
                endloop
            endif
        endif
    endif
    return false
endfunction
   
//===========================================================================
function InitTrig_Damage_Engine takes nothing returns nothing
    local unit u = CreateUnit(Player(15), 'uloc', 0, 0, 0)
    local integer i = 16
   
    //Create this trigger with UnitIndexEvents in order add and remove units
    //as they are created or removed.
    local trigger t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
    call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 2.00)
    call TriggerAddCondition(t, Filter(function SetupDmgEv))
    set t = null
   
    //Run the configuration trigger to set all configurables:
    if gg_trg_Damage_Engine_Config == null then
        //It's possible this InitTrig_ function ran first, in which case use ExecuteFunc.
        call ExecuteFunc("Trig_Damage_Engine_Config_Actions")
    else
        call TriggerExecute(gg_trg_Damage_Engine_Config)
    endif
   
    //Create trigger for storing all EVENT_UNIT_DAMAGED events.
    call CreateDmgEvTrg()
   
    //Create GUI-friendly trigger for cleaning up after UnitDamageTarget.
    set udg_ClearDamageEvent = CreateTrigger()
    call TriggerAddCondition(udg_ClearDamageEvent, Filter(function PreCheckDamagedLifeEvent))
   
    //Disable SpellDamageAbility for every player.
    loop
        set i = i - 1
        call SetPlayerAbilityAvailable(Player(i), udg_SpellDamageAbility, false)
        exitwhen i == 0
    endloop
   
    //Preload abilities.
    call UnitAddAbility(u, udg_DamageBlockingAbility)
    call UnitAddAbility(u, udg_SpellDamageAbility)
    call RemoveUnit(u)
    set u = null
endfunction
//TESH.scrollpos=-1
//TESH.alwaysfold=0
function Cond takes nothing returns boolean
    return IsUnitType( GetTriggerUnit(), UNIT_TYPE_HERO )
endfunction

function A takes nothing returns nothing

    local unit u = GetTriggerUnit()
    local integer ID = GetUnitTypeId( u )
    local player p = GetOwningPlayer( u )
    local real facing = GetRandomReal( 0, 360 )
    local real wait = 2

    if not IsUnitType( u, UNIT_TYPE_HERO ) then

        call CreateUnit( p, ID, GetRandomReal( GetRectMinX( bj_mapInitialPlayableArea ), GetRectMaxX( bj_mapInitialPlayableArea ) ), GetRandomReal( GetRectMinY( bj_mapInitialPlayableArea ), GetRectMaxY( bj_mapInitialPlayableArea ) ), facing )
        call TriggerSleepAction( wait )
        call RemoveUnit( u )

    else

        call TriggerSleepAction( wait )
        call ReviveHero( u, GetRectCenterX( bj_mapInitialPlayableArea ), GetRectCenterY( bj_mapInitialPlayableArea ), false )

    endif

    set u = null
    set p = null

endfunction

function B takes nothing returns nothing

    local unit u = GetTriggerUnit()
    local player p = GetOwningPlayer( u )
    local integer i = GetHeroLevel( u )

    if IsUnitAlly( u, p ) then

        call SetHeroLevel( u, ( i + 1 ), true )

    endif

    set u = null
    set p = null

endfunction

function InitTrig_Init takes nothing returns nothing

    local real centerX = GetRectCenterX( bj_mapInitialPlayableArea )
    local real centerY = GetRectCenterY( bj_mapInitialPlayableArea )
    local player p = Player(1)
    local real dist = 1300
    local integer creepcount = 20
    local integer campcount = 15
    local integer i = 0
    local integer f = 360
    local real x
    local real y
    local integer a = 1
    local real facing
    local integer index = 0

    local trigger t1 = CreateTrigger()
    local trigger t2 = CreateTrigger()

    call FogEnable( false )
    call FogMaskEnable( false )
    call SetHeroLevel( CreateUnit( Player(0), 'H000', centerX - 200, centerY, 270 ), 10, false )
    call SetHeroLevel( CreateUnit( Player(0), 'H001', centerX + 200, centerY, 270 ), 10, false )
    call SetPlayerState( p, PLAYER_STATE_GIVES_BOUNTY, 1 )

    loop

        exitwhen i > f
        set i = i + ( f / campcount )
        set x = centerX + dist * Cos( i * bj_DEGTORAD )
        set y = centerY + dist * Sin( i * bj_DEGTORAD )
        set facing = bj_RADTODEG * Atan2(centerY - y, centerX - x)

        loop

            exitwhen a > creepcount
            set a = a + 1
            call CreateUnit( p, 'hpea', x, y, facing )

        endloop

        set a = 1

    endloop

    set p = null

    loop

        call TriggerRegisterPlayerUnitEvent( t1, Player(index), EVENT_PLAYER_UNIT_DEATH, null )
        call TriggerRegisterPlayerUnitEvent( t2, Player(index), EVENT_PLAYER_UNIT_SELECTED, null )
        set index = index + 1
        exitwhen index == 16

    endloop

    call TriggerAddAction( t1, function A )
    call TriggerAddCondition( t2, Filter( function Cond ) )
    call TriggerAddAction( t2, function B )

    set t1 = null
    set t2 = null

endfunction