globals
constant boolean LIBRARY_BoolexprUtils=true
boolexpr BOOLEXPR_TRUE=null
boolexpr BOOLEXPR_FALSE=null
constant boolean LIBRARY_BoundSentinel=true
constant boolean BoundSentinel__ALLOW_OUTSIDE_PLAYABLE_MAP_AREA= false
real BoundSentinel__maxx
real BoundSentinel__maxy
real BoundSentinel__minx
real BoundSentinel__miny
constant boolean LIBRARY_Table=true
constant integer Table___MAX_INSTANCES=8100
hashtable Table___ht
constant boolean LIBRARY_xeSandBox=true
constant boolean LIBRARY_xebasic=true
constant integer XE_DUMMY_UNITID= 'e000'
constant integer XE_HEIGHT_ENABLER= 'Amrf'
constant integer XE_TREE_RECOGNITION= 'Aeat'
constant real XE_ANIMATION_PERIOD=  0.025
constant real XE_MAX_COLLISION_SIZE=  197.0
constant boolean LIBRARY_DemoMap=true
constant boolean DemoMap__AUTO= true
constant integer DemoMap__UNITID_TESTHERO= 'N000'
constant integer DemoMap__UNITID_SOLDIER= 'nsnp'
constant integer DemoMap__ITEMID_ASSISTANT= 'I000'
constant integer DemoMap__SPELLID_LEVELUP= 'A001'
constant integer DemoMap__SPELLID_RESET= 'A000'
constant integer DemoMap__SPELLID_RAISEFOOTMEN= 'A002'
constant integer DemoMap__COLORID_PLAYER= 5
constant integer DemoMap__COLORID_CREEPS= 12
constant integer DemoMap__COLORID_COMP= 1
constant string DemoMap__STRING_COMPNAME= "Evil guys"
constant string DemoMap__MODELPATH_OUT= "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl"
constant string DemoMap__MODELPATH_IN= "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl"
constant string DemoMap__MODELPATH_RETRAINING= "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
constant string DemoMap__MSG_SUPERMODE= "|cffffff10CoolDown/ManaCost Disabled|r"
group DemoMap__enumgroup
real DemoMap__MapSurface
real DemoMap__START_LOCATION_X
real DemoMap__START_LOCATION_Y
integer array DemoMap__CREATE_ITEMS
integer DemoMap__CREATE_ITEMS_N=0
unit array DemoMap__footman
trigger array DemoMap__trig
boolean DemoMap__SuperMode=false
integer DemoMap__Restores=0
constant boolean LIBRARY_xecast=true
constant integer xecast__MAXINSTANCES= 8190
constant integer xecast__INITIAL_DUMMY_COUNT= 12
constant integer xecast__DUMMY_STACK_LIMIT= 50
constant boolean xecast__FORCE_INVISIBLE_CAST= false
constant boolean xecast__AUTO_RESET_MANA_COOLDOWN= true
real xecast__EPSILON=0.001
constant boolean LIBRARY_xedamage=true
constant integer xedamage__MAX_SUB_OPTIONS= 3
constant real xedamage__FACTOR_TEST_DAMAGE= 0.01
constant real xedamage__MAX_DAMAGE_FACTOR= 3.00
constant real xedamage__EPSILON= 0.000000001
unit xedamage__dmger
constant integer xedamage__MAX_SPACE= 8190
constant boolean LIBRARY_xedummy=true
constant integer xedummy___ANGLE_RESOLUTION= 12
constant integer xedummy___INITIAL_DUMMY_COUNT= 36
constant integer xedummy___DUMMY_STACK_LIMIT= 240
constant boolean LIBRARY_xepreload=true
unit xepreload__dum=null
constant boolean LIBRARY_xefx=true
constant integer xefx___MAX_INSTANCES= 8190
constant real xefx___MIN_RECYCLE_DELAY= 4.0
constant real xefx___RECYCLE_INTERVAL= 0.5
constant boolean xefx___RECYCLE_DUMMY_UNITS= true
timer xefx___recycler
constant boolean LIBRARY_StormyDreams=true
constant integer StormyDreams___SPELL_ID='A00B'
constant integer StormyDreams___BONUS_SPELL_ID='AIt6'
constant integer StormyDreams___CAST_ABILITY_ID='A00D'
constant integer StormyDreams___CAST_REQUIRED_LEVEL= 0
constant integer StormyDreams___CAST_REQUIRED_BONUSLEVEL= 1
constant string StormyDreams___MODEL_PATH_MISSILE= "Abilities\\Spells\\Other\\Incinerate\\IncinerateBuff.mdl"
constant string StormyDreams___MODEL_PATH_BONUS_MISSILE= "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
constant string StormyDreams___MODEL_PATH_BONUS_FLASH= "Abilities\\Weapons\\VengeanceMissile\\VengeanceMissile.mdx"
constant string StormyDreams___MODEL_PATH_FLASH= "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdx"
constant integer StormyDreams___ALPHA_STARTING_VALUE= 0
constant real StormyDreams___ALPHA_INCREMENT_PER_SECOND= 150.0
constant real StormyDreams___FLASH_FX_PERIOD= 0.25
constant real StormyDreams___INITIAL_THROW= 0.05
constant real StormyDreams___THROW_PERIOD= 0.35
constant real StormyDreams___THROW_ANIMATION_SPEED= 4.00
constant real StormyDreams___RESTORE_ANIMATION_SPEED= 1.00
constant real StormyDreams___INITIAL_OFFSET= 60.0
constant real StormyDreams___BEZIER_Z1= 60.0
constant real StormyDreams___BEZIER_Z2= 30.0
constant real StormyDreams___BEZIER_Z3= 180.0
constant real StormyDreams___BEZIER_Z4= 0.0
constant real StormyDreams___CLOCK_TICK= XE_ANIMATION_PERIOD
constant integer StormyDreams___MAX_SPELL_LEVELS= 3
constant integer StormyDreams___MAX_BONUS_LEVELS= 3
integer array StormyDreams___V
integer array StormyDreams___VT
integer StormyDreams___N=0
integer StormyDreams___NT=0
timer StormyDreams___T
integer StormyDreams___Tab
group StormyDreams___enumgroup
boolexpr StormyDreams___fetchunits
unit array StormyDreams___U
integer StormyDreams___Un
integer StormyDreams___Cast
integer array StormyDreams___damageconf
constant boolean LIBRARY_xecollider=true
constant real xecollider___DEFAULT_COLLISION_SIZE=   50.0
constant real xecollider___DEFAULT_MAX_SPEED= 1500.0
constant real xecollider___DEFAULT_EXPIRATION_TIME=    5.0
constant real xecollider___PI2= 6.28318
constant boolean LIBRARY_xemissile=true
constant boolean LIBRARY_ChainInferno=true
constant integer ChainInferno__SPELL_ID='A00C'
constant real ChainInferno__NOISE=50.0
integer array ChainInferno__xdam
group ChainInferno__enumgroup
constant boolean LIBRARY_FireNovaStrike=true
constant integer FireNovaStrike__SPELL_ID= 'A007'
constant integer FireNovaStrike__FIREBALL_COUNT= 20
integer FireNovaStrike__damageOptions
constant boolean LIBRARY_Fireblast=true
constant integer Fireblast___SPELL_ID= 'A00E'
constant real Fireblast___TARGET_RADIUS= 750.0
constant real Fireblast___LAUNCH_PERIOD= 0.2
constant string Fireblast___MAIN_MODEL= "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
constant real Fireblast___MAIN_SCALE= 2.0
constant real Fireblast___MAIN_LAUNCH_OFFSET= 60.0
constant real Fireblast___MAIN_SPEED= 500.0
constant real Fireblast___MAIN_ARC= 0.25
constant string Fireblast___CHILD_MODEL= "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
constant real Fireblast___CHILD_SCALE= 0.5
constant real Fireblast___CHILD_SPEED= 1000.0
constant real Fireblast___CHILD_ARC= 0.15
integer Fireblast___damageOptions
trigger gg_trg_Melee_Initialization= null
trigger gg_trg_xebasic= null
trigger gg_trg_xepreload= null
trigger gg_trg_xedummy= null
trigger gg_trg_xecast= null
trigger gg_trg_xefx= null
trigger gg_trg_xedamage= null
trigger gg_trg_xecollider= null
trigger gg_trg_xemissile= null
trigger gg_trg_xe_readme= null
trigger gg_trg_xepreload_readme= null
trigger gg_trg_xedummy_readme= null
trigger gg_trg_xecast_readme= null
trigger gg_trg_xefx_readme= null
trigger gg_trg_xedamage_readme= null
trigger gg_trg_xecollider_readme= null
trigger gg_trg_xemissile_readme= null
trigger gg_trg_Table= null
trigger gg_trg_BoundSentinel= null
trigger gg_trg_IllusionRune= null
trigger gg_trg_SheepStaff= null
trigger gg_trg_BiGreenFire= null
trigger gg_trg_FireNovaStrike= null
trigger gg_trg_StormyDreams= null
trigger gg_trg_ChainInferno= null
trigger gg_trg_Fireblast= null
trigger gg_trg_sandbox= null
trigger gg_trg_DemoMap= null
integer IllusionRune___cast
constant integer BiGreenFire___FIRE_BALL_COUNT= 2
constant real BiGreenFire___DISTANCE= 75.0
trigger l__library_init
constant integer si__Table___GTable=1
integer si__Table___GTable_F=0
integer si__Table___GTable_I=0
integer array si__Table___GTable_V
constant integer si__Table=2
constant integer si__StringTable=3
constant integer si__HandleTable=4
constant integer si__DemoMap__itemdata=5
integer si__DemoMap__itemdata_F=0
integer si__DemoMap__itemdata_I=0
integer array si__DemoMap__itemdata_V
real array s__DemoMap__itemdata_sx
real array s__DemoMap__itemdata_sy
boolean array s__DemoMap__itemdata_sb
constant integer si__DemoMap__unitdata=6
integer si__DemoMap__unitdata_F=0
integer si__DemoMap__unitdata_I=0
integer array si__DemoMap__unitdata_V
real array s__DemoMap__unitdata_sx
real array s__DemoMap__unitdata_sy
real array s__DemoMap__unitdata_sf
group array s__DemoMap__unitdata_camp
integer array s___DemoMap__unitdata_items
constant integer s___DemoMap__unitdata_items_size=6
integer array s__DemoMap__unitdata_items
boolean array s__DemoMap__unitdata_stored
constant integer si__xecast=8
integer si__xecast_F=0
integer si__xecast_I=0
integer array si__xecast_V
integer array s__xecast_abilityid
integer array s__xecast_level
real array s__xecast_recycledelay
player array s__xecast_owningplayer
boolean array s__xecast_customsource
real array s__xecast_sourcex
real array s__xecast_sourcey
real array s__xecast_sourcez
boolean array s__xecast_autodestroy
unit array s__xecast_dummystack
integer s__xecast_top=0
unit s__xecast_instantdummy
integer array s__xecast_oid
timer s__xecast_gametime
timer s__xecast_T
unit array s__xecast_recycle
real array s__xecast_expiretime
integer s__xecast_rn=0
trigger s__xecast_abilityRemove
integer s__xecast_cparent
integer s__xecast_current
real s__xecast_cexpire
group s__xecast_enumgroup
real s__xecast_aoex
real s__xecast_aoey
real s__xecast_aoeradius
integer s__xecast_cinstance
boolexpr s__xecast_aoefunc
constant integer si__xedamage=9
integer si__xedamage_F=0
integer si__xedamage_I=0
integer array si__xedamage_V
boolean array s__xedamage_damageSelf
boolean array s__xedamage_damageAllies
boolean array s__xedamage_damageEnemies
boolean array s__xedamage_damageNeutral
boolean array s__xedamage_ranged
boolean array s__xedamage_visibleOnly
boolean array s__xedamage_deadOnly
boolean array s__xedamage_alsoDead
boolean array s__xedamage_damageTrees
damagetype array s__xedamage_dtype
attacktype array s__xedamage_atype
weapontype array s__xedamage_wtype
integer array s__xedamage_tag
boolean array s__xedamage_forceDamage
real array s__xedamage_allyfactor
boolean array s__xedamage_use_ex
unittype array s__xedamage_ex_ut
boolean array s__xedamage_use_req
unittype array s__xedamage_req_ut
unittype array s___xedamage_fct
constant integer s___xedamage_fct_size=3
integer array s__xedamage_fct
real array s___xedamage_fc
constant integer s___xedamage_fc_size=3
integer array s__xedamage_fc
integer array s__xedamage_fcn
integer array s___xedamage_abifct
constant integer s___xedamage_abifct_size=3
integer array s__xedamage_abifct
real array s___xedamage_abifc
constant integer s___xedamage_abifc_size=3
integer array s__xedamage_abifc
integer array s__xedamage_abifcn
boolean array s__xedamage_usefx
string array s__xedamage_fxpath
string array s__xedamage_fxattach
damagetype s__xedamage_CurrentDamageType=null
attacktype s__xedamage_CurrentAttackType=null
integer s__xedamage_CurrentDamageTag=0
integer s__xedamage_inUse= 0
boolean s__xedamage_isDummyDamage= false
integer s__xedamage_instance
integer array s__xedamage_countAOE
unit array s__xedamage_sourceAOE
real array s__xedamage_AOEx
real array s__xedamage_AOEy
real array s__xedamage_AOEradius
real array s__xedamage_AOEdamage
boolexpr s__xedamage_filterAOE
boolexpr s__xedamage_filterDestAOE
group s__xedamage_enumgroup
rect s__xedamage_AOERect
constant integer si__xedummy___recycleQueue=14
integer array s__xedummy___recycleQueue_next
integer array s__xedummy___recycleQueue_prev
real array s__xedummy___recycleQueue_angle
integer array s__xedummy___recycleQueue_size
integer array s__xedummy___recycleQueue_first
integer array s__xedummy___recycleQueue_last
constant integer si__xedummy___xedummy=15
integer si__xedummy___xedummy_F=0
integer si__xedummy___xedummy_I=0
integer array si__xedummy___xedummy_V
group s__xedummy___xedummy_g=CreateGroup()
unit array s__xedummy___xedummy_u
integer array s__xedummy___xedummy_next
unit s__xedummy___xedummy_dummy
constant integer si__xepreload__init=16
constant integer si__xefx___recyclebin=17
integer si__xefx___recyclebin_F=0
integer si__xefx___recyclebin_I=0
integer array si__xefx___recyclebin_V
unit array s__xefx___recyclebin_u
integer array s__xefx___recyclebin_next
integer array s__xefx___recyclebin_list
integer s__xefx___recyclebin_readindex=1
integer s__xefx___recyclebin_writeindex=0
integer s__xefx___recyclebin_count=0
constant integer si__xefx=18
integer si__xefx_F=0
integer si__xefx_I=0
integer array si__xefx_V
integer array s__xefx_tag
unit array s__xefx_dummy
effect array s__xefx_fx
real array s__xefx_zang
integer array s__xefx_r
integer array s__xefx_g
integer array s__xefx_b
integer array s__xefx_a
integer array s__xefx_abil
constant integer si__StormyDreams___missile=19
integer si__StormyDreams___missile_F=0
integer si__StormyDreams___missile_I=0
integer array si__StormyDreams___missile_V
group array s__StormyDreams___missile_targetlog
integer array s__StormyDreams___missile_level
integer array s__StormyDreams___missile_bonuslevel
unit array s__StormyDreams___missile_u
real array s__StormyDreams___missile_x1
real array s__StormyDreams___missile_x2
real array s__StormyDreams___missile_x3
real array s__StormyDreams___missile_x4
real array s__StormyDreams___missile_y1
real array s__StormyDreams___missile_y2
real array s__StormyDreams___missile_y3
real array s__StormyDreams___missile_y4
real array s__StormyDreams___missile_s
real array s__StormyDreams___missile_inc
integer array s__StormyDreams___missile_fx
real array s__StormyDreams___missile_flashtime
integer s__StormyDreams___missile_lastid=0
constant integer si__StormyDreams___throw=20
integer si__StormyDreams___throw_F=0
integer si__StormyDreams___throw_I=0
integer array si__StormyDreams___throw_V
integer array s__StormyDreams___throw_level
integer array s__StormyDreams___throw_bonuslevel
integer array s__StormyDreams___throw_donetimes
real array s__StormyDreams___throw_remaining
integer array s__StormyDreams___throw_tog
boolean array s__StormyDreams___throw_stop
real array s__StormyDreams___throw_tx
real array s__StormyDreams___throw_ty
unit array s__StormyDreams___throw_u
constant integer si__xecollider___eventHandler=21
integer si__xecollider___eventHandler_F=0
integer si__xecollider___eventHandler_I=0
integer array si__xecollider___eventHandler_V
integer array si__xecollider___eventHandler_type
trigger array st__xecollider___eventHandler_onDestroy
trigger array st__xecollider___eventHandler_onUnitHit
trigger array st__xecollider___eventHandler_loopControl
constant integer si__xecollider=22
integer array s__xecollider_fx
real array s__xecollider_expirationTime
real array s__xecollider_speed
real array s__xecollider_acceleration
real array s__xecollider_maxSpeed
real array s__xecollider_minSpeed
real array s__xecollider_angleSpeed
integer s__xecollider_lastSeen= 0
group array s__xecollider_seen
boolean array s__xecollider_silent
timer s__xecollider_T
integer s__xecollider_N=0
integer array s__xecollider_V
code s__xecollider_timerLoopFunction
boolean array s__xecollider_dead
real array s__xecollider_csize
real array s__xecollider_dir
constant integer s__xecollider_ANGLE_HOMING_UNIT=1
constant integer s__xecollider_ANGLE_HOMING_POINT=2
constant integer s__xecollider_ANGLE_NO_MOVEMENT=0
constant integer s__xecollider_ANGLE_ROTATING=3
integer array s__xecollider_angleMode
unit array s__xecollider_homingTargetUnit
real array s__xecollider_homingTargetX
real array s__xecollider_homingTargetY
real s__xecollider_newx
real s__xecollider_newy
group s__xecollider_enumGroup
group s__xecollider_tempGroup
unit array s__xecollider_picked
integer s__xecollider_pickedN
constant integer si__xemissile__eventHandler=23
integer si__xemissile__eventHandler_F=0
integer si__xemissile__eventHandler_I=0
integer array si__xemissile__eventHandler_V
integer array si__xemissile__eventHandler_type
trigger array st__xemissile__eventHandler_onDestroy
trigger array st__xemissile__eventHandler_onHit
trigger array st__xemissile__eventHandler_loopControl
constant integer si__xemissile__missile=24
integer array s__xemissile__missile_fx
real array s__xemissile__missile_time
real array s__xemissile__missile_mx
real array s__xemissile__missile_my
real array s__xemissile__missile_mvx
real array s__xemissile__missile_mvy
real array s__xemissile__missile_mvxy
real array s__xemissile__missile_mz
real array s__xemissile__missile_mvz
real array s__xemissile__missile_maz
location s__xemissile__missile_l= Location(0.0, 0.0)
real array s__xemissile__missile_tx
real array s__xemissile__missile_ty
real array s__xemissile__missile_tz
unit array s__xemissile__missile_tu
real array s__xemissile__missile_zoffset
boolean array s__xemissile__missile_update
boolean array s__xemissile__missile_launched
boolean array s__xemissile__missile_dead
boolean array s__xemissile__missile_silent
timer s__xemissile__missile_T
integer s__xemissile__missile_N=0
integer array s__xemissile__missile_V
code s__xemissile__missile_timerLoopFunction
constant integer si__xemissile=25
constant integer si__xehomingmissile=26
constant integer si__ChainInferno__missile=27
integer array s__ChainInferno__missile_level
integer array s__ChainInferno__missile_targetCount
unit array s__ChainInferno__missile_owner
real array s__ChainInferno__missile_time
group array s__ChainInferno__missile_targetLog
real s__ChainInferno__missile_targetdist=0.0
integer s__ChainInferno__missile_instance
constant integer si__FireNovaStrike__FireBolt=28
unit array s__FireNovaStrike__FireBolt_castingHero
integer array s__FireNovaStrike__FireBolt_level
constant integer si__FireblastChild=29
unit array s__FireblastChild_caster
integer array s__FireblastChild_level
constant integer si__FireblastMain=30
unit array s__FireblastMain_caster
integer array s__FireblastMain_level
real array s__FireblastMain_launchtime
group s__FireblastMain_g= CreateGroup()
unit s__FireblastMain_closestTarget
real s__FireblastMain_closestDistance
integer s__FireblastMain_current
constant integer si__BiGreenFire___greenMissile=31
unit array s__BiGreenFire___greenMissile_owner
integer array si__Table___GTable_type
trigger array st__Table___GTable_onDestroy
trigger st__xecollider_create
trigger st__xemissile__missile_create
trigger st__xemissile_create
trigger st__xehomingmissile_create
trigger array st___prototype11
string f__result_string
unit f__arg_unit1
real f__arg_real1
real f__arg_real2
real f__arg_real3
real f__arg_real4
real f__arg_real5
real f__arg_real6
integer f__arg_integer1
integer f__arg_this
integer f__result_integer

    integer rf__return_integer
    real rf__return_real
    boolean rf__return_boolean

endglobals
//globals from BoolexprUtils:
//endglobals from BoolexprUtils
//globals from BoundSentinel:
//endglobals from BoundSentinel
//globals from Table:
        //Feel free to change max instances if necessary, it will only affect allocation
        //speed which shouldn't matter that much.

    //=========================================================
//endglobals from Table
//globals from xeSandBox:
//endglobals from xeSandBox
//globals from xebasic:
//endglobals from xebasic
//globals from DemoMap:











//endglobals from DemoMap
//globals from xecast:
    //this is a lot, unless you leak xecast objects (which is a bad thing)
    
    
    //don't allow to keep more than DUMMY_STACK_LIMIT innactive dummy units :
    
    // If your map does not give visibility to all players, or
    // for other reasons, you might want xecast to work on
    // units that are not visible to the player, in that case
    // change this to true, else it is just a performance loss.

    //When AUTO_RESET_MANA_COOLDOWN is set to true, xecast will reset
    // the dummy unit's cooldown and mana before casting every spell.
    // it is a performance penalty, so if you are sure that all dummy spells
    // in your map got 0 mana and cooldown cost, you may set it to false.    
//endglobals from xecast
//globals from xedamage:
        
        // a low damage to do on units to test their damage factors for specific
        // attacktype/damagetype combos.
        // You'll need something as high as 20.0 to make it work well with armor resistances.
        // (Yes, you read it correctly, 20 ...
        //
        // If you use such a large value, there may be conflicts with some things relying on damage
        // (ie they are not away of the isDummyDamage tag that xedamage posseses.) which may be quite bad if you think about it...
        // then maybe it is better to change it to 0.01 ... then will work fine, just fine - but it will generally ignore armor - 
        // I am leaving it as 0.01 by default, because honestly, I'd rather make it ignore armor than have a lot of people sending me
        // rants about how they detect 20.0 damage where none is visible...
        // The maximum damage factor in the map. I think 3 is fine.
       

        //=======================================================
//endglobals from xedamage
//globals from xedummy:
        // The number of different angles at which the dummy units will be stored.

        // The total number of xe dummy units that will be preloaded on map initialization.
    
        // Don't allow to keep more than DUMMY_STACK_LIMIT inactive dummy units.
//endglobals from xedummy
//globals from xepreload:
//endglobals from xepreload
//globals from xefx:

    //Delay in order to show the death animation of the effect correctly when xefx is destroyed.
    //You may need to increase this if you are using effects with longer death animations.

    //The delay does not need to be exact so we do cleanup in batches instead of individually.
    //This determines how often the recycler runs, should be less than MIN_RECYCLE_DELAY.

    //if this is true and the xedummy library is present, units will be recycled instead of removed.
    
//endglobals from xefx
//globals from StormyDreams:
                                                        //Right now it is item damage bonus +6 , you can use any ability you want here.
                                                        //You may also leave a 0 to disable the synergy
                                                        //Having BONUS_SPELL_ID also alters the eye candy (see bellow)



       //
       // MODEL_PATH_(BONUS_)_MISSILE: The missile's model path
       // MODEL_PATH_(BONUS_)_FLASH  : The flash effect, it gets played constantly on the missile.
       //









       // Change if necessary:
//endglobals from StormyDreams
//globals from xecollider:

//endglobals from xecollider
//globals from xemissile:
//endglobals from xemissile
//globals from ChainInferno:
//endglobals from ChainInferno
//globals from FireNovaStrike:
//endglobals from FireNovaStrike
//globals from Fireblast:
        

        // Main missile visual settings:

        // Child missile visual settings:
//endglobals from Fireblast
    // Generated


//JASSHelper struct globals:



//Generated method caller for Table___GTable.onDestroy
function sc__Table___GTable_onDestroy takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__Table___GTable_onDestroy[1])
endfunction

//Generated allocator of Table___GTable
function rf__s__Table___GTable__allocate takes nothing returns nothing
 local integer this=si__Table___GTable_F
    if (this!=0) then
        set si__Table___GTable_F=si__Table___GTable_V[this]
    else
        set si__Table___GTable_I=si__Table___GTable_I+1
        set this=si__Table___GTable_I
    endif
    if (this>8100) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: Table___GTable")
set rf__return_integer= 0
return
    endif

    set si__Table___GTable_type[this]=1
    set si__Table___GTable_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__Table___GTable__allocate takes nothing returns integer
    call rf__s__Table___GTable__allocate()
    return rf__return_integer
endfunction

//Generated destructor of Table___GTable
function sc__Table___GTable_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: Table___GTable")
        return
    elseif (si__Table___GTable_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: Table___GTable")
        return
    endif
    set f__arg_this=this
    call TriggerEvaluate(st__Table___GTable_onDestroy[si__Table___GTable_type[this]])
    set si__Table___GTable_V[this]=si__Table___GTable_F
    set si__Table___GTable_F=this
endfunction

//Generated allocator of Table
function rf__s__Table__allocate takes nothing returns nothing
 local integer this=s__Table___GTable__allocate()
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__Table___GTable_type[this]=2
    set kthis=this

set rf__return_integer= this
return
endfunction
function s__Table__allocate takes nothing returns integer
    call rf__s__Table__allocate()
    return rf__return_integer
endfunction


//Generated allocator of StringTable
function rf__s__StringTable__allocate takes nothing returns nothing
 local integer this=s__Table___GTable__allocate()
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__Table___GTable_type[this]=3
    set kthis=this

set rf__return_integer= this
return
endfunction
function s__StringTable__allocate takes nothing returns integer
    call rf__s__StringTable__allocate()
    return rf__return_integer
endfunction


//Generated allocator of HandleTable
function rf__s__HandleTable__allocate takes nothing returns nothing
 local integer this=s__Table___GTable__allocate()
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__Table___GTable_type[this]=4
    set kthis=this

set rf__return_integer= this
return
endfunction
function s__HandleTable__allocate takes nothing returns integer
    call rf__s__HandleTable__allocate()
    return rf__return_integer
endfunction


//Generated allocator of DemoMap__itemdata
function rf__s__DemoMap__itemdata__allocate takes nothing returns nothing
 local integer this=si__DemoMap__itemdata_F
    if (this!=0) then
        set si__DemoMap__itemdata_F=si__DemoMap__itemdata_V[this]
    else
        set si__DemoMap__itemdata_I=si__DemoMap__itemdata_I+1
        set this=si__DemoMap__itemdata_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: DemoMap__itemdata")
set rf__return_integer= 0
return
    endif

    set si__DemoMap__itemdata_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__DemoMap__itemdata__allocate takes nothing returns integer
    call rf__s__DemoMap__itemdata__allocate()
    return rf__return_integer
endfunction

//Generated destructor of DemoMap__itemdata
function s__DemoMap__itemdata_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: DemoMap__itemdata")
        return
    elseif (si__DemoMap__itemdata_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: DemoMap__itemdata")
        return
    endif
    set si__DemoMap__itemdata_V[this]=si__DemoMap__itemdata_F
    set si__DemoMap__itemdata_F=this
endfunction

//Generated allocator of DemoMap__unitdata
function rf__s__DemoMap__unitdata__allocate takes nothing returns nothing
 local integer this=si__DemoMap__unitdata_F
    if (this!=0) then
        set si__DemoMap__unitdata_F=si__DemoMap__unitdata_V[this]
    else
        set si__DemoMap__unitdata_I=si__DemoMap__unitdata_I+1
        set this=si__DemoMap__unitdata_I
    endif
    if (this>1364) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: DemoMap__unitdata")
set rf__return_integer= 0
return
    endif
    set s__DemoMap__unitdata_items[this]=(this-1)*6
   set s__DemoMap__unitdata_stored[this]=false
    set si__DemoMap__unitdata_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__DemoMap__unitdata__allocate takes nothing returns integer
    call rf__s__DemoMap__unitdata__allocate()
    return rf__return_integer
endfunction

//Generated destructor of DemoMap__unitdata
function s__DemoMap__unitdata_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: DemoMap__unitdata")
        return
    elseif (si__DemoMap__unitdata_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: DemoMap__unitdata")
        return
    endif
    set si__DemoMap__unitdata_V[this]=si__DemoMap__unitdata_F
    set si__DemoMap__unitdata_F=this
endfunction

//Generated allocator of xecast
function rf__s__xecast__allocate takes nothing returns nothing
 local integer this=si__xecast_F
    if (this!=0) then
        set si__xecast_F=si__xecast_V[this]
    else
        set si__xecast_I=si__xecast_I+1
        set this=si__xecast_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: xecast")
set rf__return_integer= 0
return
    endif

   set s__xecast_abilityid[this]= 0
   set s__xecast_level[this]= 1
   set s__xecast_recycledelay[this]= 0.0
   set s__xecast_owningplayer[this]=Player(15)
   set s__xecast_customsource[this]=false
   set s__xecast_sourcez[this]=0.0
   set s__xecast_autodestroy[this]= false
   set s__xecast_oid[this]=0
    set si__xecast_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__xecast__allocate takes nothing returns integer
    call rf__s__xecast__allocate()
    return rf__return_integer
endfunction

//Generated destructor of xecast
function s__xecast_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: xecast")
        return
    elseif (si__xecast_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: xecast")
        return
    endif
    set si__xecast_V[this]=si__xecast_F
    set si__xecast_F=this
endfunction

//Generated allocator of xedamage
function rf__s__xedamage__allocate takes nothing returns nothing
 local integer this=si__xedamage_F
    if (this!=0) then
        set si__xedamage_F=si__xedamage_V[this]
    else
        set si__xedamage_I=si__xedamage_I+1
        set this=si__xedamage_I
    endif
    if (this>2729) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: xedamage")
set rf__return_integer= 0
return
    endif
    set s__xedamage_fct[this]=(this-1)*3
    set s__xedamage_fc[this]=(this-1)*3
    set s__xedamage_abifct[this]=(this-1)*3
    set s__xedamage_abifc[this]=(this-1)*3
   set s__xedamage_damageSelf[this]= false
   set s__xedamage_damageAllies[this]= false
   set s__xedamage_damageEnemies[this]= true
   set s__xedamage_damageNeutral[this]= true
   set s__xedamage_ranged[this]= true
   set s__xedamage_visibleOnly[this]= false
   set s__xedamage_deadOnly[this]= false
   set s__xedamage_alsoDead[this]= false
   set s__xedamage_damageTrees[this]= false
   set s__xedamage_dtype[this]= DAMAGE_TYPE_UNIVERSAL
   set s__xedamage_atype[this]= ATTACK_TYPE_NORMAL
   set s__xedamage_wtype[this]= WEAPON_TYPE_WHOKNOWS
   set s__xedamage_tag[this]= 0
   set s__xedamage_forceDamage[this]= false
   set s__xedamage_allyfactor[this]= 1.0
   set s__xedamage_use_ex[this]=  false
   set s__xedamage_ex_ut[this]= null
   set s__xedamage_use_req[this]= false
   set s__xedamage_req_ut[this]= null
   set s__xedamage_fcn[this]=0
   set s__xedamage_abifcn[this]=0
   set s__xedamage_usefx[this]= false
    set si__xedamage_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__xedamage__allocate takes nothing returns integer
    call rf__s__xedamage__allocate()
    return rf__return_integer
endfunction

//Generated destructor of xedamage
function s__xedamage_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: xedamage")
        return
    elseif (si__xedamage_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: xedamage")
        return
    endif
    set si__xedamage_V[this]=si__xedamage_F
    set si__xedamage_F=this
endfunction

//Generated method caller for xemissile__eventHandler.onHit
function sc__xemissile__eventHandler_onHit takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__xemissile__eventHandler_onHit[si__xemissile__eventHandler_type[this]])
endfunction

//Generated method executor for xemissile__eventHandler.onHit
function sx__xemissile__eventHandler_onHit takes integer this returns nothing
    set f__arg_this=this
    call TriggerExecute(st__xemissile__eventHandler_onHit[si__xemissile__eventHandler_type[this]])
endfunction

//Generated method caller for xemissile__eventHandler.loopControl
function sc__xemissile__eventHandler_loopControl takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__xemissile__eventHandler_loopControl[si__xemissile__eventHandler_type[this]])
endfunction

//Generated method executor for xemissile__eventHandler.loopControl
function sx__xemissile__eventHandler_loopControl takes integer this returns nothing
    set f__arg_this=this
    call TriggerExecute(st__xemissile__eventHandler_loopControl[si__xemissile__eventHandler_type[this]])
endfunction
//Generated destructor of xemissile__eventHandler
function sc__xemissile__eventHandler_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: xemissile__eventHandler")
        return
    elseif (si__xemissile__eventHandler_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: xemissile__eventHandler")
        return
    endif
    set f__arg_this=this
    call TriggerEvaluate(st__xemissile__eventHandler_onDestroy[si__xemissile__eventHandler_type[this]])
    set si__xemissile__eventHandler_V[this]=si__xemissile__eventHandler_F
    set si__xemissile__eventHandler_F=this
endfunction

//Generated method caller for xecollider___eventHandler.onUnitHit
function sc__xecollider___eventHandler_onUnitHit takes integer this,unit hitTarget returns nothing
    set f__arg_this=this
    set f__arg_unit1=hitTarget
    call TriggerEvaluate(st__xecollider___eventHandler_onUnitHit[si__xecollider___eventHandler_type[this]])
endfunction

//Generated method executor for xecollider___eventHandler.onUnitHit
function sx__xecollider___eventHandler_onUnitHit takes integer this,unit hitTarget returns nothing
    set f__arg_this=this
    set f__arg_unit1=hitTarget
    call TriggerExecute(st__xecollider___eventHandler_onUnitHit[si__xecollider___eventHandler_type[this]])
endfunction

//Generated method caller for xecollider___eventHandler.loopControl
function sc__xecollider___eventHandler_loopControl takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__xecollider___eventHandler_loopControl[si__xecollider___eventHandler_type[this]])
endfunction

//Generated method executor for xecollider___eventHandler.loopControl
function sx__xecollider___eventHandler_loopControl takes integer this returns nothing
    set f__arg_this=this
    call TriggerExecute(st__xecollider___eventHandler_loopControl[si__xecollider___eventHandler_type[this]])
endfunction
//Generated destructor of xecollider___eventHandler
function sc__xecollider___eventHandler_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: xecollider___eventHandler")
        return
    elseif (si__xecollider___eventHandler_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: xecollider___eventHandler")
        return
    endif
    set f__arg_this=this
    call TriggerEvaluate(st__xecollider___eventHandler_onDestroy[si__xecollider___eventHandler_type[this]])
    set si__xecollider___eventHandler_V[this]=si__xecollider___eventHandler_F
    set si__xecollider___eventHandler_F=this
endfunction

//Generated allocator of StormyDreams___throw
function rf__s__StormyDreams___throw__allocate takes nothing returns nothing
 local integer this=si__StormyDreams___throw_F
    if (this!=0) then
        set si__StormyDreams___throw_F=si__StormyDreams___throw_V[this]
    else
        set si__StormyDreams___throw_I=si__StormyDreams___throw_I+1
        set this=si__StormyDreams___throw_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: StormyDreams___throw")
set rf__return_integer= 0
return
    endif

   set s__StormyDreams___throw_donetimes[this]=0
   set s__StormyDreams___throw_remaining[this]=0
   set s__StormyDreams___throw_tog[this]=0
   set s__StormyDreams___throw_stop[this]=false
    set si__StormyDreams___throw_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__StormyDreams___throw__allocate takes nothing returns integer
    call rf__s__StormyDreams___throw__allocate()
    return rf__return_integer
endfunction

//Generated destructor of StormyDreams___throw
function s__StormyDreams___throw_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: StormyDreams___throw")
        return
    elseif (si__StormyDreams___throw_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: StormyDreams___throw")
        return
    endif
    set si__StormyDreams___throw_V[this]=si__StormyDreams___throw_F
    set si__StormyDreams___throw_F=this
endfunction

//Generated allocator of StormyDreams___missile
function rf__s__StormyDreams___missile__allocate takes nothing returns nothing
 local integer this=si__StormyDreams___missile_F
    if (this!=0) then
        set si__StormyDreams___missile_F=si__StormyDreams___missile_V[this]
    else
        set si__StormyDreams___missile_I=si__StormyDreams___missile_I+1
        set this=si__StormyDreams___missile_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: StormyDreams___missile")
set rf__return_integer= 0
return
    endif

   set s__StormyDreams___missile_s[this]=0
   set s__StormyDreams___missile_inc[this]=0.01
   set s__StormyDreams___missile_flashtime[this]=0
    set si__StormyDreams___missile_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__StormyDreams___missile__allocate takes nothing returns integer
    call rf__s__StormyDreams___missile__allocate()
    return rf__return_integer
endfunction

//Generated destructor of StormyDreams___missile
function s__StormyDreams___missile_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: StormyDreams___missile")
        return
    elseif (si__StormyDreams___missile_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: StormyDreams___missile")
        return
    endif
    set si__StormyDreams___missile_V[this]=si__StormyDreams___missile_F
    set si__StormyDreams___missile_F=this
endfunction

//Generated allocator of xefx
function rf__s__xefx__allocate takes nothing returns nothing
 local integer this=si__xefx_F
    if (this!=0) then
        set si__xefx_F=si__xefx_V[this]
    else
        set si__xefx_I=si__xefx_I+1
        set this=si__xefx_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: xefx")
set rf__return_integer= 0
return
    endif

   set s__xefx_tag[this]=0
   set s__xefx_fx[this]=null
   set s__xefx_zang[this]=0.0
   set s__xefx_r[this]=255
   set s__xefx_g[this]=255
   set s__xefx_b[this]=255
   set s__xefx_a[this]=255
   set s__xefx_abil[this]=0
    set si__xefx_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__xefx__allocate takes nothing returns integer
    call rf__s__xefx__allocate()
    return rf__return_integer
endfunction

//Generated destructor of xefx
function s__xefx_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: xefx")
        return
    elseif (si__xefx_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: xefx")
        return
    endif
    set si__xefx_V[this]=si__xefx_F
    set si__xefx_F=this
endfunction

//Generated allocator of xefx___recyclebin
function rf__s__xefx___recyclebin__allocate takes nothing returns nothing
 local integer this=si__xefx___recyclebin_F
    if (this!=0) then
        set si__xefx___recyclebin_F=si__xefx___recyclebin_V[this]
    else
        set si__xefx___recyclebin_I=si__xefx___recyclebin_I+1
        set this=si__xefx___recyclebin_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: xefx___recyclebin")
set rf__return_integer= 0
return
    endif

   set s__xefx___recyclebin_next[this]=0
    set si__xefx___recyclebin_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__xefx___recyclebin__allocate takes nothing returns integer
    call rf__s__xefx___recyclebin__allocate()
    return rf__return_integer
endfunction

//Generated destructor of xefx___recyclebin
function s__xefx___recyclebin_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: xefx___recyclebin")
        return
    elseif (si__xefx___recyclebin_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: xefx___recyclebin")
        return
    endif
    set si__xefx___recyclebin_V[this]=si__xefx___recyclebin_F
    set si__xefx___recyclebin_F=this
endfunction

//Generated allocator of xedummy___xedummy
function rf__s__xedummy___xedummy__allocate takes nothing returns nothing
 local integer this=si__xedummy___xedummy_F
    if (this!=0) then
        set si__xedummy___xedummy_F=si__xedummy___xedummy_V[this]
    else
        set si__xedummy___xedummy_I=si__xedummy___xedummy_I+1
        set this=si__xedummy___xedummy_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: xedummy___xedummy")
set rf__return_integer= 0
return
    endif

    set si__xedummy___xedummy_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__xedummy___xedummy__allocate takes nothing returns integer
    call rf__s__xedummy___xedummy__allocate()
    return rf__return_integer
endfunction

//Generated destructor of xedummy___xedummy
function s__xedummy___xedummy_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: xedummy___xedummy")
        return
    elseif (si__xedummy___xedummy_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: xedummy___xedummy")
        return
    endif
    set si__xedummy___xedummy_V[this]=si__xedummy___xedummy_F
    set si__xedummy___xedummy_F=this
endfunction

//Generated method caller for xemissile__missile.create
function sc__xemissile__missile_create takes real x,real y,real z,real a returns integer
    set f__arg_real1=x
    set f__arg_real2=y
    set f__arg_real3=z
    set f__arg_real4=a
    call TriggerEvaluate(st__xemissile__missile_create)
 return f__result_integer
endfunction

//Generated allocator of xemissile__missile
function rf__s__xemissile__missile__allocate takes nothing returns nothing
 local integer kthis
 local integer this=si__xemissile__eventHandler_F
    if (this!=0) then
        set si__xemissile__eventHandler_F=si__xemissile__eventHandler_V[this]
    else
        set si__xemissile__eventHandler_I=si__xemissile__eventHandler_I+1
        set this=si__xemissile__eventHandler_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: xemissile__missile")
set rf__return_integer= 0
return
    endif

    set si__xemissile__eventHandler_type[this]=24
    set kthis=this

   set s__xemissile__missile_mvxy[this]= 1.0
   set s__xemissile__missile_tx[this]= 0.0
   set s__xemissile__missile_ty[this]= 0.0
   set s__xemissile__missile_tz[this]= 0.0
   set s__xemissile__missile_tu[this]= null
   set s__xemissile__missile_zoffset[this]= 0.0
   set s__xemissile__missile_update[this]= true
   set s__xemissile__missile_launched[this]= false
   set s__xemissile__missile_dead[this]= false
   set s__xemissile__missile_silent[this]=false
    set si__xemissile__eventHandler_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__xemissile__missile__allocate takes nothing returns integer
    call rf__s__xemissile__missile__allocate()
    return rf__return_integer
endfunction


//Generated method caller for xecollider.create
function sc__xecollider_create takes real x,real y,real dir returns integer
    set f__arg_real1=x
    set f__arg_real2=y
    set f__arg_real3=dir
    call TriggerEvaluate(st__xecollider_create)
 return f__result_integer
endfunction

//Generated allocator of xecollider
function rf__s__xecollider__allocate takes nothing returns nothing
 local integer kthis
 local integer this=si__xecollider___eventHandler_F
    if (this!=0) then
        set si__xecollider___eventHandler_F=si__xecollider___eventHandler_V[this]
    else
        set si__xecollider___eventHandler_I=si__xecollider___eventHandler_I+1
        set this=si__xecollider___eventHandler_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: xecollider")
set rf__return_integer= 0
return
    endif

    set si__xecollider___eventHandler_type[this]=22
    set kthis=this

   set s__xecollider_expirationTime[this]= xecollider___DEFAULT_EXPIRATION_TIME
   set s__xecollider_speed[this]= 0.0
   set s__xecollider_acceleration[this]= 0.0
   set s__xecollider_maxSpeed[this]= xecollider___DEFAULT_MAX_SPEED
   set s__xecollider_minSpeed[this]= 0.0
   set s__xecollider_angleSpeed[this]= 0.0
   set s__xecollider_silent[this]= false
   set s__xecollider_dead[this]=false
   set s__xecollider_csize[this]= xecollider___DEFAULT_COLLISION_SIZE
   set s__xecollider_angleMode[this]=0
   set s__xecollider_homingTargetUnit[this]= null
    set si__xecollider___eventHandler_V[this]=-1
set rf__return_integer= this
return
endfunction
function s__xecollider__allocate takes nothing returns integer
    call rf__s__xecollider__allocate()
    return rf__return_integer
endfunction


//Generated method caller for BiGreenFire___greenMissile.onUnitHit
function sc__BiGreenFire___greenMissile_onUnitHit takes integer this,unit target returns nothing
    set f__arg_this=this
    set f__arg_unit1=target
    call TriggerEvaluate(st__xecollider___eventHandler_onUnitHit[31])
endfunction

//Generated allocator of BiGreenFire___greenMissile
function rf__s__BiGreenFire___greenMissile__allocate takes real x,real y,real dir returns nothing
 local integer this=sc__xecollider_create(x,y,dir)
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__xecollider___eventHandler_type[this]=31
    set kthis=this

set rf__return_integer= this
return
endfunction
function s__BiGreenFire___greenMissile__allocate takes real x,real y,real dir returns integer
    call rf__s__BiGreenFire___greenMissile__allocate(x,y,dir)
    return rf__return_integer
endfunction


//Generated method caller for xemissile.create
function sc__xemissile_create takes real x,real y,real z,real tx,real ty,real tz returns integer
    set f__arg_real1=x
    set f__arg_real2=y
    set f__arg_real3=z
    set f__arg_real4=tx
    set f__arg_real5=ty
    set f__arg_real6=tz
    call TriggerEvaluate(st__xemissile_create)
 return f__result_integer
endfunction

//Generated allocator of xemissile
function rf__s__xemissile__allocate takes real x,real y,real z,real a returns nothing
 local integer this=sc__xemissile__missile_create(x,y,z,a)
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__xemissile__eventHandler_type[this]=25
    set kthis=this

set rf__return_integer= this
return
endfunction
function s__xemissile__allocate takes real x,real y,real z,real a returns integer
    call rf__s__xemissile__allocate(x,y,z,a)
    return rf__return_integer
endfunction


//Generated method caller for xehomingmissile.create
function sc__xehomingmissile_create takes real x,real y,real z,unit target,real zoffset returns integer
    set f__arg_real1=x
    set f__arg_real2=y
    set f__arg_real3=z
    set f__arg_unit1=target
    set f__arg_real4=zoffset
    call TriggerEvaluate(st__xehomingmissile_create)
 return f__result_integer
endfunction

//Generated allocator of xehomingmissile
function rf__s__xehomingmissile__allocate takes real x,real y,real z,real tx,real ty,real tz returns nothing
 local integer this=sc__xemissile_create(x,y,z,tx,ty,tz)
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__xemissile__eventHandler_type[this]=26
    set kthis=this

set rf__return_integer= this
return
endfunction
function s__xehomingmissile__allocate takes real x,real y,real z,real tx,real ty,real tz returns integer
    call rf__s__xehomingmissile__allocate(x,y,z,tx,ty,tz)
    return rf__return_integer
endfunction


//Generated method caller for ChainInferno__missile.onUnitHit
function sc__ChainInferno__missile_onUnitHit takes integer this,unit hitUnit returns nothing
    set f__arg_this=this
    set f__arg_unit1=hitUnit
    call TriggerEvaluate(st__xecollider___eventHandler_onUnitHit[27])
endfunction

//Generated allocator of ChainInferno__missile
function rf__s__ChainInferno__missile__allocate takes real x,real y,real dir returns nothing
 local integer this=sc__xecollider_create(x,y,dir)
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__xecollider___eventHandler_type[this]=27
    set kthis=this

   set s__ChainInferno__missile_targetCount[this]=0
   set s__ChainInferno__missile_time[this]=0
set rf__return_integer= this
return
endfunction
function s__ChainInferno__missile__allocate takes real x,real y,real dir returns integer
    call rf__s__ChainInferno__missile__allocate(x,y,dir)
    return rf__return_integer
endfunction


//Generated method caller for FireNovaStrike__FireBolt.onUnitHit
function sc__FireNovaStrike__FireBolt_onUnitHit takes integer this,unit hitunit returns nothing
    set f__arg_this=this
    set f__arg_unit1=hitunit
    call TriggerEvaluate(st__xecollider___eventHandler_onUnitHit[28])
endfunction

//Generated method caller for FireNovaStrike__FireBolt.onDestroy
function sc__FireNovaStrike__FireBolt_onDestroy takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__xecollider___eventHandler_onDestroy[28])
endfunction

//Generated method caller for FireNovaStrike__FireBolt.loopControl
function sc__FireNovaStrike__FireBolt_loopControl takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__xecollider___eventHandler_loopControl[28])
endfunction

//Generated allocator of FireNovaStrike__FireBolt
function rf__s__FireNovaStrike__FireBolt__allocate takes real x,real y,real dir returns nothing
 local integer this=sc__xecollider_create(x,y,dir)
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__xecollider___eventHandler_type[this]=28
    set kthis=this

set rf__return_integer= this
return
endfunction
function s__FireNovaStrike__FireBolt__allocate takes real x,real y,real dir returns integer
    call rf__s__FireNovaStrike__FireBolt__allocate(x,y,dir)
    return rf__return_integer
endfunction


//Generated method caller for FireblastChild.onHit
function sc__FireblastChild_onHit takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__xemissile__eventHandler_onHit[29])
endfunction

//Generated allocator of FireblastChild
function rf__s__FireblastChild__allocate takes real x,real y,real z,unit target,real zoffset returns nothing
 local integer this=sc__xehomingmissile_create(x,y,z,target,zoffset)
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__xemissile__eventHandler_type[this]=29
    set kthis=this

set rf__return_integer= this
return
endfunction
function s__FireblastChild__allocate takes real x,real y,real z,unit target,real zoffset returns integer
    call rf__s__FireblastChild__allocate(x,y,z,target,zoffset)
    return rf__return_integer
endfunction


//Generated method caller for FireblastMain.loopControl
function sc__FireblastMain_loopControl takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__xemissile__eventHandler_loopControl[30])
endfunction

//Generated method caller for FireblastMain.onHit
function sc__FireblastMain_onHit takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__xemissile__eventHandler_onHit[30])
endfunction

//Generated allocator of FireblastMain
function rf__s__FireblastMain__allocate takes real x,real y,real z,real tx,real ty,real tz returns nothing
 local integer this=sc__xemissile_create(x,y,z,tx,ty,tz)
 local integer kthis
    if(this==0) then
set rf__return_integer= 0
return
    endif
    set si__xemissile__eventHandler_type[this]=30
    set kthis=this

   set s__FireblastMain_launchtime[this]= 0.0
set rf__return_integer= this
return
endfunction
function s__FireblastMain__allocate takes real x,real y,real z,real tx,real ty,real tz returns integer
    call rf__s__FireblastMain__allocate(x,y,z,tx,ty,tz)
    return rf__return_integer
endfunction

function sc___prototype11_execute takes integer i,integer a1 returns nothing
    set f__arg_integer1=a1

    call TriggerExecute(st___prototype11[i])
endfunction
function sc___prototype11_evaluate takes integer i,integer a1 returns string
    set f__arg_integer1=a1

    call TriggerEvaluate(st___prototype11[i])
 return f__result_string
endfunction

//library BoolexprUtils

    function BoolexprUtils___rettrue takes nothing returns boolean
        return true
    endfunction

    function BoolexprUtils___retfalse takes nothing returns boolean
        return false
    endfunction

    function BoolexprUtils___init takes nothing returns nothing
        set BOOLEXPR_TRUE=Condition(function BoolexprUtils___rettrue)
        set BOOLEXPR_FALSE=Condition(function BoolexprUtils___retfalse)
    endfunction

//endlibrary BoolexprUtils
//library BoundSentinel
//*************************************************
//* BoundSentinel
//* -------------
//*  Don't leave your units unsupervised, naughty
//* them may try to get out of the map bounds and
//* crash your game.
//*
//*  To implement, just get a vJass compiler and
//* copy this library/trigger to your map.
//*
//*************************************************

//==================================================

   //=========================================================================================

   //=======================================================================
   function BoundSentinel__dis takes nothing returns boolean
    local unit u=GetTriggerUnit()
    local real x=GetUnitX(u)
    local real y=GetUnitY(u)

       if ( x > BoundSentinel__maxx ) then
           set x=BoundSentinel__maxx
       elseif ( x < BoundSentinel__minx ) then
           set x=BoundSentinel__minx
       endif
       if ( y > BoundSentinel__maxy ) then
           set y=BoundSentinel__maxy
       elseif ( y < BoundSentinel__miny ) then
           set y=BoundSentinel__miny
       endif
       call SetUnitX(u, x)
       call SetUnitY(u, y)
    set u=null
    return false
   endfunction

   function BoundSentinel__init takes nothing returns nothing
    local trigger t= CreateTrigger()
    local region r= CreateRegion()
    local rect map
    local rect rc

       if BoundSentinel__ALLOW_OUTSIDE_PLAYABLE_MAP_AREA then
          set map=GetWorldBounds()
       else
          set map=bj_mapInitialPlayableArea
       endif

       set BoundSentinel__minx=GetRectMinX(map)
       set BoundSentinel__miny=GetRectMinY(map)
       set BoundSentinel__maxx=GetRectMaxX(map)
       set BoundSentinel__maxy=GetRectMaxY(map)
       set rc=Rect(BoundSentinel__minx, BoundSentinel__miny, BoundSentinel__maxx, BoundSentinel__maxy)
       call RegionAddRect(r, rc)
       call RemoveRect(rc)
       if BoundSentinel__ALLOW_OUTSIDE_PLAYABLE_MAP_AREA then
          call RemoveRect(map)
       endif

       call TriggerRegisterLeaveRegion(t, r, null)
       call TriggerAddCondition(t, Condition(function BoundSentinel__dis))

    set rc=null
    set map=null
   endfunction

//endlibrary BoundSentinel
//library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//*   set t=Table.create() - instanceates a new table object
//*   call t.destroy()     - destroys it
//*   t[1234567]           - Get value for key 1234567
//*                          (zero if not assigned previously)
//*   set t[12341]=32      - Assigning it.
//*   call t.flush(12341)  - Flushes the stored value, so it
//*                          doesn't use any more memory
//*   t.exists(32)         - Was key 32 assigned? Notice
//*                          that flush() unassigns values.
//*   call t.reset()       - Flushes the whole contents of the
//*                          Table.
//*
//*   call t.destroy()     - Does reset() and also recycles the id.
//*
//*   If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//*  You can use Table on structs' onInit  if the struct is
//* placed in a library that requires Table or outside a library.
//*
//*  You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//*  set Table["thisstring"][ 7 ] = 2
//*  set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************

//=============================================================


        function s__Table___GTable_reset takes integer this returns nothing
            call FlushChildHashtable(Table___ht, (this))
        endfunction

        function s__Table___GTable_onDestroy takes integer this returns nothing
            call FlushChildHashtable(Table___ht, ((this))) // INLINED!!
        endfunction

        //=============================================================
        // initialize it all.
        //
        function s__Table___GTable_onInit takes nothing returns nothing
            set Table___ht=InitHashtable()
        endfunction


    //Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.

//textmacro instance: Table__make("Table","integer","key" )

        function s__Table__getindex takes integer this,integer key returns integer
            return LoadInteger(Table___ht, (this), key)
        endfunction

        function s__Table__setindex takes integer this,integer key,integer value returns nothing
            call SaveInteger(Table___ht, (this), key, value)
        endfunction

        function s__Table_flush takes integer this,integer key returns nothing
            call RemoveSavedInteger(Table___ht, (this), key)
        endfunction

        function s__Table_exists takes integer this,integer key returns boolean
            return HaveSavedInteger(Table___ht, (this), key)
        endfunction

        function s__Table_flush2D takes string firstkey returns nothing
            call FlushChildHashtable(Table___ht, (((- StringHash(firstkey))))) // INLINED!!
        endfunction

        function s__Table__staticgetindex takes string firstkey returns integer
            return (- StringHash(firstkey))
        endfunction

//end of: Table__make("Table","integer","key" )
//textmacro instance: Table__make("StringTable","string", "StringHash(key)" )

        function s__StringTable__getindex takes integer this,string key returns integer
            return LoadInteger(Table___ht, (this), StringHash(key))
        endfunction

        function s__StringTable__setindex takes integer this,string key,integer value returns nothing
            call SaveInteger(Table___ht, (this), StringHash(key), value)
        endfunction

        function s__StringTable_flush takes integer this,string key returns nothing
            call RemoveSavedInteger(Table___ht, (this), StringHash(key))
        endfunction

        function s__StringTable_exists takes integer this,string key returns boolean
            return HaveSavedInteger(Table___ht, (this), StringHash(key))
        endfunction

        function s__StringTable_flush2D takes string firstkey returns nothing
            call FlushChildHashtable(Table___ht, (((- StringHash(firstkey))))) // INLINED!!
        endfunction

        function s__StringTable__staticgetindex takes string firstkey returns integer
            return (- StringHash(firstkey))
        endfunction

//end of: Table__make("StringTable","string", "StringHash(key)" )
//textmacro instance: Table__make("HandleTable","handle","GetHandleId(key)" )

        function s__HandleTable__getindex takes integer this,handle key returns integer
            return LoadInteger(Table___ht, (this), GetHandleId(key))
        endfunction

        function s__HandleTable__setindex takes integer this,handle key,integer value returns nothing
            call SaveInteger(Table___ht, (this), GetHandleId(key), value)
        endfunction

        function s__HandleTable_flush takes integer this,handle key returns nothing
            call RemoveSavedInteger(Table___ht, (this), GetHandleId(key))
        endfunction

        function s__HandleTable_exists takes integer this,handle key returns boolean
            return HaveSavedInteger(Table___ht, (this), GetHandleId(key))
        endfunction

        function s__HandleTable_flush2D takes string firstkey returns nothing
            call FlushChildHashtable(Table___ht, (((- StringHash(firstkey))))) // INLINED!!
        endfunction

        function s__HandleTable__staticgetindex takes string firstkey returns integer
            return (- StringHash(firstkey))
        endfunction

//end of: Table__make("HandleTable","handle","GetHandleId(key)" )


//endlibrary Table
//library xeSandBox

//endlibrary xeSandBox
//library xebasic
//**************************************************************************
//
// xebasic 0.4
// =======
// XE_DUMMY_UNITID : Rawcode of the dummy unit in your map. It should
//                   use the dummy.mdx model, so remember to import it as
//                   well, just use copy&paste to copy the dummy from the
//                   xe map to yours, then change the rawcode.
//
// XE_HEIGHT_ENABLER: Medivh's raven form ability, you may need to change
//                    this rawcode to another spell that morphs into a flier
//                    in case you modified medivh's spell in your map.
//
// XE_TREE_RECOGNITION: The ancients' Eat tree ability, same as with medivh
//                      raven form, you might have to change it.
//
// XE_ANIMATION_PERIOD: The global period of animation used by whatever
//                      timer that depends on it, if you put a low value
//                      the movement will look good but it may hurt your
//                      performance, if instead you use a high value it
//                      will not lag but will be fast.
//
// XE_MAX_COLLISION_SIZE: The maximum unit collision size in your map, if
//                        you got a unit bigger than 197.0 it would be
//                        a good idea to update this constant, since some
//                        enums will not find it. Likewise, if none of
//                        your units can go bellow X and X is much smaller
//                        than 197.0, it would be a good idea to update
//                        as well, since it will improve the performance
//                        those enums.
//
// Notice you probably don't have to update this library, unless I specify
// there are new constants which would be unlikely. 
//
//**************************************************************************

//===========================================================================


//endlibrary xebasic
//library DemoMap

function Credit takes nothing returns string
return "\n|cffffff10XE 0.9\n|cff00cccc*** Spells by: |cff0000ffVexorian.|r\n|cff00cccc*** Turtle Rock Map by: |cff0000ffBlizzard|r\n\nGive credit if you use it in your map.\n"
endfunction

function DemoMap__GetItemUserData takes item it returns integer
    return (LoadInteger(Table___ht, (((- StringHash(("meh"))))), GetHandleId((it)))) // INLINED!!
endfunction
function DemoMap__SetItemUserData takes item it,integer x returns nothing
    call SaveInteger(Table___ht, (((- StringHash(("meh"))))), GetHandleId((it)), ( x)) // INLINED!!
endfunction



function DemoMap__setupItems takes nothing returns nothing
    set DemoMap__CREATE_ITEMS[0]='I001'
    set DemoMap__CREATE_ITEMS[1]='I002'
    set DemoMap__CREATE_ITEMS[2]='I003'
    set DemoMap__CREATE_ITEMS[3]='I004'
    set DemoMap__CREATE_ITEMS_N=4
endfunction


function DemoMapFilter_IsHero takes nothing returns boolean
 return IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO)
endfunction

function DemoMap_H2I takes handle h returns integer
   return GetHandleId(h)
endfunction

//Demo map is err, a demo map, so we should be freely use UserDatas on creeps since no decent system would use them on public objects

function DemoMap__SetupEnumItem takes nothing returns nothing
 local item e=GetEnumItem()
 local integer id= s__DemoMap__itemdata__allocate()

    set s__DemoMap__itemdata_sx[id]=GetItemX(e)
    set s__DemoMap__itemdata_sy[id]=GetItemY(e)
    set s__DemoMap__itemdata_sb[id]=true

    call SaveInteger(Table___ht, (((- StringHash(("meh"))))), GetHandleId(((e ))), ( ( (id)))) // INLINED!!
 set e=null
endfunction

function DemoMap__RestoreItemAfterUse takes nothing returns nothing
 local item it=GetManipulatedItem()
 local integer k= ((LoadInteger(Table___ht, (((- StringHash(("meh"))))), GetHandleId(((it)))))) // INLINED!!
 local real x= s__DemoMap__itemdata_sx[k]
 local real y= s__DemoMap__itemdata_sy[k]
 local integer i=GetItemTypeId(it)
    call TriggerSleepAction(0)
    if not ( s__DemoMap__itemdata_sb[k] ) or ( k == 0 ) then
    elseif not IsItemOwned(it) and GetWidgetLife(it) <= 0 and ( StringLength(GetItemName(it)) > 0 or GetTriggerEventId() == EVENT_PLAYER_UNIT_USE_ITEM ) then
        call PolledWait(3)
        call SaveInteger(Table___ht, (((- StringHash(("meh"))))), GetHandleId(((CreateItem(i, x, y) ))), ( ( (k)))) // INLINED!!
    endif
 set it=null
endfunction


function SpawnFootmen takes real x,real y,real angle,boolean showeyecandy returns nothing
 local integer a=0
    loop
        exitwhen a > 5
        if ( GetWidgetLife(DemoMap__footman[a]) < 0.405 ) or ( GetOwningPlayer(DemoMap__footman[a]) != Player(0) ) then
            set DemoMap__footman[a]=CreateUnit(Player(0), DemoMap__UNITID_SOLDIER, x, y, angle)
        else
            call DestroyEffect(AddSpecialEffect(DemoMap__MODELPATH_OUT, GetUnitX(DemoMap__footman[a]), GetUnitY(DemoMap__footman[a])))
            call SetUnitPosition(DemoMap__footman[a], x, y)
        endif
        if showeyecandy then
            call DestroyEffect(AddSpecialEffectTarget(DemoMap__MODELPATH_IN, DemoMap__footman[a], "origin"))
        endif
        set a=a + 1
    endloop
endfunction

function DemoMap__LevelUpDialog takes unit u returns nothing
 local dialog prompt=DialogCreate()
 local integer n=0
 local integer i=0
 local integer result=0
 local integer T=2
    call DialogSetMessage(prompt, "Choose Level")
    set DemoMap__trig[0]=CreateTrigger()
    call TriggerRegisterDialogEvent(DemoMap__trig[0], prompt)
    loop
        exitwhen n >= 6
        set n=n + 1
        set DemoMap__trig[n]=CreateTrigger()
        call TriggerRegisterDialogButtonEvent(DemoMap__trig[n], DialogAddButton(prompt, I2S(IMaxBJ(1, ( n - 1 ) * T)), 0))
    endloop
    call DialogDisplay(Player(0), prompt, true)
    loop
        exitwhen GetTriggerEvalCount(DemoMap__trig[0]) > 0
        call TriggerSleepAction(0)
    endloop
    set i=0
    call DialogClear(prompt)
    call DialogDestroy(prompt)
    set prompt=null
    loop
        exitwhen i > n
        if GetTriggerEvalCount(DemoMap__trig[i]) > 0 then
            set result=i
        endif
        call DestroyTrigger(DemoMap__trig[i])
        set DemoMap__trig[i]=null
        set i=i + 1
    endloop
    set result=IMaxBJ(1, ( result - 1 ) * T)
    if result < GetHeroLevel(u) then
        call DestroyEffect(AddSpecialEffectTarget(DemoMap__MODELPATH_RETRAINING, u, "origin"))
        call SetHeroLevelBJ(u, result, true)
        call ModifyHeroSkillPoints(u, bj_MODIFYMETHOD_SET, result)
    else
        call SetHeroLevelBJ(u, result, true)
    endif
endfunction


function DemoMapSpell takes nothing returns nothing
 local unit u=GetTriggerUnit()
 local integer s=GetSpellAbilityId()

    if ( GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_ENDCAST ) then
        if ( DemoMap__SuperMode ) then
            call SetUnitManaPercentBJ(u, 100)
            call UnitResetCooldown(u)
        endif
    elseif ( s == DemoMap__SPELLID_RESET ) then
        set DemoMap__Restores=DemoMap__Restores + 1
        if ( DemoMap__Restores == 2 ) then
            set DemoMap__SuperMode=true
            call BJDebugMsg(DemoMap__MSG_SUPERMODE)
        endif
        call SetUnitManaPercentBJ(u, 100)
        call UnitResetCooldown(u)
        call SetUnitLifePercentBJ(u, 100)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl", u, "origin"))
        call TriggerSleepAction(2.0)
        set DemoMap__Restores=DemoMap__Restores - 1
    elseif ( s == DemoMap__SPELLID_LEVELUP ) then
        call DemoMap__LevelUpDialog(u)
    elseif ( s == DemoMap__SPELLID_RAISEFOOTMEN ) then
        call SpawnFootmen(GetUnitX(u) + 300 * CosBJ(GetUnitFacing(u)) , GetUnitY(u) + 300 * SinBJ(GetUnitFacing(u)) , GetUnitFacing(u) , true)
    endif
     set u=null
endfunction

function DemoMap__AutoRevive takes nothing returns nothing
 local group g=GetUnitsSelectedAll(Player(0))
    call ReviveHero(GetTriggerUnit(), DemoMap__START_LOCATION_X, DemoMap__START_LOCATION_Y, true)
    call SetUnitColor(GetTriggerUnit(), ConvertPlayerColor(DemoMap__COLORID_PLAYER))
    if FirstOfGroup(g) == null then
        call SetCameraPosition(DemoMap__START_LOCATION_X, DemoMap__START_LOCATION_Y)
        call SelectUnit(GetTriggerUnit(), true)
    endif
    call DestroyGroup(g)
 set g=null
endfunction


function DemoMap__RespawnCreep takes nothing returns nothing
endfunction
function DemoMap__DemoMapIsCreep takes nothing returns boolean
 return IsUnitOwnedByPlayer(GetFilterUnit(), Player(12))
endfunction

function DemoMap__InitCreeps takes nothing returns nothing
 local group aux=CreateGroup()
 local group aux2=CreateGroup()
 local group c
 local unit u
 local integer k
 local integer a=0

    call GroupClear(DemoMap__enumgroup)
    call GroupEnumUnitsOfPlayer(DemoMap__enumgroup, Player(12), BOOLEXPR_TRUE)
    loop
        set u=FirstOfGroup(DemoMap__enumgroup)
        exitwhen u == null
        call GroupRemoveUnit(DemoMap__enumgroup, u)
        set c=CreateGroup()
        call GroupClear(aux)
        loop
            call GroupRemoveUnit(DemoMap__enumgroup, u)
            call GroupRemoveUnit(aux, u)
            
            if ( GetUnitUserData(u) == 0 ) then

                call GroupClear(aux2)
                call GroupEnumUnitsInRange(aux2, GetUnitX(u), GetUnitY(u), 500.0, BOOLEXPR_TRUE)
                call GroupAddGroup(aux2, aux)
                call GroupAddUnit(c, u)

                set k=s__DemoMap__unitdata__allocate()
                set s__DemoMap__unitdata_sx[k]=GetUnitX(u)
                set s__DemoMap__unitdata_sy[k]=GetUnitY(u)
                set s__DemoMap__unitdata_sf[k]=GetUnitFacing(u)
                set s__DemoMap__unitdata_stored[k]=true
                set s__DemoMap__unitdata_camp[k]=c

                call SetUnitUserData(u, (k))
                if IsUnitType(u, UNIT_TYPE_HERO) then
                    set a=0
                    loop
                        exitwhen a > 5
                        set s___DemoMap__unitdata_items[s__DemoMap__unitdata_items[k]+a]=GetItemTypeId(UnitItemInSlot(u, a))
                        set a=a + 1
                    endloop
                endif
            endif

            set u=FirstOfGroup(aux)
            exitwhen u == null
        endloop
    endloop
    call DestroyGroup(aux)
    call DestroyGroup(aux2)
    set aux=null
    set aux2=null
endfunction

function DemoMap__doNudge takes nothing returns nothing
    call NudgeObjectsInRect(Rect(DemoMap__START_LOCATION_X - 500.0, DemoMap__START_LOCATION_Y - 500.0, DemoMap__START_LOCATION_X + 500.0, DemoMap__START_LOCATION_Y + 500.0))
endfunction
function DemoMap__init2 takes nothing returns nothing
 local trigger t
 local unit u
 local integer cx
 local integer i
 local real dx
 local real dy

    set cx=3
    loop
        call CreateUnit(Player(12), 'ngrk', 0, 0, 0)
        set cx=cx - 1
        exitwhen ( cx == 0 )
    endloop
    set cx=1
    loop
        call CreateUnit(Player(12), 'ngst', 0, 0, 0)
        set cx=cx - 1
        exitwhen ( cx == 0 )
    endloop
    set cx=1
    loop
        call CreateUnit(Player(12), 'nggr', 0, 0, 0)
        set cx=cx - 1
        exitwhen ( cx == 0 )
    endloop
    call SetCameraPosition(DemoMap__START_LOCATION_X, DemoMap__START_LOCATION_Y)

    set DemoMap__enumgroup=CreateGroup()

    set DemoMap__MapSurface=( GetRectMaxX(bj_mapInitialPlayableArea) - GetRectMinX(bj_mapInitialPlayableArea) ) * ( GetRectMaxY(bj_mapInitialPlayableArea) - GetRectMinY(bj_mapInitialPlayableArea) )

    set u=CreateUnit(Player(0), DemoMap__UNITID_TESTHERO, DemoMap__START_LOCATION_X, DemoMap__START_LOCATION_Y, 0)

    set dx=GetRandomReal(- 100, 100)
    set dy=GetRandomReal(- 100, 100)
    set i=DemoMap__CREATE_ITEMS_N - 1
    loop
        exitwhen ( i < 0 )
        call CreateItem(DemoMap__CREATE_ITEMS[i], DemoMap__START_LOCATION_X + ( i + 3 ) * dx, DemoMap__START_LOCATION_Y + ( i + 3 ) * dy)
        set i=i - 1
    endloop



    call UnitAddItemToSlotById(u, DemoMap__ITEMID_ASSISTANT, 1)

    set u=CreateUnit(Player(0), DemoMap__UNITID_TESTHERO, DemoMap__START_LOCATION_X, DemoMap__START_LOCATION_Y, 0)

    call UnitAddItemToSlotById(u, DemoMap__ITEMID_ASSISTANT, 1)




//    call GroupEnumUnitsOfPlayer(enumgroup, Player(0), Condition(function SetupFilterPlayerUnit)  )

    //call CreateCasters(12)

    set bj_lastCreatedGameCache=InitGameCache("demomap.c")
    
    set t=CreateTrigger()
    call EnumItemsInRect(bj_mapInitialPlayableArea, BOOLEXPR_TRUE, function DemoMap__SetupEnumItem)
    call TriggerRegisterPlayerUnitEvent(t, Player(0), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
    call TriggerRegisterPlayerUnitEvent(t, Player(0), EVENT_PLAYER_UNIT_USE_ITEM, null)
    call TriggerAddAction(t, function DemoMap__RestoreItemAfterUse)

    set t=CreateTrigger()

    call DemoMap__InitCreeps()
    call TriggerRegisterPlayerUnitEvent(t, Player(12), EVENT_PLAYER_UNIT_DEATH, null)
    call TriggerAddAction(t, function DemoMap__RespawnCreep)
    set t=CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(t, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(t, Player(0), EVENT_PLAYER_UNIT_SPELL_ENDCAST, null)
    call TriggerAddAction(t, function DemoMapSpell)
    set t=CreateTrigger()
    call TriggerRegisterPlayerUnitEventSimple(t, Player(0), EVENT_PLAYER_HERO_REVIVABLE)
    call TriggerAddAction(t, function DemoMap__AutoRevive)
    set t=CreateTrigger()
    call TriggerAddAction(t, function Credit)

    call SpawnFootmen(DemoMap__START_LOCATION_X + 100 , DemoMap__START_LOCATION_Y + 100 , 0 , false)

    call SetPlayerColorBJ(Player(0), ConvertPlayerColor(DemoMap__COLORID_PLAYER), true)
    call SetPlayerColorBJ(Player(12), ConvertPlayerColor(DemoMap__COLORID_CREEPS), true)
    call SetPlayerColorBJ(Player(1), ConvertPlayerColor(DemoMap__COLORID_COMP), true)
    call SetPlayerName(Player(1), DemoMap__STRING_COMPNAME)
    call SetPlayerAllianceStateBJ(Player(1), Player(0), bj_ALLIANCE_UNALLIED)
    call SetPlayerAllianceStateBJ(Player(0), Player(1), bj_ALLIANCE_UNALLIED)
    call EnableCreepSleepBJ(false)
    call SetTimeOfDay(12)
    call SetTimeOfDayScalePercentBJ(0.00)
    //call FogMaskEnableOff()
    //call FogEnableOff()

    //call TimerStart(CreateTimer(), 0, false,  function doNudge)
set t=null
endfunction

function DemoMap__init takes nothing returns nothing
 local trigger t=CreateTrigger()
 local integer i=0
 local integer c=0
     call DemoMap__setupItems()
     call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 100000, ("\n|cffffff10XE 0.9\n|cff00cccc*** Spells by: |cff0000ffVexorian.|r\n|cff00cccc*** Turtle Rock Map by: |cff0000ffBlizzard|r\n\nGive credit if you use it in your map.\n")) // INLINED!!
    loop
        exitwhen ( i == 12 )
        if ( GetPlayerController(Player(i)) == MAP_CONTROL_USER ) and ( GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING ) then
            set c=c + 1
            if ( c == 2 ) then
            call BJDebugMsg("Sorry, no testing mode enabled")
                return
            endif
        endif
        set i=i + 1
    endloop

    set DemoMap__START_LOCATION_X=GetStartLocationX(GetPlayerStartLocation(Player(0)))
    set DemoMap__START_LOCATION_Y=GetStartLocationY(GetPlayerStartLocation(Player(0)))



    call TriggerAddAction(t, function DemoMap__init2)
    if ( DemoMap__AUTO ) then
        call TriggerExecute(t)
    else
       call TriggerRegisterPlayerChatEvent(t, Player(0), "iddqd", true)
    endif
    
 set t=null
endfunction


//endlibrary DemoMap
//library xecast
//******************************************************************************
// xecast 0.9
// ------
//  Because dummy casters REALLY ARE this complicated!
//
//******************************************************************************

//==============================================================================

//=========================================================================
// Please notice all textmacros in this library are considered private.
//  in other words: DON'T RUN THOSE TEXTMACROS!
//




                                       // This is, a time period before they get recycle.
                                       // For example, some spells are not instant, there is
                                       // also the problem with damaging spells, this recycle
                                       // delay must be large enough to contain all the time
                                       // in which the spell can do damage.


                                            //notice this can also affect what units are targeteable

    //==================================================================================================
    // You need an order id for the ability so the dummy unit is able to cast it, two ways to assign it
    //   set instance.orderid     = 288883            //would assign an integer orderid
    //   set instance.orderstring = "chainlightning"  //would assign an orderstring
    //                                                 (as those in the object editor)
    //
    function s__xecast__set_orderid takes integer this,integer v returns nothing
        set s__xecast_oid[this]=v
    endfunction
    function s__xecast__set_orderstring takes integer this,string s returns nothing
        set s__xecast_oid[this]=OrderId(s)
    endfunction

    //=================================================================================================
    // Finally, you can determine from which point to cast the ability: z is the height coordinate.
    //


    function s__xecast_setSourcePoint takes integer this,real x,real y,real z returns nothing
       set s__xecast_sourcex[this]=x
       set s__xecast_sourcey[this]=y
       set s__xecast_sourcez[this]=z
       set s__xecast_customsource[this]=true
    endfunction

    function s__xecast_setSourceLoc takes integer this,location loc,real z returns nothing
       set s__xecast_sourcex[this]=GetLocationX(loc)
       set s__xecast_sourcey[this]=GetLocationY(loc)
       set s__xecast_sourcez[this]=z
       set s__xecast_customsource[this]=true
    endfunction


    //========================================================================================================
    // you are always allowed to use .create() but you can also use createBasic which sets some things that
    // are usually necessary up.
    //
    function s__xecast_createBasic takes integer abilityID,integer orderid,player owner returns integer
     local integer r=s__xecast__allocate()
        if ( r == 0 ) then
             call BJDebugMsg("Warning: unbelievable but you actually used all xecast instances in your map! Please make sure you are not forgetting to destroy those what you create intensively, if that's not the case, then you'll have to increase xecast MAXINSTANCES")
        endif
        set s__xecast_oid[r]=orderid
        set s__xecast_abilityid[r]=abilityID
        set s__xecast_owningplayer[r]=owner
     return r
    endfunction

    //========================================================================================================
    // Just like the above one, but the instance will self destruct after a call to any cast method
    // (recommended)
    //
    function s__xecast_createBasicA takes integer abilityID,integer orderid,player owner returns integer
     local integer r=s__xecast__allocate()
        if ( r == 0 ) then
             call BJDebugMsg("Warning: unbelievable but you actually used all xecast instances in your map! Please make sure you are not forgetting to destroy those what you create intensively, if that's not the case, then you'll have to increase xecast MAXINSTANCES")
        endif
        set s__xecast_oid[r]=orderid
        set s__xecast_abilityid[r]=abilityID
        set s__xecast_owningplayer[r]=owner
        set s__xecast_autodestroy[r]=true
     return r
    endfunction

    //==========================================================================================================
    // Just like create, but the struct instance self destructs after a call to any cast method
    // (Recommended)
    //
    function s__xecast_createA takes nothing returns integer
     local integer r=s__xecast__allocate()
        set s__xecast_autodestroy[r]=true
     return r
    endfunction

    //==========================================================================================================
    // So, create the dummy, assign options and cast the skill!
    // .castOnTarget(u)       : If you want to hit a unit u with the ability, supports FORCE_INVISIBLE_CAST.
    // .castOnWidgetTarget(w) : If you want to hit a widget w with the ability.
    // .castOnPoint(x,y)      : If you want to hit a point (x,y) with the ability.
    // .castInPoint(x,y)      : For spells like warstomp which do not have a target.
    // .castOnAOE(x,y,radius) : Classic area of effect cast. Considers collision size.
    // .castOnGroup(g)        : Cast unit the unit group g, notice it will empty the group yet not destroy it.
    //

    //**********************************************************************************************************
    // The implementation of such methods follows: 




    //==========================================================================================================
    // private dorecycle method, sorry but I need this up here.
    //
    function s__xecast_dorecycle takes nothing returns nothing
     local unit u=s__xecast_recycle[0]
     local integer l
     local integer r
     local integer p
     local real lt
        call IssueImmediateOrder(u, "stop") // bugfix, see: http://www.wc3c.net/showpost.php?p=1131163&postcount=5
        call UnitRemoveAbility(u, GetUnitUserData(u))
        call SetUnitUserData(u, 0)
        call SetUnitFlyHeight(u, 0, 0)
        call PauseUnit(u, false)
        if ( s__xecast_top == xecast__DUMMY_STACK_LIMIT ) then
            call RemoveUnit(u)
        else
            set s__xecast_dummystack[s__xecast_top]=u
            set s__xecast_top=s__xecast_top + 1
        endif
        set s__xecast_rn=s__xecast_rn - 1
        if ( s__xecast_rn == 0 ) then
            return
        endif
        set p=0
        set lt=s__xecast_expiretime[s__xecast_rn]
        loop
            set l=p * 2 + 1
            exitwhen l >= s__xecast_rn
            set r=p * 2 + 2
            if ( r >= s__xecast_rn ) then
                if ( s__xecast_expiretime[l] < lt ) then
                    set s__xecast_expiretime[p]=s__xecast_expiretime[l]
                    set s__xecast_recycle[p]=s__xecast_recycle[l]
                    set p=l
                else
                    exitwhen true
                endif
            elseif ( lt <= s__xecast_expiretime[l] ) and ( lt <= s__xecast_expiretime[r] ) then
                exitwhen true
            elseif ( s__xecast_expiretime[l] < s__xecast_expiretime[r] ) then
                set s__xecast_expiretime[p]=s__xecast_expiretime[l]
                set s__xecast_recycle[p]=s__xecast_recycle[l]
                set p=l
            else
                set s__xecast_expiretime[p]=s__xecast_expiretime[r]
                set s__xecast_recycle[p]=s__xecast_recycle[r]
                set p=r
            endif
        endloop
        set s__xecast_recycle[p]=s__xecast_recycle[s__xecast_rn]
        set s__xecast_expiretime[p]=lt
        call TimerStart(s__xecast_T, s__xecast_expiretime[0] - TimerGetElapsed(s__xecast_gametime), false, function s__xecast_dorecycle)
    endfunction



    // Repetitive process and no inline implemented for large functions, so for now it is a textmacro:

    function s__xecast_castOnTarget takes integer this,unit target returns nothing
     local unit dummy
     local unit tar
//textmacro instance: xecast_allocdummy()
        if ( s__xecast_recycledelay[this] < xecast__EPSILON ) then
            set dummy=s__xecast_instantdummy
            call SetUnitOwner(dummy, s__xecast_owningplayer[this], false)
        elseif ( s__xecast_top > 0 ) then
            set s__xecast_top=s__xecast_top - 1
            set dummy=s__xecast_dummystack[s__xecast_top]
            call SetUnitOwner(dummy, s__xecast_owningplayer[this], false)
        else
            set dummy=CreateUnit(s__xecast_owningplayer[this], XE_DUMMY_UNITID, 0, 0, 0)
            call TriggerRegisterUnitEvent(s__xecast_abilityRemove, dummy, EVENT_UNIT_SPELL_ENDCAST)
            call UnitAddAbility(dummy, 'Aloc')
            call UnitAddAbility(dummy, XE_HEIGHT_ENABLER)
            call UnitRemoveAbility(dummy, XE_HEIGHT_ENABLER)
        endif
        call UnitAddAbility(dummy, s__xecast_abilityid[this])
//#         static if xecast__AUTO_RESET_MANA_COOLDOWN then
                call UnitResetCooldown(dummy)
                call SetUnitState(dummy, UNIT_STATE_MANA, 10000.0)
//#         endif
        if ( s__xecast_level[this] > 1 ) then
            call SetUnitAbilityLevel(dummy, s__xecast_abilityid[this], s__xecast_level[this])
        endif
//end of: xecast_allocdummy()
        if ( s__xecast_customsource[this] ) then
            call SetUnitX(dummy, s__xecast_sourcex[this])
            call SetUnitY(dummy, s__xecast_sourcey[this])
            call SetUnitFlyHeight(dummy, s__xecast_sourcez[this], 0.0)
        else
            call SetUnitX(dummy, GetWidgetX(target))
            call SetUnitY(dummy, GetWidgetY(target))
        endif
//#         static if  xecast__FORCE_INVISIBLE_CAST  then
//#             call UnitShareVision(target, .owningplayer, true)
//#             call IssueTargetOrderById(dummy,this.oid,target)
//#             call UnitShareVision(target, .owningplayer, false)
//#         else
                call IssueTargetOrderById(dummy, s__xecast_oid[this], target)
//#         endif

//textmacro instance: xecast_deallocdummy()
        if ( s__xecast_recycledelay[this] >= xecast__EPSILON ) then
            set s__xecast_cexpire=TimerGetElapsed(s__xecast_gametime) + s__xecast_recycledelay[this]
            set s__xecast_current=s__xecast_rn
            set s__xecast_rn=s__xecast_rn + 1
            loop
                exitwhen ( s__xecast_current == 0 )
                set s__xecast_cparent=( s__xecast_current - 1 ) / 2
                exitwhen ( s__xecast_expiretime[s__xecast_cparent] <= s__xecast_cexpire )
                set s__xecast_recycle[s__xecast_current]=s__xecast_recycle[s__xecast_cparent]
                set s__xecast_expiretime[s__xecast_current]=s__xecast_expiretime[s__xecast_cparent]
                set s__xecast_current=s__xecast_cparent
            endloop
            set s__xecast_expiretime[s__xecast_current]=s__xecast_cexpire
            set s__xecast_recycle[s__xecast_current]=dummy
            call SetUnitUserData(dummy, s__xecast_abilityid[this])
            call TimerStart(s__xecast_T, s__xecast_expiretime[0] - TimerGetElapsed(s__xecast_gametime), false, function s__xecast_dorecycle)
        else
            call SetUnitUserData(dummy, 0)
            call SetUnitFlyHeight(dummy, 0, 0)
            call UnitRemoveAbility(dummy, s__xecast_abilityid[this])
        endif
//end of: xecast_deallocdummy()
        if ( s__xecast_autodestroy[this] ) then
            call s__xecast_deallocate(this)
        endif
    endfunction

    //accepts units, items and destructables, if you know it is
    // a unit it is better to use castOnTarget since that would
    // be able to use FORCE_INVISIBLE_CAST if necessary.
    //
    function s__xecast_castOnWidgetTarget takes integer this,widget target returns nothing
     local unit dummy
     local unit tar
//textmacro instance: xecast_allocdummy()
        if ( s__xecast_recycledelay[this] < xecast__EPSILON ) then
            set dummy=s__xecast_instantdummy
            call SetUnitOwner(dummy, s__xecast_owningplayer[this], false)
        elseif ( s__xecast_top > 0 ) then
            set s__xecast_top=s__xecast_top - 1
            set dummy=s__xecast_dummystack[s__xecast_top]
            call SetUnitOwner(dummy, s__xecast_owningplayer[this], false)
        else
            set dummy=CreateUnit(s__xecast_owningplayer[this], XE_DUMMY_UNITID, 0, 0, 0)
            call TriggerRegisterUnitEvent(s__xecast_abilityRemove, dummy, EVENT_UNIT_SPELL_ENDCAST)
            call UnitAddAbility(dummy, 'Aloc')
            call UnitAddAbility(dummy, XE_HEIGHT_ENABLER)
            call UnitRemoveAbility(dummy, XE_HEIGHT_ENABLER)
        endif
        call UnitAddAbility(dummy, s__xecast_abilityid[this])
//#         static if xecast__AUTO_RESET_MANA_COOLDOWN then
                call UnitResetCooldown(dummy)
                call SetUnitState(dummy, UNIT_STATE_MANA, 10000.0)
//#         endif
        if ( s__xecast_level[this] > 1 ) then
            call SetUnitAbilityLevel(dummy, s__xecast_abilityid[this], s__xecast_level[this])
        endif
//end of: xecast_allocdummy()
        if ( s__xecast_customsource[this] ) then
            call SetUnitX(dummy, s__xecast_sourcex[this])
            call SetUnitY(dummy, s__xecast_sourcey[this])
            call SetUnitFlyHeight(dummy, s__xecast_sourcez[this], 0.0)
        else
            call SetUnitX(dummy, GetWidgetX(target))
            call SetUnitY(dummy, GetWidgetY(target))
        endif
        call IssueTargetOrderById(dummy, s__xecast_oid[this], target)

//textmacro instance: xecast_deallocdummy()
        if ( s__xecast_recycledelay[this] >= xecast__EPSILON ) then
            set s__xecast_cexpire=TimerGetElapsed(s__xecast_gametime) + s__xecast_recycledelay[this]
            set s__xecast_current=s__xecast_rn
            set s__xecast_rn=s__xecast_rn + 1
            loop
                exitwhen ( s__xecast_current == 0 )
                set s__xecast_cparent=( s__xecast_current - 1 ) / 2
                exitwhen ( s__xecast_expiretime[s__xecast_cparent] <= s__xecast_cexpire )
                set s__xecast_recycle[s__xecast_current]=s__xecast_recycle[s__xecast_cparent]
                set s__xecast_expiretime[s__xecast_current]=s__xecast_expiretime[s__xecast_cparent]
                set s__xecast_current=s__xecast_cparent
            endloop
            set s__xecast_expiretime[s__xecast_current]=s__xecast_cexpire
            set s__xecast_recycle[s__xecast_current]=dummy
            call SetUnitUserData(dummy, s__xecast_abilityid[this])
            call TimerStart(s__xecast_T, s__xecast_expiretime[0] - TimerGetElapsed(s__xecast_gametime), false, function s__xecast_dorecycle)
        else
            call SetUnitUserData(dummy, 0)
            call SetUnitFlyHeight(dummy, 0, 0)
            call UnitRemoveAbility(dummy, s__xecast_abilityid[this])
        endif
//end of: xecast_deallocdummy()
        if ( s__xecast_autodestroy[this] ) then
            call s__xecast_deallocate(this)
        endif
    endfunction



    function s__xecast_castOnPoint takes integer this,real x,real y returns nothing
     local unit dummy
//textmacro instance: xecast_allocdummy()
        if ( s__xecast_recycledelay[this] < xecast__EPSILON ) then
            set dummy=s__xecast_instantdummy
            call SetUnitOwner(dummy, s__xecast_owningplayer[this], false)
        elseif ( s__xecast_top > 0 ) then
            set s__xecast_top=s__xecast_top - 1
            set dummy=s__xecast_dummystack[s__xecast_top]
            call SetUnitOwner(dummy, s__xecast_owningplayer[this], false)
        else
            set dummy=CreateUnit(s__xecast_owningplayer[this], XE_DUMMY_UNITID, 0, 0, 0)
            call TriggerRegisterUnitEvent(s__xecast_abilityRemove, dummy, EVENT_UNIT_SPELL_ENDCAST)
            call UnitAddAbility(dummy, 'Aloc')
            call UnitAddAbility(dummy, XE_HEIGHT_ENABLER)
            call UnitRemoveAbility(dummy, XE_HEIGHT_ENABLER)
        endif
        call UnitAddAbility(dummy, s__xecast_abilityid[this])
//#         static if xecast__AUTO_RESET_MANA_COOLDOWN then
                call UnitResetCooldown(dummy)
                call SetUnitState(dummy, UNIT_STATE_MANA, 10000.0)
//#         endif
        if ( s__xecast_level[this] > 1 ) then
            call SetUnitAbilityLevel(dummy, s__xecast_abilityid[this], s__xecast_level[this])
        endif
//end of: xecast_allocdummy()
        if ( s__xecast_customsource[this] ) then
            call SetUnitX(dummy, s__xecast_sourcex[this])
            call SetUnitY(dummy, s__xecast_sourcey[this])
            call SetUnitFlyHeight(dummy, s__xecast_sourcez[this], 0.0)
        else
            call SetUnitX(dummy, x)
            call SetUnitY(dummy, y)
        endif
        call IssuePointOrderById(dummy, s__xecast_oid[this], x, y)
//textmacro instance: xecast_deallocdummy()
        if ( s__xecast_recycledelay[this] >= xecast__EPSILON ) then
            set s__xecast_cexpire=TimerGetElapsed(s__xecast_gametime) + s__xecast_recycledelay[this]
            set s__xecast_current=s__xecast_rn
            set s__xecast_rn=s__xecast_rn + 1
            loop
                exitwhen ( s__xecast_current == 0 )
                set s__xecast_cparent=( s__xecast_current - 1 ) / 2
                exitwhen ( s__xecast_expiretime[s__xecast_cparent] <= s__xecast_cexpire )
                set s__xecast_recycle[s__xecast_current]=s__xecast_recycle[s__xecast_cparent]
                set s__xecast_expiretime[s__xecast_current]=s__xecast_expiretime[s__xecast_cparent]
                set s__xecast_current=s__xecast_cparent
            endloop
            set s__xecast_expiretime[s__xecast_current]=s__xecast_cexpire
            set s__xecast_recycle[s__xecast_current]=dummy
            call SetUnitUserData(dummy, s__xecast_abilityid[this])
            call TimerStart(s__xecast_T, s__xecast_expiretime[0] - TimerGetElapsed(s__xecast_gametime), false, function s__xecast_dorecycle)
        else
            call SetUnitUserData(dummy, 0)
            call SetUnitFlyHeight(dummy, 0, 0)
            call UnitRemoveAbility(dummy, s__xecast_abilityid[this])
        endif
//end of: xecast_deallocdummy()
        if ( s__xecast_autodestroy[this] ) then
            call s__xecast_deallocate(this)
        endif
    endfunction
    function s__xecast_castOnLoc takes integer this,location loc returns nothing
        //debug call BJDebugMsg("Warning: Locations are in use")
        //nah but I should 
        call s__xecast_castOnPoint(this,GetLocationX(loc) , GetLocationY(loc))
    endfunction

    //ignores custom source x and y (for obvious reasons)
    function s__xecast_castInPoint takes integer this,real x,real y returns nothing
     local unit dummy
//textmacro instance: xecast_allocdummy()
        if ( s__xecast_recycledelay[this] < xecast__EPSILON ) then
            set dummy=s__xecast_instantdummy
            call SetUnitOwner(dummy, s__xecast_owningplayer[this], false)
        elseif ( s__xecast_top > 0 ) then
            set s__xecast_top=s__xecast_top - 1
            set dummy=s__xecast_dummystack[s__xecast_top]
            call SetUnitOwner(dummy, s__xecast_owningplayer[this], false)
        else
            set dummy=CreateUnit(s__xecast_owningplayer[this], XE_DUMMY_UNITID, 0, 0, 0)
            call TriggerRegisterUnitEvent(s__xecast_abilityRemove, dummy, EVENT_UNIT_SPELL_ENDCAST)
            call UnitAddAbility(dummy, 'Aloc')
            call UnitAddAbility(dummy, XE_HEIGHT_ENABLER)
            call UnitRemoveAbility(dummy, XE_HEIGHT_ENABLER)
        endif
        call UnitAddAbility(dummy, s__xecast_abilityid[this])
//#         static if xecast__AUTO_RESET_MANA_COOLDOWN then
                call UnitResetCooldown(dummy)
                call SetUnitState(dummy, UNIT_STATE_MANA, 10000.0)
//#         endif
        if ( s__xecast_level[this] > 1 ) then
            call SetUnitAbilityLevel(dummy, s__xecast_abilityid[this], s__xecast_level[this])
        endif
//end of: xecast_allocdummy()
        if ( s__xecast_customsource[this] ) then
            call SetUnitFlyHeight(dummy, s__xecast_sourcez[this], 0.0)
        endif
        call SetUnitX(dummy, x)
        call SetUnitY(dummy, y)
        call IssueImmediateOrderById(dummy, s__xecast_oid[this])
//textmacro instance: xecast_deallocdummy()
        if ( s__xecast_recycledelay[this] >= xecast__EPSILON ) then
            set s__xecast_cexpire=TimerGetElapsed(s__xecast_gametime) + s__xecast_recycledelay[this]
            set s__xecast_current=s__xecast_rn
            set s__xecast_rn=s__xecast_rn + 1
            loop
                exitwhen ( s__xecast_current == 0 )
                set s__xecast_cparent=( s__xecast_current - 1 ) / 2
                exitwhen ( s__xecast_expiretime[s__xecast_cparent] <= s__xecast_cexpire )
                set s__xecast_recycle[s__xecast_current]=s__xecast_recycle[s__xecast_cparent]
                set s__xecast_expiretime[s__xecast_current]=s__xecast_expiretime[s__xecast_cparent]
                set s__xecast_current=s__xecast_cparent
            endloop
            set s__xecast_expiretime[s__xecast_current]=s__xecast_cexpire
            set s__xecast_recycle[s__xecast_current]=dummy
            call SetUnitUserData(dummy, s__xecast_abilityid[this])
            call TimerStart(s__xecast_T, s__xecast_expiretime[0] - TimerGetElapsed(s__xecast_gametime), false, function s__xecast_dorecycle)
        else
            call SetUnitUserData(dummy, 0)
            call SetUnitFlyHeight(dummy, 0, 0)
            call UnitRemoveAbility(dummy, s__xecast_abilityid[this])
        endif
//end of: xecast_deallocdummy()
        if ( s__xecast_autodestroy[this] ) then
            call s__xecast_deallocate(this)
        endif
    endfunction
    function s__xecast_castInLoc takes integer this,location loc returns nothing
        //debug call BJDebugMsg("Warning: Locations are in use")
        //nah but I should 
        call s__xecast_castInPoint(this,GetLocationX(loc) , GetLocationY(loc))
    endfunction


    //===================================================================================================
    // For method castOnAOE:
    //

    // Might look wrong, but this is the way to make it consider collision size, a spell that
    // got a target circle and uses this method will let the user know which units it will
    // hit with the mass cast.
    function s__xecast_filterAOE takes nothing returns boolean
     local unit u=GetFilterUnit()
        if IsUnitInRangeXY(u, s__xecast_aoex, s__xecast_aoey, s__xecast_aoeradius) then
            call s__xecast_castOnTarget(s__xecast_cinstance,u)
        endif
     set u=null
     return false
    endfunction

    //
    function s__xecast_castOnAOE takes integer this,real x,real y,real radius returns nothing
     local boolean ad=s__xecast_autodestroy[this]

        if ( ad ) then
            set s__xecast_autodestroy[this]=false
        endif
        set s__xecast_aoex=x
        set s__xecast_aoey=y
        set s__xecast_aoeradius=radius
        set s__xecast_cinstance=this
        call GroupEnumUnitsInRange(s__xecast_enumgroup, x, y, radius + XE_MAX_COLLISION_SIZE, s__xecast_aoefunc)
        if ( ad ) then
            call s__xecast_deallocate(this)
        endif
    endfunction

    function s__xecast_castOnAOELoc takes integer this,location loc,real radius returns nothing
        call s__xecast_castOnAOE(this,GetLocationX(loc) , GetLocationY(loc) , radius)
    endfunction

    //==================================================================================================
    // A quick and dirt castOnGroup method, perhaps it'll later have castOntarget inlined, but not now
    //
    function s__xecast_castOnGroup takes integer this,group g returns nothing
     local boolean ad=s__xecast_autodestroy[this]
     local unit t
        if ( ad ) then
            set s__xecast_autodestroy[this]=false
        endif

        loop
            set t=FirstOfGroup(g)
            exitwhen ( t == null )
            call GroupRemoveUnit(g, t)
            call s__xecast_castOnTarget(this,t)
        endloop
        if ( ad ) then
            call s__xecast_deallocate(this)
        endif
    endfunction

    function s__xecast_removeAbility takes nothing returns boolean
     local unit u=GetTriggerUnit()
         if ( GetUnitUserData(u) != 0 ) then
             call PauseUnit(u, true)
         endif
        //This is necessary, picture a value for recycle delay that's higher than the casting time,
        //for example if the spell does dps, if you leave the dummy caster with the ability and it 
        //is owned by an AI player it will start casting the ability on player units, so it is
        // a good idea to pause it...

     set u=null
     return true
    endfunction

    //===================================================================================================
    // structinit is a scope private keyword.
    //
    function s__xecast_xecast__structinit takes nothing returns nothing
     local integer i=xecast__INITIAL_DUMMY_COUNT + 1
     local unit u
        set s__xecast_aoefunc=Condition(function s__xecast_filterAOE)
        set s__xecast_enumgroup=CreateGroup()
        set s__xecast_abilityRemove=CreateTrigger()
        loop
            exitwhen ( i == 0 )
            set u=CreateUnit(Player(15), XE_DUMMY_UNITID, 0, 0, 0)
            call TriggerRegisterUnitEvent(s__xecast_abilityRemove, u, EVENT_UNIT_SPELL_ENDCAST)
            call UnitAddAbility(u, 'Aloc')
            call UnitAddAbility(u, XE_HEIGHT_ENABLER)
            call UnitRemoveAbility(u, XE_HEIGHT_ENABLER)
            set s__xecast_dummystack[s__xecast_top]=u
            set s__xecast_top=s__xecast_top + 1
            set i=i - 1
        endloop
        call TriggerAddCondition(s__xecast_abilityRemove, Condition(function s__xecast_removeAbility))
        set s__xecast_top=s__xecast_top - 1
        set s__xecast_instantdummy=s__xecast_dummystack[s__xecast_top]
        set s__xecast_T=CreateTimer()
        set s__xecast_gametime=CreateTimer()
        call TimerStart(s__xecast_gametime, 12 * 60 * 60, false, null)
    endfunction




function xecast__init takes nothing returns nothing
    call s__xecast_xecast__structinit()
endfunction


//endlibrary xecast
//library xedamage
//************************************************************************
// xedamage 0.8
// --------
//  For all your damage and targetting needs.
//
//************************************************************************

//===========================================================================================================



        //----
        // fields and methods for a xedamage object, they aid determining valid targets and special
        // damage factor conditions.
        //
        // Notice the default values.
        //
                                       // xedamage would consider this unit as immune unless you set damageSelf to true

                                       // true by default, you may not really need to modify this.


                                       //AOE for example targets a circle, so it can affect the destructables
                                       //in that circle, a custom spell using xedamage for targetting configuration
                                       //could also have an if-then-else implemented so it can verify if it is true
                                       //then affect trees manually.

        //
        // Damage type stuff:
        //    .dtype : the "damagetype" , determines if the spell is physical, magical or ultimate.
        //    .atype : the "attacktype" , deals with armor.
        //    .wtype : the "weapontype" , determines the sound effect to be played when damage is done.
        //
        //  Please use common.j/blizzard.j/ some guide to know what damage/attack/weapon types can be used
        //

        //
        // Damage type 'tag' people might use xedamage.isInUse() to detect xedamage usage, there are other static
        //  variables like xedamage.CurrentDamageType and xedamage.CurrentDamageTag. The tag allows you to specify
        //  a custom id for the damage type ** Notice the tag would aid you for some spell stuff, for example,
        //  you can use it in a way similar to Rising_Dusk's damage system.
        //

        //
        // if true, forceDamage will make xedamage ignore dtype and atype and try as hard as possible to deal 100%
        // damage.


        //
        // Ally factor! Certain spells probably have double purposes and heal allies while harming enemies. This
        // field allows you to do such thing.
        //

        //
        // field: .exception = SOME_UNIT_TYPE
        // This field adds an exception unittype (classification), if the unit belongs to this unittype it will
        // be ignored.
        //
        function s__xedamage__set_exception takes integer this,unittype ut returns nothing
            set s__xedamage_use_ex[this]=true
            set s__xedamage_ex_ut[this]=ut
        endfunction

        //
        // field: .required = SOME_UNIT_TYPE
        // This field adds a required unittype (classification), if the unit does not belong to this unittype
        //  it will be ignored.
        //
        function s__xedamage__set_required takes integer this,unittype ut returns nothing
            set s__xedamage_use_req[this]=true
            set s__xedamage_req_ut[this]=ut
        endfunction




        //
        // method .factor(SOME_UNIT_TYPE, factor)
        //  You might call factor() if you wish to specify a special damage factor for a certain classification,
        // for example call d.factor(UNIT_TYPE_STRUCTURE, 0.5) makes xedamage do half damage to structures.
        //
        function s__xedamage_factor takes integer this,unittype ut,real fc returns nothing
            if ( s__xedamage_fcn[this] == xedamage__MAX_SUB_OPTIONS ) then
                 call BJDebugMsg("In one instance of xedamage, you are doing too much calls to factor(), please increase MAX_SUB_OPTIONS to allow more, or cut the number of factor() calls")
                return
            endif
            set s___xedamage_fct[s__xedamage_fct[this]+s__xedamage_fcn[this]]=ut
            set s___xedamage_fc[s__xedamage_fc[this]+s__xedamage_fcn[this]]=fc
            set s__xedamage_fcn[this]=s__xedamage_fcn[this] + 1
        endfunction


        //
        // method .abilityFactor('abil', factor)
        //  You might call abilityFactor() if you wish to specify a special damage factor for units that have a
        // certain ability/buff.
        // for example call d.abilityFactor('A000', 1.5 ) makes units that have the A000 ability take 50% more
        // damage than usual.
        //
        
        function s__xedamage_abilityFactor takes integer this,integer abilityId,real fc returns nothing
            if ( s__xedamage_abifcn[this] == xedamage__MAX_SUB_OPTIONS ) then
                 call BJDebugMsg("In one instance of xedamage, you are doing too much calls to abilityFactor(), please increase MAX_SUB_OPTIONS to allow more, or cut the number of abilityFactor() calls")
                return
            endif
            set s___xedamage_abifct[s__xedamage_abifct[this]+s__xedamage_abifcn[this]]=abilityId
            set s___xedamage_abifc[s__xedamage_abifc[this]+s__xedamage_abifcn[this]]=fc
            set s__xedamage_abifcn[this]=s__xedamage_abifcn[this] + 1
        endfunction


        //
        // method .useSpecialEffect("effect\\path.mdl", "origin")
        // Makes it add (and destroy) an effect when damage is performed.
        //
        function s__xedamage_useSpecialEffect takes integer this,string path,string attach returns nothing
            set s__xedamage_usefx[this]=true
            set s__xedamage_fxpath[this]=path
            set s__xedamage_fxattach[this]=attach
        endfunction


        //********************************************************************
        //* Now, the usage stuff:
        //*

        //================================================================================
        // static method xedamage.isInUse()  will return true during a unit damaged
        // event in case this damage was caused by xedamage, in this case, you can
        // read variables like CurrentDamageType, CurrentAttackType and CurrentDamageTag
        // to be able to recognize what sort of damage was done.
        //

        function s__xedamage_isInUse takes nothing returns boolean
            return ( s__xedamage_inUse > 0 ) //inline friendly.
        endfunction
        

        //========================================================================================================
        // This function calculates the damage factor caused by a certain attack and damage
        // type, it is static : xedamage.getDamageTypeFactor(someunit, ATTAcK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, 100)
        //
        function s__xedamage_getDamageTypeFactor takes unit u,attacktype a,damagetype d returns real
         local real hp=GetWidgetLife(u)
         local real mana=GetUnitState(u, UNIT_STATE_MANA)
         local real r
         local real fc= xedamage__FACTOR_TEST_DAMAGE

            //Since a unit is in that point, we don't need checks.
            call SetUnitX(xedamage__dmger, GetUnitX(u))
            call SetUnitY(xedamage__dmger, GetUnitY(u))

            call SetUnitOwner(xedamage__dmger, GetOwningPlayer(u), false)
            set r=hp
            if ( hp < xedamage__FACTOR_TEST_DAMAGE * xedamage__MAX_DAMAGE_FACTOR ) then
                 call SetWidgetLife(u, hp + xedamage__FACTOR_TEST_DAMAGE * xedamage__MAX_DAMAGE_FACTOR)
                 set r=hp + xedamage__FACTOR_TEST_DAMAGE * xedamage__MAX_DAMAGE_FACTOR
                 set fc=GetWidgetLife(u) - hp + xedamage__EPSILON
            endif
            set s__xedamage_isDummyDamage=true
            call UnitDamageTarget(xedamage__dmger, u, fc, false, false, a, d, null)
//#             static if true then
                    if IsUnitType(u, UNIT_TYPE_DEAD) and ( hp > 0.405 ) then
                        call BJDebugMsg("xedamage: For some reason, the unit being tested by getDamageTypeFactor has died. Verify MAX_DAMAGE_FACTOR is set to a correct value. ")
                    endif
//#             endif
            
            set s__xedamage_isDummyDamage=false
            call SetUnitOwner(xedamage__dmger, Player(15), false)
            if ( mana > GetUnitState(u, UNIT_STATE_MANA) ) then
                //Unit had mana shield, return 1 and restore mana too.
                call SetUnitState(u, UNIT_STATE_MANA, mana)
                set r=1
            else
                set r=( r - GetWidgetLife(u) ) / fc
            endif
            call SetWidgetLife(u, hp)
         return r
        endfunction


function rf__s__xedamage_getTargetFactorCore takes integer this,unit source,unit target,boolean usetypes returns nothing
         local player p=GetOwningPlayer(source)
         local boolean allied=IsUnitAlly(target, p)
         local boolean enemy=IsUnitEnemy(target, p)
         local boolean neutral=allied
         local real f
         local real negf=1.0
         local integer i

            if ( s__xedamage_damageAllies[this] != s__xedamage_damageNeutral[this] ) then
                set neutral=allied and not ( GetPlayerAlliance(GetOwningPlayer(target), p, ALLIANCE_HELP_REQUEST) )
                //I thought accuracy was not as important as speed , I think that REQUEST is false is enough to consider
                // it neutral.
                //set neutral= allied and not (GetPlayerAlliance(GetOwningPlayer(target),p, ALLIANCE_HELP_RESPONSE ))
                //set neutral= allied and not (GetPlayerAlliance(GetOwningPlayer(target),p, ALLIANCE_SHARED_XP ))
                //set neutral= allied and not (GetPlayerAlliance(GetOwningPlayer(target),p, ALLIANCE_SHARED_SPELLS ))
                set allied=allied and not ( neutral )
            endif

            if ( not s__xedamage_damageAllies[this] ) and allied then
set rf__return_real= 0.0
return
            elseif ( not s__xedamage_damageEnemies[this] ) and enemy then
set rf__return_real= 0.0
return
            elseif ( ( not s__xedamage_damageSelf[this] ) and ( source == target ) ) then
set rf__return_real= 0.0
return
            elseif ( not s__xedamage_damageNeutral[this] ) and neutral then
set rf__return_real= 0.0
return
            elseif ( s__xedamage_use_ex[this] and IsUnitType(target, s__xedamage_ex_ut[this]) ) then
set rf__return_real= 0.0
return
            elseif ( s__xedamage_visibleOnly[this] and not IsUnitVisible(target, p) ) then
set rf__return_real= 0.0
return
            elseif ( s__xedamage_deadOnly[this] and not IsUnitType(target, UNIT_TYPE_DEAD) ) then
set rf__return_real= 0.0
return
            elseif ( not ( s__xedamage_alsoDead[this] ) and IsUnitType(target, UNIT_TYPE_DEAD) ) then
set rf__return_real= 0.0
return
            endif

            set f=1.0
            
            if ( IsUnitAlly(target, p) ) then
                set f=f * s__xedamage_allyfactor[this]
                if ( f <= - xedamage__EPSILON ) then
                    set f=- f
                    set negf=- 1.0
                endif
            endif
            if ( s__xedamage_use_req[this] and not IsUnitType(target, s__xedamage_req_ut[this]) ) then
set rf__return_real= 0.0
return
            endif

            set i=s__xedamage_fcn[this] - 1
            loop
                exitwhen ( i < 0 )
                if ( IsUnitType(target, s___xedamage_fct[s__xedamage_fct[this]+i]) ) then
                    set f=f * s___xedamage_fc[s__xedamage_fc[this]+i]
                    if ( f <= - xedamage__EPSILON ) then
                        set f=- f
                        set negf=- 1.0
                    endif
                endif
                set i=i - 1
            endloop
            set i=s__xedamage_abifcn[this] - 1
            loop
                exitwhen ( i < 0 )
                if ( GetUnitAbilityLevel(target, s___xedamage_abifct[s__xedamage_abifct[this]+i]) > 0 ) then
                    set f=f * s___xedamage_abifc[s__xedamage_abifc[this]+i]
                    if ( f <= - xedamage__EPSILON ) then
                        set f=- f
                        set negf=- 1.0
                    endif
                endif
                set i=i - 1
            endloop
            set f=f * negf

            if ( f < xedamage__EPSILON ) and ( f > - xedamage__EPSILON ) then
set rf__return_real= 0.0
return
            endif
            if ( s__xedamage_forceDamage[this] or not usetypes ) then
set rf__return_real= f
return
            endif
            set f=f * s__xedamage_getDamageTypeFactor(target , s__xedamage_atype[this] , s__xedamage_dtype[this])

            if ( f < xedamage__EPSILON ) and ( f > - xedamage__EPSILON ) then
set rf__return_real= 0.0
return
            endif

set rf__return_real= f
return
endfunction
function s__xedamage_getTargetFactorCore takes integer this,unit source,unit target,boolean usetypes returns real
    call rf__s__xedamage_getTargetFactorCore(this,source,target,usetypes)
    return rf__return_real
endfunction

        //====================================================================
        // With this you might decide if a unit is a valid target for a spell.
        //
        function s__xedamage_getTargetFactor takes integer this,unit source,unit target returns real
            return s__xedamage_getTargetFactorCore(this,source , target , true)
        endfunction

        //======================================================================
        // a little better, I guess
        //
        function s__xedamage_allowedTarget takes integer this,unit source,unit target returns boolean
            return ( s__xedamage_getTargetFactorCore(this,source , target , false) != 0.0 )
        endfunction


        //=======================================================================
        // performs damage to the target unit, for unit 'source'. 
        //
function rf__s__xedamage_damageTarget takes integer this,unit source,unit target,real damage returns nothing
         local damagetype dt=s__xedamage_CurrentDamageType
         local attacktype at=s__xedamage_CurrentAttackType
         local integer tg=s__xedamage_CurrentDamageTag
         local real f= s__xedamage_getTargetFactorCore(this,source , target , false)
         local real pl

            if ( f != 0.0 ) then
                set s__xedamage_CurrentDamageType=s__xedamage_dtype[this]
                set s__xedamage_CurrentAttackType=s__xedamage_atype[this]
                set s__xedamage_CurrentDamageTag=s__xedamage_tag[this]

                
                set s__xedamage_inUse=s__xedamage_inUse + 1
                set pl=GetWidgetLife(target)
                call UnitDamageTarget(source, target, f * damage, true, s__xedamage_ranged[this], s__xedamage_atype[this], s__xedamage_dtype[this], s__xedamage_wtype[this])
                set s__xedamage_inUse=s__xedamage_inUse - 1
                set s__xedamage_CurrentDamageTag=tg
                set s__xedamage_CurrentDamageType=dt
                set s__xedamage_CurrentAttackType=at
                if ( pl != GetWidgetLife(target) ) then
                    if ( s__xedamage_usefx[this] ) then
                         call DestroyEffect(AddSpecialEffectTarget(s__xedamage_fxpath[this], target, s__xedamage_fxattach[this]))
                    endif
set rf__return_boolean= true
return
                endif
            endif
set rf__return_boolean= false
return
endfunction
function s__xedamage_damageTarget takes integer this,unit source,unit target,real damage returns boolean
    call rf__s__xedamage_damageTarget(this,source,target,damage)
    return rf__return_boolean
endfunction

        //=======================================================================================
        // The same as damageTarget, but it forces a specific damage value, good if you already
        // know the target.
        //
        function s__xedamage_damageTargetForceValue takes integer this,unit source,unit target,real damage returns nothing
         local damagetype dt=s__xedamage_CurrentDamageType
         local attacktype at=s__xedamage_CurrentAttackType
         local integer tg=s__xedamage_CurrentDamageTag

                set s__xedamage_CurrentDamageType=s__xedamage_dtype[this]
                set s__xedamage_CurrentAttackType=s__xedamage_atype[this]
                set s__xedamage_CurrentDamageTag=s__xedamage_tag[this]

                if ( s__xedamage_usefx[this] ) then
                    call DestroyEffect(AddSpecialEffectTarget(s__xedamage_fxpath[this], target, s__xedamage_fxattach[this]))
                endif
                
                set s__xedamage_inUse=s__xedamage_inUse + 1
                call UnitDamageTarget(source, target, damage, true, s__xedamage_ranged[this], null, null, s__xedamage_wtype[this])
                set s__xedamage_inUse=s__xedamage_inUse - 1
                set s__xedamage_CurrentDamageTag=tg
                set s__xedamage_CurrentDamageType=dt
                set s__xedamage_CurrentAttackType=at
        endfunction

        //=====================================================================================
        // Notice: this will not Destroy the group, but it will certainly empty the group.
        //
        function s__xedamage_damageGroup takes integer this,unit source,group targetGroup,real damage returns integer
         local damagetype dt=s__xedamage_CurrentDamageType
         local attacktype at=s__xedamage_CurrentAttackType
         local integer tg=s__xedamage_CurrentDamageTag
         local unit target
         local real f
         local integer count=0
         local real hp

            set s__xedamage_CurrentDamageType=s__xedamage_dtype[this]
            set s__xedamage_CurrentAttackType=s__xedamage_atype[this]
            set s__xedamage_CurrentDamageTag=s__xedamage_tag[this]
            set s__xedamage_inUse=s__xedamage_inUse + 1
            loop
                set target=FirstOfGroup(targetGroup)
                exitwhen ( target == null )
                call GroupRemoveUnit(targetGroup, target)
                set f=s__xedamage_getTargetFactorCore(this,source , target , false)
                if ( f != 0.0 ) then
                    set count=count + 1
                    if ( s__xedamage_usefx[this] ) then
                        set hp=GetWidgetLife(target)
                    endif

                    call UnitDamageTarget(source, target, f * damage, true, s__xedamage_ranged[this], s__xedamage_atype[this], s__xedamage_dtype[this], s__xedamage_wtype[this])
                    if ( s__xedamage_usefx[this] and ( hp > GetWidgetLife(target) ) ) then
                        call DestroyEffect(AddSpecialEffectTarget(s__xedamage_fxpath[this], target, s__xedamage_fxattach[this]))
                    endif

                endif
            endloop


            set s__xedamage_inUse=s__xedamage_inUse - 1
            set s__xedamage_CurrentDamageTag=tg
            set s__xedamage_CurrentDamageType=dt
            set s__xedamage_CurrentAttackType=at
         return count
        endfunction


function rf__s__xedamage_damageAOE_Enum takes nothing returns nothing
         local unit target=GetFilterUnit()
         local integer this=s__xedamage_instance
         local real f
         local real hp
         
             if ( not IsUnitInRangeXY(target, s__xedamage_AOEx[this], s__xedamage_AOEy[this], s__xedamage_AOEradius[this]) ) then
                 set target=null
set rf__return_boolean= false
return
             endif
             set f=s__xedamage_getTargetFactorCore(this,s__xedamage_sourceAOE[this] , target , false)
             if ( f != 0.0 ) then
                 set s__xedamage_countAOE[this]=s__xedamage_countAOE[this] + 1
                 if ( s__xedamage_usefx[this] ) then
                      set hp=GetWidgetLife(target)
                 endif
                 call UnitDamageTarget(s__xedamage_sourceAOE[this], target, f * s__xedamage_AOEdamage[this], true, s__xedamage_ranged[this], s__xedamage_atype[this], s__xedamage_dtype[this], s__xedamage_wtype[this])
                 if ( s__xedamage_usefx[this] and ( hp > GetWidgetLife(target) ) ) then
                     call DestroyEffect(AddSpecialEffectTarget(s__xedamage_fxpath[this], target, s__xedamage_fxattach[this]))
                 endif
             endif

          set s__xedamage_instance=this //better restore, nesting IS possible!
          set target=null
set rf__return_boolean= false
return
endfunction
function s__xedamage_damageAOE_Enum takes nothing returns boolean
    call rf__s__xedamage_damageAOE_Enum()
    return rf__return_boolean
endfunction

function rf__s__xedamage_damageAOE_DestructablesEnum takes nothing returns nothing
         local destructable target=GetFilterDestructable()
         local integer this=s__xedamage_instance
         local real dx=s__xedamage_AOEx[this] - GetDestructableX(target)
         local real dy=s__xedamage_AOEy[this] - GetDestructableY(target)

             if ( dx * dx + dy * dy >= s__xedamage_AOEradius[this] + xedamage__EPSILON ) then
                 set target=null
set rf__return_boolean= false
return
             endif
             set s__xedamage_countAOE[this]=s__xedamage_countAOE[this] + 1
             if ( s__xedamage_usefx[this] ) then
                 call DestroyEffect(AddSpecialEffectTarget(s__xedamage_fxpath[this], target, s__xedamage_fxattach[this]))
             endif
             call UnitDamageTarget(s__xedamage_sourceAOE[this], target, s__xedamage_AOEdamage[this], true, s__xedamage_ranged[this], s__xedamage_atype[this], s__xedamage_dtype[this], s__xedamage_wtype[this])

          set s__xedamage_instance=this //better restore, nesting IS possible!
          set target=null
set rf__return_boolean= false
return
endfunction
function s__xedamage_damageAOE_DestructablesEnum takes nothing returns boolean
    call rf__s__xedamage_damageAOE_DestructablesEnum()
    return rf__return_boolean
endfunction
        //==========================================================================================
        // will affect trees if damageTrees is true!
        // 
        function s__xedamage_damageAOE takes integer this,unit source,real x,real y,real radius,real damage returns integer
         local damagetype dt=s__xedamage_CurrentDamageType
         local attacktype at=s__xedamage_CurrentAttackType
         local integer tg=s__xedamage_CurrentDamageTag

            set s__xedamage_CurrentDamageType=s__xedamage_dtype[this]
            set s__xedamage_CurrentAttackType=s__xedamage_atype[this]
            set s__xedamage_CurrentDamageTag=s__xedamage_tag[this]
            set s__xedamage_inUse=s__xedamage_inUse + 1
            set s__xedamage_instance=this
            set s__xedamage_countAOE[this]=0
            set s__xedamage_sourceAOE[this]=source
            set s__xedamage_AOEx[this]=x
            set s__xedamage_AOEradius[this]=radius
            set s__xedamage_AOEy[this]=y
            set s__xedamage_AOEdamage[this]=damage
            call GroupEnumUnitsInRange(s__xedamage_enumgroup, x, y, radius + XE_MAX_COLLISION_SIZE, s__xedamage_filterAOE)
            if ( s__xedamage_damageTrees[this] ) then
                call SetRect(s__xedamage_AOERect, x - radius, y - radius, x + radius, y + radius)
                set s__xedamage_AOEradius[this]=s__xedamage_AOEradius[this] * s__xedamage_AOEradius[this]
                call EnumDestructablesInRect(s__xedamage_AOERect, s__xedamage_filterDestAOE, null)
            endif
            set s__xedamage_inUse=s__xedamage_inUse - 1
            set s__xedamage_CurrentDamageTag=tg
            set s__xedamage_CurrentDamageType=dt
            set s__xedamage_CurrentAttackType=at
         return s__xedamage_countAOE[this]
        endfunction

        function s__xedamage_damageAOELoc takes integer this,unit source,location loc,real radius,real damage returns integer
            return s__xedamage_damageAOE(this,source , GetLocationX(loc) , GetLocationY(loc) , radius , damage)
        endfunction

        //==========================================================================================
        // only affects trees, ignores damageTrees
        // 
        function s__xedamage_damageDestructablesAOE takes integer this,unit source,real x,real y,real radius,real damage returns integer
            set s__xedamage_instance=this
            set s__xedamage_countAOE[this]=0
            set s__xedamage_sourceAOE[this]=source
            set s__xedamage_AOEx[this]=x
            set s__xedamage_AOEradius[this]=radius * radius
            set s__xedamage_AOEy[this]=y
            set s__xedamage_AOEdamage[this]=damage
            //if(.damageTrees) then
                call SetRect(s__xedamage_AOERect, x - radius, y - radius, x + radius, y + radius)
                call EnumDestructablesInRect(s__xedamage_AOERect, s__xedamage_filterDestAOE, null)
            //endif
         return s__xedamage_countAOE[this]
        endfunction
        function s__xedamage_damageDestructablesAOELoc takes integer this,unit source,location loc,real radius,real damage returns integer
            return s__xedamage_damageDestructablesAOE(this,source , GetLocationX(loc) , GetLocationY(loc) , radius , damage)
        endfunction

        //'friend' with the library init
        function s__xedamage_xedamage__structInit takes nothing returns nothing
            set s__xedamage_AOERect=Rect(0, 0, 0, 0)
            set s__xedamage_filterAOE=Condition(function s__xedamage_damageAOE_Enum)
            set s__xedamage_filterDestAOE=Condition(function s__xedamage_damageAOE_DestructablesEnum)
            set s__xedamage_enumgroup=CreateGroup()
        endfunction

    function xedamage__init takes nothing returns nothing
        set xedamage__dmger=CreateUnit(Player(15), XE_DUMMY_UNITID, 0., 0., 0.)
        call UnitAddAbility(xedamage__dmger, 'Aloc')
        call s__xedamage_xedamage__structInit()
    endfunction





//endlibrary xedamage
//library xedummy
//******************************************************************************
// xedummy 0.9
// ------
// For all your xe dummy recycling needs.
//
//******************************************************************************

//==============================================================================

// END OF CALIBRATION SECTION
// ================================================================



        function s__xedummy___recycleQueue_onInit takes nothing returns nothing
            local integer i=0
            loop
                exitwhen i == xedummy___ANGLE_RESOLUTION
                set i=i + 1
                set s__xedummy___recycleQueue_prev[(i)]=(i - 1)
                set s__xedummy___recycleQueue_next[(i)]=(i + 1)
                set s__xedummy___recycleQueue_angle[(i)]=( i - 0.5 ) * ( 360.0 / xedummy___ANGLE_RESOLUTION )
            endloop
            set s__xedummy___recycleQueue_prev[(1)]=(i)
            set s__xedummy___recycleQueue_next[(i)]=(1)
        endfunction

        function s__xedummy___recycleQueue_get takes real angle returns integer
            return (R2I(angle / 360.0 * xedummy___ANGLE_RESOLUTION) + 1)
        endfunction

// ================================================================


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

        
        function s__xedummy___xedummy_queueInsert takes integer this,integer q returns nothing
            call SetUnitFacing(s__xedummy___xedummy_u[this], s__xedummy___recycleQueue_angle[q])

            if s__xedummy___recycleQueue_size[q] == 0 then
                set s__xedummy___recycleQueue_first[q]=this
            else
                set s__xedummy___xedummy_next[s__xedummy___recycleQueue_last[q]]=this
            endif
            set s__xedummy___recycleQueue_last[q]=this
            set s__xedummy___xedummy_next[this]=0

            // Recursively check adajcent queues and migrate xedummies as needed.
            if s__xedummy___recycleQueue_size[q] > s__xedummy___recycleQueue_size[s__xedummy___recycleQueue_next[q]] then
                set this=s__xedummy___recycleQueue_first[q]
                set s__xedummy___recycleQueue_first[q]=s__xedummy___xedummy_next[this]
                call s__xedummy___xedummy_queueInsert(this,s__xedummy___recycleQueue_next[q])
            elseif s__xedummy___recycleQueue_size[q] > s__xedummy___recycleQueue_size[s__xedummy___recycleQueue_prev[q]] then
                set this=s__xedummy___recycleQueue_first[q]
                set s__xedummy___recycleQueue_first[q]=s__xedummy___xedummy_next[this]
                call s__xedummy___xedummy_queueInsert(this,s__xedummy___recycleQueue_prev[q])
            else
                set s__xedummy___recycleQueue_size[q]=s__xedummy___recycleQueue_size[q] + 1
            endif
        endfunction
        
        function s__xedummy___xedummy_queueRemove takes integer q returns integer
            // Recursively check adajcent queues and migrate xedummies as needed.
            local integer this
            if s__xedummy___recycleQueue_size[q] < s__xedummy___recycleQueue_size[s__xedummy___recycleQueue_next[q]] then
                set this=s__xedummy___recycleQueue_last[q]
                set s__xedummy___recycleQueue_last[q]=s__xedummy___xedummy_queueRemove(s__xedummy___recycleQueue_next[q])
//Recursion + many return statements found, if you see a compile error in the next lines
//Then you should really, really fix this function as it is probably a return bug false possitive. 
//If you are sure it is fine, and want to be able to compile your map, disable the "return bug fix"

                set s__xedummy___xedummy_next[this]=s__xedummy___recycleQueue_last[q]
                call SetUnitFacing(s__xedummy___xedummy_u[s__xedummy___recycleQueue_last[q]], s__xedummy___recycleQueue_angle[q])
            elseif s__xedummy___recycleQueue_size[q] < s__xedummy___recycleQueue_size[s__xedummy___recycleQueue_prev[q]] then
                set this=s__xedummy___recycleQueue_last[q]
                set s__xedummy___recycleQueue_last[q]=s__xedummy___xedummy_queueRemove(s__xedummy___recycleQueue_prev[q])
//Recursion + many return statements found, if you see a compile error in the next lines
//Then you should really, really fix this function as it is probably a return bug false possitive. 
//If you are sure it is fine, and want to be able to compile your map, disable the "return bug fix"

                set s__xedummy___xedummy_next[this]=s__xedummy___recycleQueue_last[q]
                call SetUnitFacing(s__xedummy___xedummy_u[s__xedummy___recycleQueue_last[q]], s__xedummy___recycleQueue_angle[q])
            else
                set s__xedummy___recycleQueue_size[q]=s__xedummy___recycleQueue_size[q] - 1
                if s__xedummy___recycleQueue_size[q] == 0 then
                    set s__xedummy___recycleQueue_last[q]=0
                endif
            endif

            set this=s__xedummy___recycleQueue_first[q]
            set s__xedummy___recycleQueue_first[q]=s__xedummy___xedummy_next[this]
            set s__xedummy___xedummy_next[this]=0
            return this
        endfunction
    
        // ----------------------------------------------------------------

function rf__s__xedummy___xedummy_create takes unit u returns nothing
            local integer this
            if GetUnitTypeId(u) != XE_DUMMY_UNITID then
                 call BJDebugMsg("ReleaseXEDummy error: Method called on a unit of an incorrect type.")
            elseif IsUnitInGroup(u, s__xedummy___xedummy_g) then
                 call BJDebugMsg("ReleaseXEDummy error: Method called on an already released unit.")
            else
                set this=s__xedummy___xedummy__allocate()
                if (this) > xedummy___DUMMY_STACK_LIMIT then
                    call RemoveUnit(u)
                    call s__xedummy___xedummy_deallocate(this)
set rf__return_integer= 0
return
                endif
                set s__xedummy___xedummy_u[this]=u
                call GroupAddUnit(s__xedummy___xedummy_g, u)
                call s__xedummy___xedummy_queueInsert(this,(R2I(((GetUnitFacing(u))*1.0) / 360.0 * xedummy___ANGLE_RESOLUTION) + 1)) // INLINED!!
                call SetUnitAnimationByIndex(u, 90)
                call SetUnitScale(u, 1, 0, 0)
                call SetUnitVertexColor(u, 255, 255, 255, 255)
                // call ShowUnit(u, false) // Do not hide the unit, it is rather costly and not needed.
set rf__return_integer= this
return
            endif
set rf__return_integer= 0
return
endfunction
function s__xedummy___xedummy_create takes unit u returns integer
    call rf__s__xedummy___xedummy_create(u)
    return rf__return_integer
endfunction

        function s__xedummy___xedummy_destroy takes integer this returns nothing
            call GroupRemoveUnit(s__xedummy___xedummy_g, s__xedummy___xedummy_u[this])
            call ShowUnit(s__xedummy___xedummy_u[this], true) // Show the unit in case it was hidden before being recycled.
            set s__xedummy___xedummy_u[this]=null
            call s__xedummy___xedummy_deallocate(this)
        endfunction
        
        // ----------------------------------------------------------------


        function s__xedummy___xedummy_onInit takes nothing returns nothing
            local integer i=xedummy___INITIAL_DUMMY_COUNT
            local integer q=(1)
            if i > xedummy___DUMMY_STACK_LIMIT then
                 call BJDebugMsg("xedummy error: INITIAL_DUMMY_COUNT can not be larger than DUMMY_STACK_LIMIT.")
                set i=xedummy___DUMMY_STACK_LIMIT
            endif
            loop
                exitwhen i == 0
                set s__xedummy___xedummy_dummy=CreateUnit(Player(15), XE_DUMMY_UNITID, 0.0, 0.0, s__xedummy___recycleQueue_angle[q])
                call UnitAddAbility(s__xedummy___xedummy_dummy, XE_HEIGHT_ENABLER)
                call UnitAddAbility(s__xedummy___xedummy_dummy, 'Aloc')
                call UnitRemoveAbility(s__xedummy___xedummy_dummy, XE_HEIGHT_ENABLER)
                call s__xedummy___xedummy_create(s__xedummy___xedummy_dummy)
                set i=i - 1
                set q=s__xedummy___recycleQueue_next[q]
            endloop
        endfunction

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

        function s__xedummy___xedummy_new takes player p,real x,real y,real face returns unit
            local integer q
            local integer this
            loop
                exitwhen face > 0.0
                set face=face + 360.0
            endloop
            loop
                exitwhen face < 360.0
                set face=face - 360.0
            endloop
            set q=(R2I(((face)*1.0) / 360.0 * xedummy___ANGLE_RESOLUTION) + 1) // INLINED!!
            if s__xedummy___recycleQueue_size[q] == 0 then
                set s__xedummy___xedummy_dummy=CreateUnit(p, XE_DUMMY_UNITID, x, y, face)
                call UnitAddAbility(s__xedummy___xedummy_dummy, XE_HEIGHT_ENABLER)
                call UnitAddAbility(s__xedummy___xedummy_dummy, 'Aloc')
                call UnitRemoveAbility(s__xedummy___xedummy_dummy, XE_HEIGHT_ENABLER)
                call SetUnitX(s__xedummy___xedummy_dummy, x)
                call SetUnitY(s__xedummy___xedummy_dummy, y)
            else
                set this=s__xedummy___xedummy_queueRemove(q)
                set s__xedummy___xedummy_dummy=s__xedummy___xedummy_u[this]
                call s__xedummy___xedummy_destroy(this)
                call SetUnitX(s__xedummy___xedummy_dummy, x)
                call SetUnitY(s__xedummy___xedummy_dummy, y)
                call SetUnitFacing(s__xedummy___xedummy_dummy, face)
                call SetUnitOwner(s__xedummy___xedummy_dummy, p, true)
            endif
            return s__xedummy___xedummy_dummy
        endfunction

        function s__xedummy___xedummy_release takes unit u returns nothing
            call s__xedummy___xedummy_create(u)
        endfunction
    
// ================================================================

    function XE_NewDummyUnit takes player p,real x,real y,real face returns unit
        return s__xedummy___xedummy_new(p , x , y , face)
    endfunction

    function XE_ReleaseDummyUnit takes unit u returns nothing
        call s__xedummy___xedummy_create((u)) // INLINED!!
    endfunction


//endlibrary xedummy
//library xepreload
//******************************************************************************
// xepreload 0.9
// ---------
// Ah, the joy of preloading abilities, it is such a necessary evil...
// Notice you are not supposed to use this system in places outside map init
//
// This one does the preloading and tries to minimize the hit on loading time
// for example, it only needs one single native call per ability preloaded.
//
//******************************************************************************

//==============================================================================

    //inline friendly (when debug mode is off..)
    function XE_PreloadAbility takes integer abilid returns nothing
        call UnitAddAbility(xepreload__dum, abilid)
//#         static if true then
                if ( xepreload__dum == null ) then
                    call BJDebugMsg("XE_PreloadAbility: do not load abilities after map init or during modules' onInit")
                elseif GetUnitAbilityLevel(xepreload__dum, abilid) == 0 then
                    call BJDebugMsg("XE_PreloadAbility: Ability " + sc___prototype11_evaluate(1,abilid) + " does not exist.")
                endif
//#         endif
    endfunction
    // ................................................................................

    //================================================================================
    // Convert a integer id value into a 4-letter id code.
    // * Taken from cheats.j so I don't have to code it again.
    // * Used only on debug so making a whole library for it seemed silly
    // * Private so people don't begin using xepreload just to call this function....
    // * It will not work correctly if you paste this code in the custom script section
    //   due to the infamous % bug. Then again, if you do that then you probably 
    // deserve it....
    //
    function xepreload__DebugIdInteger2IdString takes integer value returns string
     local string charMap= ".................................!.#$%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."
     local string result= ""
     local integer remainingValue= value
     local integer charValue
     local integer byteno

     set byteno=0
     loop
         set charValue=ModuloInteger(remainingValue, 256)
         set remainingValue=remainingValue / 256
         set result=SubString(charMap, charValue, charValue + 1) + result
 
         set byteno=byteno + 1
         exitwhen byteno == 4
     endloop
     return result
    endfunction

    //--------------------------------
    function xepreload__kill takes nothing returns nothing
        call RemoveUnit(xepreload__dum)
        set xepreload__dum=null
//#         static if  LIBRARY_TimerUtils   then
//#             call ReleaseTimer( GetExpiredTimer() )
//#         else
                call DestroyTimer(GetExpiredTimer())
//#         endif
    endfunction
    
    function s__xepreload__init_onInit takes nothing returns nothing
     local timer t
        set xepreload__dum=CreateUnit(Player(15), XE_DUMMY_UNITID, 0, 0, 0)
        if ( xepreload__dum == null ) then
             call BJDebugMsg("xePreload : XE_DUMMY_UNITID (" + sc___prototype11_evaluate(1,XE_DUMMY_UNITID) + ") not added correctly to the map.")
        endif
//#         static if  LIBRARY_TimerUtils  then
//#             set t=NewTimer()
//#         else
                set t=CreateTimer()
//#         endif
        call TimerStart(t, 0.0, false, function xepreload__kill)
        set t=null
    endfunction


//endlibrary xepreload
//library xefx
//**************************************************
// xefx 0.9
// --------
//  Recommended: ARGB (adds ARGBrecolor method)
//  For your movable fx needs
//
//**************************************************

//==================================================



       function s__xefx___recyclebin_Recycle takes nothing returns nothing
            local integer this= s__xefx___recyclebin_list[s__xefx___recyclebin_readindex]
            loop
                exitwhen this == 0
//#                 static if xefx___RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then
                        call s__xedummy___xedummy_create(((s__xefx___recyclebin_u[this]))) // INLINED!!
//#                 else
//#                     call RemoveUnit(this.u)
//#                 endif
                set s__xefx___recyclebin_u[this]=null
                set s__xefx___recyclebin_count=s__xefx___recyclebin_count - 1
                call s__xefx___recyclebin_deallocate(this)
                set this=s__xefx___recyclebin_next[this]
            endloop
            set s__xefx___recyclebin_list[s__xefx___recyclebin_readindex]=0
            set s__xefx___recyclebin_writeindex=s__xefx___recyclebin_readindex
            set s__xefx___recyclebin_readindex=s__xefx___recyclebin_readindex + 1
            if s__xefx___recyclebin_readindex > R2I(xefx___MIN_RECYCLE_DELAY / xefx___RECYCLE_INTERVAL + 1.0) then
                set s__xefx___recyclebin_readindex=0
            endif
            if s__xefx___recyclebin_count != 0 then
                call TimerStart(xefx___recycler, xefx___RECYCLE_INTERVAL, false, function s__xefx___recyclebin_Recycle)
            endif
       endfunction
       
       function s__xefx___recyclebin_create takes unit u returns integer
           local integer this=s__xefx___recyclebin__allocate()
           if s__xefx___recyclebin_count == 0 then
                call TimerStart(xefx___recycler, xefx___RECYCLE_INTERVAL, false, function s__xefx___recyclebin_Recycle)
           endif
           set s__xefx___recyclebin_count=s__xefx___recyclebin_count + 1
           set s__xefx___recyclebin_u[this]=u
           call SetUnitOwner(u, Player(15), false)
           set s__xefx___recyclebin_next[this]=s__xefx___recyclebin_list[s__xefx___recyclebin_writeindex]
           set s__xefx___recyclebin_list[s__xefx___recyclebin_writeindex]=this
           return this
       endfunction



   function xefx___init takes nothing returns nothing
       set xefx___recycler=CreateTimer()
   endfunction



       function s__xefx_create takes real x,real y,real facing returns integer
        local integer this=s__xefx__allocate()
//#            static if xefx___RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then
                   set s__xefx_dummy[this]=(s__xedummy___xedummy_new((Player(15) ) , (( x )*1.0) , (( y )*1.0) , (( facing * bj_RADTODEG)*1.0))) // INLINED!!
//#            else
//#                set this.dummy= CreateUnit(Player(15), XE_DUMMY_UNITID, x,y, facing*bj_RADTODEG)
//#                call UnitAddAbility(this.dummy,XE_HEIGHT_ENABLER)
//#                call UnitAddAbility(this.dummy,'Aloc')
//#                call UnitRemoveAbility(this.dummy,XE_HEIGHT_ENABLER)
//#                call SetUnitX(this.dummy,x)
//#                call SetUnitY(this.dummy,y)
//#            endif
        return this
       endfunction

       function s__xefx__get_owner takes integer this returns player
           return GetOwningPlayer(s__xefx_dummy[this])
       endfunction

       function s__xefx__set_owner takes integer this,player p returns nothing
           call SetUnitOwner(s__xefx_dummy[this], p, false)
       endfunction

       function s__xefx__set_teamcolor takes integer this,playercolor c returns nothing
           call SetUnitColor(s__xefx_dummy[this], c)
       endfunction

       function s__xefx__set_scale takes integer this,real value returns nothing
           call SetUnitScale(s__xefx_dummy[this], value, value, value)
       endfunction

//textmacro instance: XEFX_colorstuff("red","r")
       function s__xefx__get_red takes integer this returns integer
           return s__xefx_r[this]
       endfunction
       function s__xefx__set_red takes integer this,integer value returns nothing
           set s__xefx_r[this]=value
           call SetUnitVertexColor(s__xefx_dummy[this], s__xefx_r[this], s__xefx_g[this], s__xefx_b[this], s__xefx_a[this])
       endfunction
//end of: XEFX_colorstuff("red","r")
//textmacro instance: XEFX_colorstuff("green","g")
       function s__xefx__get_green takes integer this returns integer
           return s__xefx_g[this]
       endfunction
       function s__xefx__set_green takes integer this,integer value returns nothing
           set s__xefx_g[this]=value
           call SetUnitVertexColor(s__xefx_dummy[this], s__xefx_r[this], s__xefx_g[this], s__xefx_b[this], s__xefx_a[this])
       endfunction
//end of: XEFX_colorstuff("green","g")
//textmacro instance: XEFX_colorstuff("blue","b")
       function s__xefx__get_blue takes integer this returns integer
           return s__xefx_b[this]
       endfunction
       function s__xefx__set_blue takes integer this,integer value returns nothing
           set s__xefx_b[this]=value
           call SetUnitVertexColor(s__xefx_dummy[this], s__xefx_r[this], s__xefx_g[this], s__xefx_b[this], s__xefx_a[this])
       endfunction
//end of: XEFX_colorstuff("blue","b")
//textmacro instance: XEFX_colorstuff("alpha","a")
       function s__xefx__get_alpha takes integer this returns integer
           return s__xefx_a[this]
       endfunction
       function s__xefx__set_alpha takes integer this,integer value returns nothing
           set s__xefx_a[this]=value
           call SetUnitVertexColor(s__xefx_dummy[this], s__xefx_r[this], s__xefx_g[this], s__xefx_b[this], s__xefx_a[this])
       endfunction
//end of: XEFX_colorstuff("alpha","a")

       function s__xefx_recolor takes integer this,integer r,integer g,integer b,integer a returns nothing
           set s__xefx_r[this]=r
           set s__xefx_g[this]=g
           set s__xefx_b[this]=b
           set s__xefx_a[this]=a
           call SetUnitVertexColor(s__xefx_dummy[this], s__xefx_r[this], s__xefx_g[this], s__xefx_b[this], s__xefx_a[this])
       endfunction


       function s__xefx__get_abilityid takes integer this returns integer
           return s__xefx_abil[this]
       endfunction

       function s__xefx__set_abilityid takes integer this,integer a returns nothing
           if ( s__xefx_abil[this] != 0 ) then
               call UnitRemoveAbility(s__xefx_dummy[this], s__xefx_abil[this])
           endif

           if ( a != 0 ) then
               call UnitAddAbility(s__xefx_dummy[this], a)
           endif
           set s__xefx_abil[this]=a
       endfunction
       
       function s__xefx__get_abilityLevel takes integer this returns integer
           return GetUnitAbilityLevel(s__xefx_dummy[this], s__xefx_abil[this])
       endfunction
       
       function s__xefx__set_abilityLevel takes integer this,integer newLevel returns nothing
           call SetUnitAbilityLevel(s__xefx_dummy[this], s__xefx_abil[this], newLevel)
       endfunction

       function s__xefx_flash takes integer this,string fx returns nothing
           call DestroyEffect(AddSpecialEffectTarget(fx, s__xefx_dummy[this], "origin"))
       endfunction

       function s__xefx__get_xyangle takes integer this returns real
           return GetUnitFacing(s__xefx_dummy[this]) * bj_DEGTORAD
       endfunction
       function s__xefx__set_xyangle takes integer this,real value returns nothing
           call SetUnitFacing(s__xefx_dummy[this], value * bj_RADTODEG)
       endfunction

       function s__xefx__get_zangle takes integer this returns real
           return s__xefx_zang[this]
       endfunction

       function s__xefx__set_zangle takes integer this,real value returns nothing
        local integer i=R2I(value * bj_RADTODEG + 90.5)
           set s__xefx_zang[this]=value
           if ( i >= 180 ) then
               set i=179
           elseif ( i < 0 ) then
               set i=0
           endif
               
           call SetUnitAnimationByIndex(s__xefx_dummy[this], i)
       endfunction


       function s__xefx__get_x takes integer this returns real
           return GetUnitX(s__xefx_dummy[this])
       endfunction
       function s__xefx__get_y takes integer this returns real
           return GetUnitY(s__xefx_dummy[this])
       endfunction
       function s__xefx__get_z takes integer this returns real
           return GetUnitFlyHeight(s__xefx_dummy[this])
       endfunction

       function s__xefx__set_z takes integer this,real value returns nothing
           call SetUnitFlyHeight(s__xefx_dummy[this], value, 0)
       endfunction

       function s__xefx__set_x takes integer this,real value returns nothing
           call SetUnitX(s__xefx_dummy[this], value)
       endfunction

       function s__xefx__set_y takes integer this,real value returns nothing
           call SetUnitY(s__xefx_dummy[this], value)
       endfunction

       function s__xefx__set_fxpath takes integer this,string newpath returns nothing
           if ( s__xefx_fx[this] != null ) then
               call DestroyEffect(s__xefx_fx[this])
           endif
           if ( newpath == "" ) then
               set s__xefx_fx[this]=null
           else
               set s__xefx_fx[this]=AddSpecialEffectTarget(newpath, s__xefx_dummy[this], "origin")
           endif

       endfunction
       
       function s__xefx_hiddenReset takes integer this,string newfxpath,real newfacing returns nothing
        local real x= GetUnitX(s__xefx_dummy[this])
        local real y= GetUnitY(s__xefx_dummy[this])
        local real z= (GetUnitFlyHeight(s__xefx_dummy[(this)])) // INLINED!!
        local real za= (s__xefx_zang[(this)]) // INLINED!!
        local integer level= s__xefx__get_abilityLevel(this)
           call s__xefx__set_fxpath(this,null)
//#            static if xefx___RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then
                   if ( s__xefx_abil[this] != 0 ) then
                       call UnitRemoveAbility(s__xefx_dummy[this], s__xefx_abil[this])
                   endif
                   call s__xefx___recyclebin_create(s__xefx_dummy[this])
                   set s__xefx_dummy[this]=(s__xedummy___xedummy_new((Player(15) ) , (( x )*1.0) , (( y )*1.0) , (( newfacing * bj_RADTODEG)*1.0))) // INLINED!!
//#            else
//#                call RemoveUnit(this.dummy)
//#                set this.dummy= CreateUnit(Player(15), XE_DUMMY_UNITID, x,y, newfacing*bj_RADTODEG)
//#                call UnitAddAbility(this.dummy,XE_HEIGHT_ENABLER)
//#                call UnitAddAbility(this.dummy,'Aloc')
//#                call UnitRemoveAbility(this.dummy,XE_HEIGHT_ENABLER)
//#                call SetUnitX(this.dummy,x)
//#                call SetUnitY(this.dummy,y)
//#            endif
           call s__xefx__set_fxpath(this,newfxpath)
           if ( level != 0 ) then
               call UnitAddAbility(s__xefx_dummy[this], s__xefx_abil[this])
               call SetUnitAbilityLevel(s__xefx_dummy[this], s__xefx_abil[this], level)
           endif
           call SetUnitFlyHeight(s__xefx_dummy[(this)], ((z)*1.0), 0) // INLINED!!
           call s__xefx__set_zangle(this,za)
       endfunction


       function s__xefx_destroy takes integer this returns nothing
           if ( s__xefx_abil[this] != 0 ) then
               call UnitRemoveAbility(s__xefx_dummy[this], s__xefx_abil[this])
           endif
           if ( s__xefx_fx[this] != null ) then
               call DestroyEffect(s__xefx_fx[this])
               set s__xefx_fx[this]=null
           endif
           call s__xefx___recyclebin_create(s__xefx_dummy[this])
           set s__xefx_dummy[this]=null
           call s__xefx_deallocate(this)
       endfunction

       function s__xefx_hiddenDestroy takes integer this returns nothing
           call ShowUnit(s__xefx_dummy[this], false)
           call s__xefx_destroy(this)
       endfunction
       


//endlibrary xefx
//library StormyDreams
//**************************************************************************************
//* StormyDreams
//* ------------
//*  Author: Vexorian.
//*  Requirements:
//*      - xecast, xefx, xepreload
//*      - The Table library
//*      - A triggerer ability, with a point target. An example would be
//*        the StormyDreams ability you can find in this map's object editor.
//*      * If you want the synergy/enable bonus casting you need:
//*           - An ability to cast, for example the default is a parasite based
//*             ability called 
//*      * Synergy is based on the level of an ability specified by BONUS_SPELL_ID
//*        it could then be a passive/active ability, or a buff.
//*      
//*************************************************************************************


   //==================================================================================
   // Config:
   //
   //

   function StormyDreams___castOrderId takes nothing returns integer
       return OrderId("parasite") //sorry, but it turns out these things can't be declared on global init
   endfunction

   ////
   // Some config functions:
   // -
   // radius:            "Radius", somehow determines the curve
   // speed :            Missile speed
   // maxBolts:          Max number of missiles.
   // missileCollision:  Collision size of the missile
   // damage:            Damage done by the missile during contact.
   // missileDistance:   Initial target distance (for the first missile)
   // distanceIncrement: How much the distance is incremented per missile.  
   // castRecycleDelay:  How much to wait before recycling the caster.

   function StormyDreams___radius takes real level returns real
       return level * 0.0 + 200.0
   endfunction

   function StormyDreams___speed takes integer level returns integer
       return level * 0 + 500
   endfunction

   function StormyDreams___maxBolts takes integer level returns integer
       return 6 + level * 0
   endfunction

   function StormyDreams___missileCollision takes real level,real bonuslevel returns real
       return 0.0 * level + 0.0 * bonuslevel + 100.0 //65.0
   endfunction

   function StormyDreams___damage takes real level,real bonuslevel returns real
       return 11 * level + 5 * bonuslevel + 4.0
   endfunction

   function StormyDreams___missileScale takes real level,real bonuslevel returns real
       return 1.0 + level * 0.0 + bonuslevel * 1.1
   endfunction

   function StormyDreams___initialDistance takes real level,real bonuslevel returns real
       return 500.0 + 0 * level + 0 * bonuslevel
   endfunction

   function StormyDreams___distanceIncrement takes real level,real bonuslevel returns real
       return 100.0 + 0 * level + 0 * bonuslevel
   endfunction

   function StormyDreams___castRecycleDelay takes real level,real bonuslevel returns real
       return 5.0 * level + 0.0 * bonuslevel + 0.0
   endfunction


   function StormyDreams___configDamage takes integer level,integer bonuslevel,integer d returns nothing
   //Read xedamage's documentation to know how to configure this.
   //does not support damagetrees

       call s__xedamage_useSpecialEffect(d,GetAbilityEffectById('AOcl', EFFECT_TYPE_TARGET, 0) , "origin")
           set s__xedamage_tag[d]=666

           set s__xedamage_damageAllies[d]=true //True if you want it to hurt allies.
           set s__xedamage_atype[d]=ATTACK_TYPE_NORMAL // NORMAL (spell) attacktype
           call s__xedamage__set_exception(d,UNIT_TYPE_FLYING) // Don't hit fliers

       if ( bonuslevel > 0 ) then //* The bonus version:
           set s__xedamage_dtype[d]=DAMAGE_TYPE_UNIVERSAL // UNIVERSAL damage, no building damage reduction

       else //* The normal version:
           set s__xedamage_dtype[d]=DAMAGE_TYPE_LIGHTNING // LIGHTNING (magical) damage,
           call s__xedamage_factor(d,UNIT_TYPE_STRUCTURE , 0.33) // does 1/3 damage to buildings.
       endif


   endfunction

//===============================================================================
// The code. Sample begins
//



   function StormyDreams___fetchFilterUnit takes nothing returns boolean
       set StormyDreams___U[StormyDreams___Un]=GetFilterUnit()
       set StormyDreams___Un=StormyDreams___Un + 1
       return false
   endfunction

function rf__StormyDreams___processThrow takes integer th returns nothing
    local integer m=s__StormyDreams___missile__allocate()
    local integer l=s__StormyDreams___throw_level[th]
    local real xk
    local real yk
    local real ang
    local real ang2
    local real dist
    local real ca
    local real sa


       if ( (m) > s__StormyDreams___missile_lastid ) then
           set s__StormyDreams___missile_lastid=(m)
           set s__StormyDreams___missile_targetlog[m]=CreateGroup()
       else
           call GroupClear(s__StormyDreams___missile_targetlog[m])
       endif
       call SetUnitTimeScale(s__StormyDreams___throw_u[th], StormyDreams___THROW_ANIMATION_SPEED)
       set s__StormyDreams___missile_x1[m]=GetUnitX(s__StormyDreams___throw_u[th])
       set s__StormyDreams___missile_y1[m]=GetUnitY(s__StormyDreams___throw_u[th])
       set ang=Atan2(s__StormyDreams___throw_ty[th] - s__StormyDreams___missile_y1[m], s__StormyDreams___throw_tx[th] - s__StormyDreams___missile_x1[m])

       set s__StormyDreams___missile_x1[m]=s__StormyDreams___missile_x1[m] + StormyDreams___INITIAL_OFFSET * Cos(ang)
       set s__StormyDreams___missile_y1[m]=s__StormyDreams___missile_y1[m] + StormyDreams___INITIAL_OFFSET * Sin(ang)

       
       if ( s__StormyDreams___throw_tog[th] == 0 ) then
           set s__StormyDreams___throw_tog[th]=1
           set ang2=ang + bj_PI / 2
       else
           set s__StormyDreams___throw_tog[th]=0
           set ang2=ang - bj_PI / 2
       endif
       set s__StormyDreams___missile_fx[m]=s__xefx_create(s__StormyDreams___missile_x1[m] , s__StormyDreams___missile_y1[m] , ang2)
       call SetUnitX(s__xefx_dummy[(s__StormyDreams___missile_fx[m])], ((s__StormyDreams___missile_x1[m])*1.0)) // INLINED!!
       call SetUnitY(s__xefx_dummy[(s__StormyDreams___missile_fx[m])], ((s__StormyDreams___missile_y1[m])*1.0)) // INLINED!!
       set s__StormyDreams___missile_bonuslevel[m]=s__StormyDreams___throw_bonuslevel[th]
       set s__StormyDreams___missile_level[m]=l

       if ( s__StormyDreams___throw_bonuslevel[th] > 0 ) then
           call s__xefx__set_fxpath(s__StormyDreams___missile_fx[m],StormyDreams___MODEL_PATH_MISSILE)
       else
           call s__xefx__set_fxpath(s__StormyDreams___missile_fx[m],StormyDreams___MODEL_PATH_BONUS_MISSILE)
       endif
       call s__xefx__set_scale(s__StormyDreams___missile_fx[m],(1.0 + ((l )*1.0) * 0.0 + (( s__StormyDreams___throw_bonuslevel[th])*1.0) * 1.1)) // INLINED!!
       call SetUnitFlyHeight(s__xefx_dummy[(s__StormyDreams___missile_fx[m])], ((StormyDreams___BEZIER_Z1)*1.0), 0) // INLINED!!
       
       set dist=(500.0 + 0 * ((l )*1.0) + 0 * (( s__StormyDreams___throw_bonuslevel[th])*1.0)) + s__StormyDreams___throw_donetimes[th] * (100.0 + 0 * ((l )*1.0) + 0 * (( s__StormyDreams___throw_bonuslevel[th])*1.0)) // INLINED!!
       set s__StormyDreams___missile_x4[m]=s__StormyDreams___missile_x1[m] + dist * Cos(ang)
       set s__StormyDreams___missile_y4[m]=s__StormyDreams___missile_y1[m] + dist * Sin(ang)
       set ca=(((l)*1.0) * 0.0 + 200.0) * Cos(ang2) // INLINED!!
       set sa=(((l)*1.0) * 0.0 + 200.0) * Sin(ang2) // INLINED!!
       set s__StormyDreams___missile_x3[m]=s__StormyDreams___missile_x4[m] - 4 * ca
       set s__StormyDreams___missile_y3[m]=s__StormyDreams___missile_y4[m] - 4 * sa

       set s__StormyDreams___missile_x2[m]=s__StormyDreams___missile_x1[m] + 3 * ca
       set s__StormyDreams___missile_y2[m]=s__StormyDreams___missile_y1[m] + 3 * sa

       call s__xefx__set_alpha(s__StormyDreams___missile_fx[m],StormyDreams___ALPHA_STARTING_VALUE)
       set dist=SquareRoot(( s__StormyDreams___missile_x4[m] - s__StormyDreams___missile_x1[m] ) * ( s__StormyDreams___missile_x4[m] - s__StormyDreams___missile_x1[m] ) + ( s__StormyDreams___missile_y4[m] - s__StormyDreams___missile_y1[m] ) * ( s__StormyDreams___missile_y4[m] - s__StormyDreams___missile_y1[m] )) //sqrt is necessary
       set s__StormyDreams___missile_inc[m]=( ((l) * 0 + 500) / dist ) * StormyDreams___CLOCK_TICK // INLINED!!

       set s__StormyDreams___missile_u[m]=s__StormyDreams___throw_u[th]
       set StormyDreams___V[StormyDreams___N]=m
       set StormyDreams___N=StormyDreams___N + 1

       set s__StormyDreams___throw_donetimes[th]=s__StormyDreams___throw_donetimes[th] + 1
       if ( s__StormyDreams___throw_donetimes[th] >= (6 + (l) * 0) ) then // INLINED!!
           call SetUnitTimeScale(s__StormyDreams___throw_u[th], StormyDreams___RESTORE_ANIMATION_SPEED)
           call SaveInteger(Table___ht, ((StormyDreams___Tab)), (GetHandleId(s__StormyDreams___throw_u[th])), ( 0)) // INLINED!!
set rf__return_boolean= true
return
       else
           set s__StormyDreams___throw_remaining[th]=StormyDreams___THROW_PERIOD
           // Having to type unnecessary returns makes vexorian a dull boy
           // Having to type unnecessary returns makes vexorian a dull boy
           // Having to type unnecessary returns makes vexorian a dull boy
           // Having to type unnecessary returns makes vexorian a dull boy
           // Having to type unnecessary returns makes vexorian a dull boy
           // Having to type unnecessary returns makes vexorian a dull boy
           // Having to type unnecessary returns makes vexorian a dull boy
           // Having to type unnecessary returns makes vexorian a dull boy
           // Having to type unnecessary returns makes vexorian a dull boy
           // Having to type unnecessary returns makes vexorian a dull boy


set rf__return_boolean= false
return
       endif
set rf__return_boolean= false
return
endfunction
function StormyDreams___processThrow takes integer th returns boolean
    call rf__StormyDreams___processThrow(th)
    return rf__return_boolean
endfunction

   function StormyDreams___onExpire takes nothing returns nothing
    local integer i=0
    local integer n=StormyDreams___N
    local integer m
    local integer th
    local real s
    local real x
    local real y
    local real z
    local boolean keep
    local integer j
    local integer ab
    local real fc
    local integer k

       //missile code
       set StormyDreams___N=0
       loop
           exitwhen i == n
           set m=StormyDreams___V[i]
           set s=s__StormyDreams___missile_s[m]
           set s=s + s__StormyDreams___missile_inc[m]
           set keep=true
           if ( s >= 1.000000001 ) then
               set s=1
               set keep=false
           endif
           set x=s * s * s * s__StormyDreams___missile_x4[m] + 3 * s * s * ( 1 - s ) * s__StormyDreams___missile_x3[m] + 3 * s * ( 1 - s ) * ( 1 - s ) * s__StormyDreams___missile_x2[m] + ( 1 - s ) * ( 1 - s ) * ( 1 - s ) * s__StormyDreams___missile_x1[m]
           set y=s * s * s * s__StormyDreams___missile_y4[m] + 3 * s * s * ( 1 - s ) * s__StormyDreams___missile_y3[m] + 3 * s * ( 1 - s ) * ( 1 - s ) * s__StormyDreams___missile_y2[m] + ( 1 - s ) * ( 1 - s ) * ( 1 - s ) * s__StormyDreams___missile_y1[m]
           set z=s * s * s * StormyDreams___BEZIER_Z4 + 3 * s * s * ( 1 - s ) * StormyDreams___BEZIER_Z3 + 3 * s * ( 1 - s ) * ( 1 - s ) * StormyDreams___BEZIER_Z2 + ( 1 - s ) * ( 1 - s ) * ( 1 - s ) * StormyDreams___BEZIER_Z1
           call SetUnitFacing(s__xefx_dummy[(s__StormyDreams___missile_fx[m])], ((Atan2(y - (GetUnitY(s__xefx_dummy[(s__StormyDreams___missile_fx[m])])), x - (GetUnitX(s__xefx_dummy[(s__StormyDreams___missile_fx[m])]))))*1.0) * bj_RADTODEG) // INLINED!!
           set s__StormyDreams___missile_flashtime[m]=s__StormyDreams___missile_flashtime[m] + StormyDreams___CLOCK_TICK
           call s__xefx__set_alpha(s__StormyDreams___missile_fx[m],(s__xefx_a[(s__StormyDreams___missile_fx[m])]) + R2I(StormyDreams___ALPHA_INCREMENT_PER_SECOND * StormyDreams___CLOCK_TICK + 0.5)) // INLINED!!
           if ( s__StormyDreams___missile_flashtime[m] >= StormyDreams___FLASH_FX_PERIOD ) then
               if ( s__StormyDreams___missile_bonuslevel[m] > 0 ) then
                   call s__xefx_flash(s__StormyDreams___missile_fx[m],StormyDreams___MODEL_PATH_BONUS_FLASH)
               else
                   call s__xefx_flash(s__StormyDreams___missile_fx[m],StormyDreams___MODEL_PATH_FLASH)
               endif
               set s__StormyDreams___missile_flashtime[m]=0
           endif
           call SetUnitX(s__xefx_dummy[(s__StormyDreams___missile_fx[m])], ((x)*1.0)) // INLINED!!
           call SetUnitY(s__xefx_dummy[(s__StormyDreams___missile_fx[m])], ((y)*1.0)) // INLINED!!
           set StormyDreams___Un=0
           call GroupEnumUnitsInRange(StormyDreams___enumgroup, x, y, (0.0 * ((s__StormyDreams___missile_level[m] )*1.0) + 0.0 * (( s__StormyDreams___missile_bonuslevel[m])*1.0) + 100.0) + XE_MAX_COLLISION_SIZE, StormyDreams___fetchunits) // INLINED!!
           set j=0
           set k=s__StormyDreams___missile_level[m] * ( StormyDreams___MAX_BONUS_LEVELS + 1 ) + s__StormyDreams___missile_bonuslevel[m] //let's save this array index for later.
           loop
               exitwhen ( j == StormyDreams___Un )
               if ( StormyDreams___U[j] != s__StormyDreams___missile_u[m] ) and ( IsUnitInRangeXY(StormyDreams___U[j], x, y, (0.0 * ((s__StormyDreams___missile_level[m] )*1.0) + 0.0 * (( s__StormyDreams___missile_bonuslevel[m])*1.0) + 100.0)) ) and not IsUnitInGroup(StormyDreams___U[j], s__StormyDreams___missile_targetlog[m]) then // INLINED!!
                   set fc=(s__xedamage_getTargetFactorCore((StormyDreams___damageconf[k]),(s__StormyDreams___missile_u[m] ) , ( StormyDreams___U[j]) , true)) // INLINED!!
                   if ( fc != 0.0 ) then
                       if ( s__StormyDreams___missile_level[m] >= StormyDreams___CAST_REQUIRED_LEVEL ) and ( s__StormyDreams___missile_bonuslevel[m] >= StormyDreams___CAST_REQUIRED_BONUSLEVEL ) then
                            set s__xecast_owningplayer[StormyDreams___Cast]=GetOwningPlayer(s__StormyDreams___missile_u[m])
                            set s__xecast_level[StormyDreams___Cast]=s__StormyDreams___missile_level[m]
                            set s__xecast_recycledelay[StormyDreams___Cast]=(5.0 * ((s__StormyDreams___missile_level[m] )*1.0) + 0.0 * (( s__StormyDreams___missile_bonuslevel[m])*1.0) + 0.0) // INLINED!!
                           call s__xecast_castOnTarget(StormyDreams___Cast,StormyDreams___U[j])
                       endif
                       call GroupAddUnit(s__StormyDreams___missile_targetlog[m], StormyDreams___U[j])
                       //notice we are usign forceValue, since we already know the factor, it is also possible to
                       // call damageTarget directly, but that means the system will calculate the factor twice for no reason.
                       call s__xedamage_damageTargetForceValue(StormyDreams___damageconf[k],s__StormyDreams___missile_u[m] , StormyDreams___U[j] , fc * (11 * ((s__StormyDreams___missile_level[m] )*1.0) + 5 * (( s__StormyDreams___missile_bonuslevel[m])*1.0) + 4.0)) // INLINED!!
                   endif
               endif
               set j=j + 1
           endloop

           if ( not keep ) then
               call s__xefx_destroy(s__StormyDreams___missile_fx[m])
               call GroupClear(s__StormyDreams___missile_targetlog[m])
               call s__StormyDreams___missile_deallocate(m)
           else
               set s__StormyDreams___missile_s[m]=s
               set StormyDreams___V[StormyDreams___N]=m
               set StormyDreams___N=StormyDreams___N + 1
           endif
           set i=i + 1
       endloop

       //now call throw code, supposedly this is not called as many times as missile code, so
       // we might as well use a function call...
       set n=StormyDreams___NT
       set StormyDreams___NT=0
       set i=0
       loop
           exitwhen ( i == n )
           set th=StormyDreams___VT[i]
           set s__StormyDreams___throw_remaining[th]=s__StormyDreams___throw_remaining[th] - StormyDreams___CLOCK_TICK
           if s__StormyDreams___throw_stop[th] or ( ( s__StormyDreams___throw_remaining[th] <= - 0.001 ) and StormyDreams___processThrow(th) ) then
               call SetUnitTimeScale(s__StormyDreams___throw_u[th], StormyDreams___RESTORE_ANIMATION_SPEED)
               call s__StormyDreams___throw_deallocate(th)
           else
               set StormyDreams___VT[StormyDreams___NT]=th
               set StormyDreams___NT=StormyDreams___NT + 1
           endif
           set i=i + 1
       endloop

       if ( StormyDreams___N == 0 ) and ( StormyDreams___NT == 0 ) then
           call PauseTimer(StormyDreams___T)
       endif
   endfunction

   function StormyDreams___onSpellEffect takes nothing returns nothing
    local location loc=GetSpellTargetLoc()
    local unit u=GetTriggerUnit()
    local integer th=s__StormyDreams___throw__allocate()

       call SaveInteger(Table___ht, ((StormyDreams___Tab)), (GetHandleId(u)), ( (th))) // INLINED!!
       set StormyDreams___VT[StormyDreams___NT]=th
       set s__StormyDreams___throw_level[th]=GetUnitAbilityLevel(u, StormyDreams___SPELL_ID)
       set s__StormyDreams___throw_bonuslevel[th]=GetUnitAbilityLevel(u, StormyDreams___BONUS_SPELL_ID)
       set s__StormyDreams___throw_remaining[th]=StormyDreams___INITIAL_THROW
       set s__StormyDreams___throw_tx[th]=GetLocationX(loc)
       set s__StormyDreams___throw_ty[th]=GetLocationY(loc)
       set s__StormyDreams___throw_u[th]=u
       set StormyDreams___NT=StormyDreams___NT + 1
       if ( StormyDreams___NT == 1 ) then
           call TimerStart(StormyDreams___T, StormyDreams___CLOCK_TICK, true, function StormyDreams___onExpire)
       endif

    set loc=null
    set u=null
   endfunction

   function StormyDreams___onSpellEnd takes nothing returns nothing
    local integer key=GetHandleId(GetTriggerUnit())
    local integer th=((LoadInteger(Table___ht, ((StormyDreams___Tab)), (key)))) // INLINED!!
       if ( th != 0 ) then
           set s__StormyDreams___throw_stop[th]=true
           call RemoveSavedInteger(Table___ht, ((StormyDreams___Tab)), (key)) // INLINED!!
       endif
   endfunction
   function StormyDreams___spellIdMatch takes nothing returns boolean
       return ( StormyDreams___SPELL_ID == GetSpellAbilityId() )
   endfunction

   //=====================================================================================================
   // Init stuff:
   //
   function StormyDreams___init takes nothing returns nothing
    local trigger t=CreateTrigger()
    local integer i
    local integer j
       call XE_PreloadAbility(StormyDreams___CAST_ABILITY_ID)
       set StormyDreams___Cast=s__xecast__allocate()
       set s__xecast_abilityid[StormyDreams___Cast]=StormyDreams___CAST_ABILITY_ID
       set s__xecast_oid[(StormyDreams___Cast)]=((OrderId("parasite"))) // INLINED!!
       set StormyDreams___enumgroup=CreateGroup()
       set StormyDreams___fetchunits=Condition(function StormyDreams___fetchFilterUnit)
       set StormyDreams___Tab=s__Table__allocate()
       set StormyDreams___T=CreateTimer()
       call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
       call TriggerAddCondition(t, Condition(function StormyDreams___spellIdMatch))
       call TriggerAddAction(t, function StormyDreams___onSpellEffect)
       set t=CreateTrigger()
       call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_ENDCAST)
       call TriggerAddCondition(t, Condition(function StormyDreams___spellIdMatch))
       call TriggerAddAction(t, function StormyDreams___onSpellEnd)

       set i=1

       loop
           exitwhen ( i > StormyDreams___MAX_SPELL_LEVELS )
           set j=0
           loop
               exitwhen ( j > StormyDreams___MAX_BONUS_LEVELS )
               set StormyDreams___damageconf[i * ( StormyDreams___MAX_BONUS_LEVELS + 1 ) + j]=s__xedamage__allocate()
               call StormyDreams___configDamage(i , j , StormyDreams___damageconf[i * ( StormyDreams___MAX_BONUS_LEVELS + 1 ) + j])
               set j=j + 1
           endloop
           set i=i + 1
       endloop


    set t=null
   endfunction

//endlibrary StormyDreams
//library xecollider
//****************************************************************
//*
//* xecollider 0.9
//* --------------
//*  A xecollider object is a special effect that has a collision
//* size that can trigger a hit event and also many options to
//* configure its automatic movement.
//*
//*  Please use .terminate() instead of .destroy() this ensures
//* that it will be safe to destroy it (else you would have to
//* worry about destroying it during the animation loop/etc.)
//*
//*  To use this struct is a little different than the other
//* current parts of xe. Instead of just creating the xecollider
//* (which works, but it would only be a xefx that can have speed)
//* you probably need to make it do something special on the
//* unit hit event... For this reason, you need to make a new
//* struct extending xecollider that declares an onUnitHit method
//* you may also declare a loopControl method, very useful, can
//* help you reduce 'attaching'.
//*
//****************************************************************

//================================================================

    //===========================================================================
    // So, this exists merely so you can declare your own event handler methods
    // if interfaces make your brain blow out, please skip the next four lines.
    //

    //===========================================================================
     // use terminate() instead of .destroy() to "kill" the collider.
     // don't worry, terminate will call destroy automatically.

        //============================================================================
        // delegates:
        //   We are delegating a xefx object so that people call all the xefx methods
        //  and member from a xecollider object. This means that from a user
        // perspective a xecollider is also an instance of xefx. 
        //
        //   Notable ones are: .x , .y , .fxpath and .z ,
        // check out xefx's documentation for more info.
        //

        //##==========================================================================
        // public variables:
        //

        // Movement speed for the missile.

        // Speed added per second (notice you can use a negative value here)

        // If there is acceleration, it is wise to have a cap...

                                         // direction angle, allows curved movement.


        //##==========================================================================
        // public methods:
        //

        //----
        // Well, it is a good idea to actually create the missiles.
        // notice that if your custom missile struct needs to declare its own create
        // method, you can call this as allocate(x,y,dir).
        //
        // Sorry, no Loc version.
        //
        function s__xecollider_create takes real x,real y,real dir returns integer
         local integer xc= s__xecollider__allocate()
            set s__xecollider_fx[xc]=s__xefx_create(x , y , dir)
            set s__xecollider_dir[xc]=dir
            set s__xecollider_V[s__xecollider_N]=xc
            set s__xecollider_N=s__xecollider_N + 1
            if ( s__xecollider_N == 1 ) then
                call TimerStart(s__xecollider_T, XE_ANIMATION_PERIOD, true, s__xecollider_timerLoopFunction)
            endif
            if ( s__xecollider_lastSeen < (xc) ) then //with this I do group recycling
                set s__xecollider_lastSeen=(xc)
                set s__xecollider_seen[xc]=CreateGroup()
            endif

         return xc
        endfunction

        //----
        // The direction is just the angle in radians to which the missile's model faces
        // and the automatic movement uses.
        //
        function s__xecollider__get_direction takes integer this returns real
            return s__xecollider_dir[this]
        endfunction
        function s__xecollider__set_direction takes integer this,real v returns nothing
            set s__xecollider_dir[this]=v
            call SetUnitFacing(s__xefx_dummy[(s__xecollider_fx[this])], ((v)*1.0) * bj_RADTODEG) // INLINED!!
        endfunction

        //----
        // The collisionSize
        //
        function s__xecollider__get_collisionSize takes integer this returns real
            return s__xecollider_csize[this]
        endfunction
        function s__xecollider__set_collisionSize takes integer this,real value returns nothing
            set s__xecollider_csize[this]=value
            //good long attribute name, but we use csize in the loop
            //don't worry this gets inlined, it would also be helpful if
            //I ever decide to add a control for assignment.
        endfunction



        //---
        // targetUnit is a unit to follow (or try to follow), notice that homing
        // options require an angleSpeed different to 0.0
        //
        function s__xecollider__get_targetUnit takes integer this returns unit
            return s__xecollider_homingTargetUnit[this]
        endfunction
        function s__xecollider__set_targetUnit takes integer this,unit u returns nothing
            if ( u == null ) then
                set s__xecollider_angleMode[this]=s__xecollider_ANGLE_NO_MOVEMENT
            else
                set s__xecollider_angleMode[this]=s__xecollider_ANGLE_HOMING_UNIT
            endif
            set s__xecollider_homingTargetUnit[this]=u
        endfunction

        //----
        // targetPoint is a point to reach (or try to reach), notice that homing
        // options require an angleSpeed different to 0.0
        //
        function s__xecollider_setTargetPoint takes integer this,real x,real y returns nothing
            set s__xecollider_angleMode[this]=s__xecollider_ANGLE_HOMING_POINT
            set s__xecollider_homingTargetX[this]=x
            set s__xecollider_homingTargetY[this]=y
        endfunction
        function s__xecollider_setTargetPointLoc takes integer this,location loc returns nothing
            set s__xecollider_angleMode[this]=s__xecollider_ANGLE_HOMING_POINT
            set s__xecollider_homingTargetX[this]=GetLocationX(loc)
            set s__xecollider_homingTargetY[this]=GetLocationY(loc)
        endfunction

        //----
        // Call this in case you used targetUnit or TargetPoint so the missile
        // forgets the order to home that target.
        //
        function s__xecollider_forgetTarget takes integer this returns nothing
            set s__xecollider_angleMode[this]=s__xecollider_ANGLE_NO_MOVEMENT
        endfunction
        
        function s__xecollider__get_rotating takes integer this returns boolean
            return ( s__xecollider_angleMode[this] == s__xecollider_ANGLE_ROTATING )
        endfunction
        function s__xecollider__set_rotating takes integer this,boolean val returns nothing
            if ( val ) then
                 set s__xecollider_angleMode[this]=s__xecollider_ANGLE_ROTATING
            elseif ( s__xecollider_angleMode[this] == s__xecollider_ANGLE_ROTATING ) then
                 set s__xecollider_angleMode[this]=s__xecollider_ANGLE_NO_MOVEMENT
            endif
        endfunction
        
        function s__xecollider_destroy takes integer this returns nothing
            call GroupClear(s__xecollider_seen[this])
            if ( s__xecollider_silent[this] ) then
                call s__xefx_hiddenDestroy(s__xecollider_fx[this])
            else
                call s__xefx_destroy(s__xecollider_fx[this])
            endif
            call sc__xecollider___eventHandler_deallocate(this)
        endfunction

        function s__xecollider_terminate takes integer this returns nothing
            set s__xecollider_dead[this]=true
            call s__xefx__set_fxpath(s__xecollider_fx[this],"")
        endfunction
        // declare hiddenDestroy so people don't call directly on the delegate xefx
        function s__xecollider_hiddenDestroy takes integer this returns nothing
            set s__xecollider_silent[this]=true
            call s__xecollider_terminate(this)
        endfunction


        //--------

        


       




        





        function s__xecollider_timerLoop takes nothing returns nothing
         local integer i=0
         local integer c=0
         local integer this
         local real d
         local real ns
         local real wa
         local real df1
         local real df2
         local unit u
         local group g

            loop
               exitwhen ( i == s__xecollider_N )

               set this=s__xecollider_V[i] //adopt-a-instance
               set s__xecollider_expirationTime[this]=s__xecollider_expirationTime[this] - XE_ANIMATION_PERIOD
               if ( s__xecollider_dead[this] or ( s__xecollider_expirationTime[this] <= 0.0 ) ) then
                   call s__xecollider_destroy(this)
               else
                   set ns=s__xecollider_angleSpeed[this] * XE_ANIMATION_PERIOD
                   if ( ns != 0.0 ) then
                       if ( s__xecollider_angleMode[this] == s__xecollider_ANGLE_HOMING_UNIT ) then
                           set u=s__xecollider_homingTargetUnit[this]
                           if ( ( GetUnitTypeId(u) == 0 ) or IsUnitType(u, UNIT_TYPE_DEAD) ) then
                               set s__xecollider_angleMode[this]=s__xecollider_ANGLE_NO_MOVEMENT
                               set s__xecollider_homingTargetUnit[this]=null
                           else
                               set s__xecollider_homingTargetX[this]=GetUnitX(u)
                               set s__xecollider_homingTargetY[this]=GetUnitY(u)
                           endif
                           set u=null
                       endif
                       if ( s__xecollider_angleMode[this] == s__xecollider_ANGLE_ROTATING ) then
                           //nothing (ns is already ns)
                       elseif ( s__xecollider_angleMode[this] != s__xecollider_ANGLE_NO_MOVEMENT ) then
                           if ( ns <= 0 ) then
                               set ns=- ns
                           endif
                           set wa=Atan2(s__xecollider_homingTargetY[this] - (GetUnitY(s__xefx_dummy[(s__xecollider_fx[this])])), s__xecollider_homingTargetX[this] - (GetUnitX(s__xefx_dummy[(s__xecollider_fx[this])]))) // INLINED!!

                           //if(wa<0.0) then
                           //    set wa=wa+PI2
                           //endif
                           set df1=wa - s__xecollider_dir[this]
                           set df2=( xecollider___PI2 + wa ) - s__xecollider_dir[this]

                           if ( df1 <= 0 ) then
                               if ( df2 <= 0 ) then
                                   if ( df2 >= df1 ) then
                                       set df1=df2
                                   endif
                               else
                                   if ( - df1 >= df2 ) then
                                       set df1=df2
                                   endif
                               endif
                           else
                               if ( df2 <= 0 ) then
                                   if ( - df2 <= df1 ) then
                                       set df1=df2
                                   endif
                               else
                                   if ( df2 <= df1 ) then
                                       set df1=df2
                                   endif
                               endif
                           endif
                           if ( df1 <= 0 ) then
                               if ( - df1 >= ns ) then
                                   set ns=- ns
                               else
                                   set ns=df1
                               endif
                           else
                               if ( df1 <= ns ) then
                                   set ns=df1
                               endif
                           endif

                       else
                            set ns=0
                       endif
                       set d=s__xecollider_dir[this]
                       set d=d + ns
                       if ( d >= xecollider___PI2 ) then
                           set d=d - xecollider___PI2
                       elseif ( d < 0 ) then
                           set d=d + xecollider___PI2
                       endif
                       set s__xecollider_dir[this]=d
                       call SetUnitFacing(s__xefx_dummy[(s__xecollider_fx[this])], ((d)*1.0) * bj_RADTODEG) // INLINED!!
                   endif

                   // function calls are expensive, damned we are, long code inside of loop
                   // correct software dev. tells us this should go to another function,
                   // but this is Jass, not real life.

                   set ns=s__xecollider_speed[this] + s__xecollider_acceleration[this] * XE_ANIMATION_PERIOD
                   if ( ns < s__xecollider_minSpeed[this] ) then
                       set ns=s__xecollider_minSpeed[this]
                   elseif ( ns > s__xecollider_maxSpeed[this] ) then
                       set ns=s__xecollider_maxSpeed[this]
                   endif
                   set d=( ( s__xecollider_speed[this] + ns ) / 2 ) * XE_ANIMATION_PERIOD
                   set s__xecollider_speed[this]=ns
                   set s__xecollider_newx=(GetUnitX(s__xefx_dummy[(s__xecollider_fx[this])])) + d * Cos(s__xecollider_dir[this]) // INLINED!!
                   set s__xecollider_newy=(GetUnitY(s__xefx_dummy[(s__xecollider_fx[this])])) + d * Sin(s__xecollider_dir[this]) // INLINED!!
                   call SetUnitX(s__xefx_dummy[(s__xecollider_fx[this])], ((s__xecollider_newx)*1.0)) // INLINED!!
                   call SetUnitY(s__xefx_dummy[(s__xecollider_fx[this])], ((s__xecollider_newy)*1.0)) // INLINED!!

                   call GroupEnumUnitsInRange(s__xecollider_enumGroup, s__xecollider_newx, s__xecollider_newy, s__xecollider_csize[this] + XE_MAX_COLLISION_SIZE, null)
                   loop
                       set u=FirstOfGroup(s__xecollider_enumGroup)
                       exitwhen u == null
                       call GroupRemoveUnit(s__xecollider_enumGroup, u)
                       if not IsUnitType(u, UNIT_TYPE_DEAD) and not ( s__xecollider_dead[this] ) and ( GetUnitTypeId(u) != XE_DUMMY_UNITID ) and IsUnitInRangeXY(u, s__xecollider_newx, s__xecollider_newy, s__xecollider_csize[this]) then
                           call GroupAddUnit(s__xecollider_tempGroup, u)
                           if not IsUnitInGroup(u, s__xecollider_seen[this]) then
                               call sc__xecollider___eventHandler_onUnitHit(this,u)
                           endif
                       endif
                   endloop

                   set g=s__xecollider_tempGroup
                   call GroupClear(s__xecollider_seen[this])
                   set s__xecollider_tempGroup=s__xecollider_seen[this]
                   set s__xecollider_seen[this]=g
                   set g=null

                   set s__xecollider_V[c]=this
                   set c=c + 1
                   if ( (st__xecollider___eventHandler_loopControl[si__xecollider___eventHandler_type[this]]!=null) and not s__xecollider_dead[this] ) then
                       call sc__xecollider___eventHandler_loopControl(this)
                   endif
               endif
               set i=i + 1
            endloop
            //call BJDebugMsg("}")
            set s__xecollider_N=c
            if ( c == 0 ) then
                call PauseTimer(s__xecollider_T)
            endif

        endfunction

        //============================================================================
        // you aren't supposed to call doInit yourself, try not to do it.
        //
        function s__xecollider_doInit takes nothing returns nothing
            set s__xecollider_enumGroup=CreateGroup()
            set s__xecollider_tempGroup=CreateGroup()
            set s__xecollider_timerLoopFunction=( function s__xecollider_timerLoop )
            set s__xecollider_T=CreateTimer()
        endfunction

    function xecollider___init takes nothing returns nothing
        call s__xecollider_doInit()
    endfunction

//endlibrary xecollider
//library xemissile
//****************************************************************
//*
//* xemissile 0.9
//* -------------
//*  A xemissile object is a special effect that moves like a
//* WC3's attack or spell missile.
//*
//*  Please use .terminate() instead of .destroy() this ensures
//* that it will be safe to destroy it (else you would have to
//* worry about destroying it during the animation loop/etc.)
//*
//*  This struct is used similarly to xecollider. Instead of just
//* creating the xemissile (which works, but it would only be a
//* xefx that can move like a missile) you probably need to make
//* it do something special when it reaches its target...
//* For this reason, you need to make a new struct extending
//* xemissile that declares an onHit method, you may also declare
//* a loopControl method.
//*
//****************************************************************


    //===========================================================================
    // So, this exists merely so you can declare your own event handler methods
    // if interfaces make your brain blow out, please skip the next four lines.
    //
    
    //===========================================================================


        // movement duration parameter.
        // xy movement parameters.
        // z movement parameters.
        // target parameters.
        
        
        function s__xemissile__missile__get_x takes integer this returns real
            return s__xemissile__missile_mx[this]
        endfunction
        function s__xemissile__missile__get_y takes integer this returns real
            return s__xemissile__missile_my[this]
        endfunction
        function s__xemissile__missile__get_z takes integer this returns real
            call MoveLocation(s__xemissile__missile_l, s__xemissile__missile_mx[this], s__xemissile__missile_my[this])
            return s__xemissile__missile_mz[this] - GetLocationZ(s__xemissile__missile_l)
        endfunction
        
        function s__xemissile__missile__set_x takes integer this,real r returns nothing
            set s__xemissile__missile_update[this]=true
            set s__xemissile__missile_mx[this]=r
        endfunction
        function s__xemissile__missile__set_y takes integer this,real r returns nothing
            set s__xemissile__missile_update[this]=true
            set s__xemissile__missile_my[this]=r
        endfunction
        function s__xemissile__missile__set_z takes integer this,real r returns nothing
            set s__xemissile__missile_update[this]=true
            call MoveLocation(s__xemissile__missile_l, s__xemissile__missile_mx[this], s__xemissile__missile_my[this])
            set s__xemissile__missile_mz[this]=r + GetLocationZ(s__xemissile__missile_l)
        endfunction

        function s__xemissile__missile__get_speed takes integer this returns real
            return s__xemissile__missile_mvxy[this] / XE_ANIMATION_PERIOD
        endfunction
        function s__xemissile__missile__set_speed takes integer this,real newspeed returns nothing
            local real factor=newspeed * XE_ANIMATION_PERIOD / s__xemissile__missile_mvxy[this]
            if newspeed <= 0.0 then
                 call BJDebugMsg("xemissile speed error: speed must be a non-zero positive value.")
                return
            endif
            set s__xemissile__missile_mvxy[this]=newspeed * XE_ANIMATION_PERIOD
            if s__xemissile__missile_launched[this] then
                set s__xemissile__missile_time[this]=s__xemissile__missile_time[this] / factor
                set s__xemissile__missile_mvx[this]=s__xemissile__missile_mvx[this] * factor
                set s__xemissile__missile_mvy[this]=s__xemissile__missile_mvy[this] * factor
                set s__xemissile__missile_mvz[this]=s__xemissile__missile_mvz[this] * factor
                set s__xemissile__missile_maz[this]=s__xemissile__missile_maz[this] * factor * factor
            endif
        endfunction

        function s__xemissile__missile__get_targetUnit takes integer this returns unit
            return s__xemissile__missile_tu[this]
        endfunction
        function s__xemissile__missile__set_targetUnit takes integer this,unit u returns nothing
            set s__xemissile__missile_update[this]=true
            set s__xemissile__missile_tu[this]=u
            set s__xemissile__missile_tx[this]=GetUnitX(u)
            set s__xemissile__missile_ty[this]=GetUnitY(u)
            call MoveLocation(s__xemissile__missile_l, s__xemissile__missile_tx[this], s__xemissile__missile_ty[this])
            set s__xemissile__missile_tz[this]=GetUnitFlyHeight(u) + GetLocationZ(s__xemissile__missile_l) + s__xemissile__missile_zoffset[this]
        endfunction
        
        function s__xemissile__missile_setTargetPoint takes integer this,real x,real y,real z returns nothing
            set s__xemissile__missile_update[this]=true
            set s__xemissile__missile_tu[this]=null
            set s__xemissile__missile_tx[this]=x
            set s__xemissile__missile_ty[this]=y
            call MoveLocation(s__xemissile__missile_l, s__xemissile__missile_tx[this], s__xemissile__missile_ty[this])
            set s__xemissile__missile_tz[this]=z + GetLocationZ(s__xemissile__missile_l)
        endfunction

        //-------- Missile launcher

        function s__xemissile__missile_launch takes integer this,real speed,real arc returns nothing
            local real dx=s__xemissile__missile_tx[this] - s__xemissile__missile_mx[this]
            local real dy=s__xemissile__missile_ty[this] - s__xemissile__missile_my[this]
            local real d=SquareRoot(dx * dx + dy * dy)
            local real a=Atan2(dy, dx)
            local real dz=s__xemissile__missile_tz[this] - s__xemissile__missile_mz[this]
            set s__xemissile__missile_mvxy[this]=speed * XE_ANIMATION_PERIOD
            if speed <= 0.0 then
                 call BJDebugMsg("xemissile launch error: speed must be a non-zero positive value.")
                return
            elseif d > 0.0 then
                set s__xemissile__missile_time[this]=d / speed
            else
                set s__xemissile__missile_time[this]=XE_ANIMATION_PERIOD
            endif
            set s__xemissile__missile_mvz[this]=( ( d * arc ) / ( s__xemissile__missile_time[this] / 4.0 ) + dz / s__xemissile__missile_time[this] ) * XE_ANIMATION_PERIOD // Do some mathemagics to get a proper arc.

            set s__xemissile__missile_dead[this]=s__xemissile__missile_dead[this] and not ( s__xemissile__missile_launched[this] ) // In case this is called from the onHit method to bounce the missile.
            
            if not s__xemissile__missile_dead[this] and not s__xemissile__missile_launched[this] then
                set s__xemissile__missile_launched[this]=true
                set s__xemissile__missile_V[s__xemissile__missile_N]=this
                set s__xemissile__missile_N=s__xemissile__missile_N + 1
                if ( s__xemissile__missile_N == 1 ) then
                    call TimerStart(s__xemissile__missile_T, XE_ANIMATION_PERIOD, true, s__xemissile__missile_timerLoopFunction)
                endif
            endif
        endfunction
        
        //-------- Constructors and destructors

        function s__xemissile__missile_create takes real x,real y,real z,real a returns integer
         local integer this=s__xemissile__missile__allocate()
            set s__xemissile__missile_mx[this]=x
            set s__xemissile__missile_my[this]=y
            call MoveLocation(s__xemissile__missile_l, x, y)
            set s__xemissile__missile_mz[this]=z + GetLocationZ(s__xemissile__missile_l)

            set s__xemissile__missile_fx[this]=s__xefx_create(x , y , a)
            call SetUnitFlyHeight(s__xefx_dummy[(s__xemissile__missile_fx[this])], ((z)*1.0), 0) // INLINED!!
         return this
        endfunction

        function s__xemissile__missile_destroy takes integer this returns nothing
            if ( s__xemissile__missile_silent[this] ) then
                call s__xefx_hiddenDestroy(s__xemissile__missile_fx[this])
            else
                call s__xefx_destroy(s__xemissile__missile_fx[this])
            endif
            call sc__xemissile__eventHandler_deallocate(this)
        endfunction

        function s__xemissile__missile_terminate takes integer this returns nothing
            set s__xemissile__missile_dead[this]=true
            call s__xefx__set_zangle(s__xemissile__missile_fx[this],0.0)
            call s__xefx__set_fxpath(s__xemissile__missile_fx[this],"")
        endfunction
        // declare hiddenDestroy so people don't call directly on the delegate xefx
        function s__xemissile__missile_hiddenDestroy takes integer this returns nothing
            set s__xemissile__missile_silent[this]=true
            call s__xemissile__missile_terminate(this)
        endfunction

        //-------- Main engine


        function s__xemissile__missile_timerLoop takes nothing returns nothing
         local integer i=0
         local integer c=0
         local integer this
         
         local real dx
         local real dy
         local real d
         local real a

            loop
                exitwhen ( i == s__xemissile__missile_N )

                set this=s__xemissile__missile_V[i] //adopt-a-instance
                if s__xemissile__missile_dead[this] then
                    set s__xemissile__missile_launched[this]=false
                    call s__xefx__set_zangle(s__xemissile__missile_fx[this],0.0)
                    call s__xemissile__missile_destroy(this)
                else
                    if s__xemissile__missile_tu[this] != null and GetUnitTypeId(s__xemissile__missile_tu[this]) != 0 then
                        set s__xemissile__missile_update[this]=true
                        set s__xemissile__missile_tx[this]=GetUnitX(s__xemissile__missile_tu[this])
                        set s__xemissile__missile_ty[this]=GetUnitY(s__xemissile__missile_tu[this])
                        call MoveLocation(s__xemissile__missile_l, s__xemissile__missile_tx[this], s__xemissile__missile_ty[this])
                        set s__xemissile__missile_tz[this]=GetUnitFlyHeight(s__xemissile__missile_tu[this]) + GetLocationZ(s__xemissile__missile_l) + s__xemissile__missile_zoffset[this]
                    endif
                    if s__xemissile__missile_update[this] then
                        set s__xemissile__missile_update[this]=false
                        set dx=s__xemissile__missile_tx[this] - s__xemissile__missile_mx[this]
                        set dy=s__xemissile__missile_ty[this] - s__xemissile__missile_my[this]
                        set d=SquareRoot(dx * dx + dy * dy)
                        set a=Atan2(dy, dx)
                        if d > 0.0 then
                            set s__xemissile__missile_time[this]=d / s__xemissile__missile_mvxy[this] * XE_ANIMATION_PERIOD
                        else
                            set s__xemissile__missile_time[this]=XE_ANIMATION_PERIOD
                        endif
                        set s__xemissile__missile_mvx[this]=Cos(a) * s__xemissile__missile_mvxy[this]
                        set s__xemissile__missile_mvy[this]=Sin(a) * s__xemissile__missile_mvxy[this]
                        call SetUnitFacing(s__xefx_dummy[(s__xemissile__missile_fx[this])], ((a)*1.0) * bj_RADTODEG) // INLINED!!
                        set s__xemissile__missile_maz[this]=2 * ( ( s__xemissile__missile_tz[this] - s__xemissile__missile_mz[this] ) / s__xemissile__missile_time[this] / s__xemissile__missile_time[this] * XE_ANIMATION_PERIOD * XE_ANIMATION_PERIOD - ( s__xemissile__missile_mvz[this] * XE_ANIMATION_PERIOD ) / s__xemissile__missile_time[this] )
                    endif
                    
                    set s__xemissile__missile_mx[this]=s__xemissile__missile_mx[this] + s__xemissile__missile_mvx[this]
                    set s__xemissile__missile_my[this]=s__xemissile__missile_my[this] + s__xemissile__missile_mvy[this]
                    set a=s__xemissile__missile_maz[this] / 2.0
                    set s__xemissile__missile_mvz[this]=s__xemissile__missile_mvz[this] + a
                    set s__xemissile__missile_mz[this]=s__xemissile__missile_mz[this] + s__xemissile__missile_mvz[this]
                    set s__xemissile__missile_mvz[this]=s__xemissile__missile_mvz[this] + a

                    call SetUnitX(s__xefx_dummy[(s__xemissile__missile_fx[this])], ((s__xemissile__missile_mx[this])*1.0)) // INLINED!!
                    call SetUnitY(s__xefx_dummy[(s__xemissile__missile_fx[this])], ((s__xemissile__missile_my[this])*1.0)) // INLINED!!
                    call MoveLocation(s__xemissile__missile_l, s__xemissile__missile_mx[this], s__xemissile__missile_my[this])
                    call SetUnitFlyHeight(s__xefx_dummy[(s__xemissile__missile_fx[this])], ((s__xemissile__missile_mz[this] - GetLocationZ(s__xemissile__missile_l))*1.0), 0) // INLINED!!
                    call s__xefx__set_zangle(s__xemissile__missile_fx[this],Atan2(s__xemissile__missile_mvz[this], s__xemissile__missile_mvxy[this]))
                    
                    set s__xemissile__missile_time[this]=s__xemissile__missile_time[this] - XE_ANIMATION_PERIOD
                    if s__xemissile__missile_time[this] <= 0.0 then
                        set s__xemissile__missile_dead[this]=true
                        call sc__xemissile__eventHandler_onHit(this)
                        if s__xemissile__missile_dead[this] then
                            call s__xefx__set_fxpath(s__xemissile__missile_fx[this],"")
                        endif
                    endif

                    set s__xemissile__missile_V[c]=this
                    set c=c + 1
                    if ( (st__xemissile__eventHandler_loopControl[si__xemissile__eventHandler_type[this]]!=null) and not s__xemissile__missile_dead[this] ) then
                        call sc__xemissile__eventHandler_loopControl(this)
                    endif
                endif
                set i=i + 1
            endloop
            set s__xemissile__missile_N=c
            if ( c == 0 ) then
                call PauseTimer(s__xemissile__missile_T)
            endif
        endfunction

        function s__xemissile__missile_onInit takes nothing returns nothing
            set s__xemissile__missile_timerLoopFunction=( function s__xemissile__missile_timerLoop )
            set s__xemissile__missile_T=CreateTimer()
        endfunction

    //===========================================================================

        function s__xemissile_create takes real x,real y,real z,real tx,real ty,real tz returns integer
         local integer xm= s__xemissile__allocate(x , y , z , Atan2(ty - y, tx - x))
            call s__xemissile__missile_setTargetPoint(xm,tx , ty , tz)
         return xm
        endfunction

        function s__xehomingmissile_create takes real x,real y,real z,unit target,real zoffset returns integer
         local integer xm= s__xehomingmissile__allocate(x , y , z , GetUnitX(target) , GetUnitY(target) , 0.0)
            set s__xemissile__missile_zoffset[xm]=zoffset
            call s__xemissile__missile__set_targetUnit(xm,target)
         return xm
        endfunction


//endlibrary xemissile
//library ChainInferno

    function ChainInferno__missileCount takes integer level returns integer
        return 3 + level
    endfunction
    function ChainInferno__missileMaxSpeed takes integer level returns real
        return 700.0 + level * 0.0
    endfunction
    function ChainInferno__missileMinSpeed takes integer level returns real
        return 100.0 + level * 0.0
    endfunction
    function ChainInferno__maxTargets takes integer level returns integer
        return 2 + 1 * level
    endfunction
    function ChainInferno__missileDamage takes integer level returns real
        return 15.0 + level * 3.0
    endfunction
    function ChainInferno__detectDistance takes integer level returns real
        return 1000.0 + 0.0 * level
    endfunction
    function ChainInferno__configMissile takes integer m,integer level returns nothing
        call SetUnitFlyHeight(s__xefx_dummy[(s__xecollider_fx[m])], ((60.0)*1.0), 0) // notice a xecollider object is used, and we can mess with these fields // in the config section like this thanks to OOPness. // In the case of this spell, maxSpeed and minSpeed are treated in a  // special way, so they do not get assigned by this function. // The movement height of each missile: //the duration of each missile // INLINED!!
        set s__xecollider_expirationTime[m]=5.0 + 0.0 * level
        call s__xefx__set_fxpath(s__xecollider_fx[m],"Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl") // The model used by the missile:
        set s__xecollider_csize[(m)]=((50.0 + level * 0.0)*1.0) // INLINED!!
        set s__xecollider_acceleration[m]=1200.0 + level * 0.0
        set s__xecollider_angleSpeed[m]=bj_PI * 4
    endfunction
    function ChainInferno__setupDamage takes integer xd,integer level returns nothing
        set s__xedamage_damageAllies[xd]=false // Hit enemies exclusively
        set s__xedamage_damageEnemies[xd]=true //
        set s__xedamage_damageNeutral[xd]=false //do not hit buildings
        call s__xedamage__set_exception(xd,UNIT_TYPE_STRUCTURE) // fire (magical) normal damage
        set s__xedamage_dtype[xd]=DAMAGE_TYPE_FIRE
        set s__xedamage_atype[xd]=ATTACK_TYPE_NORMAL
    endfunction
        function s__ChainInferno__missile_create takes real x,real y,real dir returns integer
            local integer this=s__ChainInferno__missile__allocate(x , y , dir)
            if ( s__ChainInferno__missile_targetLog[this] == null ) then
                set s__ChainInferno__missile_targetLog[this]=CreateGroup()
            endif
            call GroupClear(s__ChainInferno__missile_targetLog[this])
            return this
        endfunction
            function s__ChainInferno__missile_anon__0 takes nothing returns boolean
                local integer this=s__ChainInferno__missile_instance
                local unit picked=GetFilterUnit()
                local real dx=(GetUnitX(s__xefx_dummy[(s__xecollider_fx[this])])) - GetUnitX(picked) // INLINED!!
                local real dy=(GetUnitY(s__xefx_dummy[(s__xecollider_fx[this])])) - GetUnitY(picked) // INLINED!!
                local real dis=SquareRoot(dx * dx + dy * dy)
                if ( not ( IsUnitInGroup(picked, s__ChainInferno__missile_targetLog[this]) ) and ( picked != s__ChainInferno__missile_owner[this] ) and ( ( (s__xecollider_homingTargetUnit[(this)]) == null ) or ( dis < s__ChainInferno__missile_targetdist ) ) and (s__xedamage_getTargetFactorCore((ChainInferno__xdam[s__ChainInferno__missile_level[this]]),(s__ChainInferno__missile_owner[this] ) , ( picked) , false) != 0.0) ) then //Pick the best new target. // INLINED!!
                    set s__ChainInferno__missile_targetdist=dis
                    call s__xecollider__set_targetUnit(this,picked)
                endif
                set picked=null
                return false
            endfunction
        function s__ChainInferno__missile_onUnitHit takes integer this,unit hitUnit returns nothing
            if ( ( hitUnit != s__ChainInferno__missile_owner[this] ) and not ( IsUnitInGroup(hitUnit, s__ChainInferno__missile_targetLog[this]) ) ) then
                if ( not ( s__xedamage_damageTarget(ChainInferno__xdam[s__ChainInferno__missile_level[this]],s__ChainInferno__missile_owner[this] , hitUnit , (15.0 + (s__ChainInferno__missile_level[this]) * 3.0)) ) ) then // INLINED!!
                    return
                endif
                call s__xefx_flash(s__xecollider_fx[this],"Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl")
                call GroupAddUnit(s__ChainInferno__missile_targetLog[this], hitUnit)
                set s__ChainInferno__missile_targetCount[this]=s__ChainInferno__missile_targetCount[this] + 1
                if ( s__ChainInferno__missile_targetCount[this] == (2 + 1 * (s__ChainInferno__missile_level[this])) ) then // INLINED!!
                    call s__xecollider_terminate(this)
                    return
                endif
                if ( ( (s__xecollider_homingTargetUnit[(this)]) != hitUnit ) and ( (s__xecollider_homingTargetUnit[(this)]) != null ) ) then // INLINED!!
                    return
                endif
                set s__ChainInferno__missile_instance=this
                call s__xecollider__set_targetUnit(this,null)
                call GroupEnumUnitsInRange(ChainInferno__enumgroup, (GetUnitX(s__xefx_dummy[(s__xecollider_fx[this])])), (GetUnitY(s__xefx_dummy[(s__xecollider_fx[this])])), (1000.0 + 0.0 * (s__ChainInferno__missile_level[this])), Condition(function s__ChainInferno__missile_anon__0)) // INLINED!!
                if ( (s__xecollider_homingTargetUnit[(this)]) == null ) then // INLINED!!
                    set s__xecollider_angleSpeed[this]=0
                    set s__xecollider_angleMode[(this)]=s__xecollider_ANGLE_NO_MOVEMENT // INLINED!!
                endif
            endif
        endfunction
    function ChainInferno__onSpell takes nothing returns nothing
        local unit u=GetTriggerUnit()
        local integer level=GetUnitAbilityLevel(u, ChainInferno__SPELL_ID)
        local integer i
        local real tx=GetSpellTargetX()
        local real ty=GetSpellTargetY()
        local real x=GetUnitX(u)
        local real y=GetUnitY(u)
        local real f=Atan2(ty - y, tx - x)
        local integer m
        if ( ChainInferno__xdam[level] == 0 ) then //all array elements start at 0
            set ChainInferno__xdam[level]=s__xedamage__allocate() //the trick here is to init the xedamage instance for each level only when necessary.
            call ChainInferno__setupDamage(ChainInferno__xdam[level] , level)
        endif
        set i=0 //create a new missile:
        loop
        exitwhen ( i >= (3 + (level)) ) // INLINED!!
            set m=s__ChainInferno__missile_create(x + GetRandomReal(- ChainInferno__NOISE, ChainInferno__NOISE) , y + GetRandomReal(- ChainInferno__NOISE, ChainInferno__NOISE) , f) // NOISE works just as a random off-set for the missile position, it makes the spell look better.
            set s__ChainInferno__missile_owner[m]=u
            call s__xecollider__set_targetUnit(m,GetSpellTargetUnit())
            set s__ChainInferno__missile_level[m]=level
            call ChainInferno__configMissile(m , level) // call configMissile :
            set s__xecollider_maxSpeed[m]=(700.0 + (level) * 0.0) //This one is important, the secret to the looks of the spell is with doing these tricks, each // missile starts at a speed slower than the previous one, then the movement is accelerated // by missileAcceleration(level) until all the missiles have the same speed. // INLINED!!
            set s__xecollider_speed[m]=s__xecollider_maxSpeed[m] - ( s__xecollider_maxSpeed[m] - (100.0 + (level) * 0.0) ) * ( i + 1 ) / (3 + (level)) // INLINED!!
        set i=i + 1
        endloop
        set u=null
    endfunction
        function ChainInferno__anon__1 takes nothing returns boolean
            return GetSpellAbilityId() == ChainInferno__SPELL_ID
        endfunction
    function ChainInferno__onInit takes nothing returns nothing
        local trigger t=CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddAction(t, function ChainInferno__onSpell)
        call TriggerAddCondition(t, Condition(function ChainInferno__anon__1))
        set ChainInferno__enumgroup=CreateGroup() //let's init the enumgroup variable:
    endfunction

//endlibrary ChainInferno
//library FireNovaStrike
//**************************************************************************************
//* FireNovaStrike
//* ---------------
//*  A simple xedamage + xecollider demo.
//*  Requirements:
//*      - xecollider, xedamage
//*      - A triggerer ability, with a unit target. An example would be
//*        the FireNovaStrike ability you can find in this map's object editor.
//*      
//*************************************************************************************

   //==================================================================================
   // Config:
   //
   //

   //==================================================================================
   // Let's set the damage options up, this function takes a xedamage object d
   // which something else probably instantiated and we would like to configure.
   //
   function FireNovaStrike__setupDamageOptions takes integer d returns nothing
       set s__xedamage_dtype[d]=DAMAGE_TYPE_FIRE // Do spell, fire (magic) damage
       set s__xedamage_atype[d]=ATTACK_TYPE_NORMAL //

       call s__xedamage_factor(d,UNIT_TYPE_STRUCTURE , 0.5) //half damage to buildings.

       set s__xedamage_damageEnemies[d]=true // This evil spell pretty much hits
       set s__xedamage_damageAllies[d]=true // anything that is not invulnerable or
       set s__xedamage_damageNeutral[d]=true // the casting hero himSelf... it would
       set s__xedamage_damageSelf[d]=false // be quite dumb if it was able to hit the hero...

   endfunction

   //**********************************************************************************


   //==================================================================================
   //  FireBolt struct: to make your xecolliders (in case you wish to detect events...
   // you need to extend your own struct, see it as a convenience cause it also saves
   // you the problem of attaching stuff (see how I am saving the casting unit in
   // the missile's struct so I can do damage correctly)
   //
   //
                                              //* your FireBolt struct represents a xecollider as well

                           // helps us adding fields to the missile like this

       //==============================================================================
       // The missile's onUnitHit method is called everytime it hits a unit.
       // So this method is handling the unitHit event, nice?
       //
       function s__FireNovaStrike__FireBolt_onUnitHit takes integer this,unit hitunit returns nothing

           // We want the missile to 'die' automatically on impact, but we don't
           // want it to die on any impact, for example, when the missile is created
           // it will count as an impact with the casting hero... We are using xedamage's
           // damageSelf option to prevent the hero from being targeteable...

           // xedamage.allowedTarget returns true if under those options a unit would
           // be a valid target for the source, in this case, the source is the casting
           // hero (which we are retrieving from the struct's members)  while the target
           // is the unit that was just hit (which we are retrieving from the method's
           // argument)
           //
           if ( (s__xedamage_getTargetFactorCore((FireNovaStrike__damageOptions),(s__FireNovaStrike__FireBolt_castingHero[this] ) , ( hitunit) , false) != 0.0) ) then // INLINED!!

               //Let's make the unit look as if it is taking fire, how? Let's make a fireball effect explode on them:
               call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl", hitunit, "origin"))

               // We know it is a valid target, let's damage it?
               // we are retrieving the level from the struct's members, and it is used in
               // a simple damage formula, for every level the damage increases by 25.
               call s__xedamage_damageTarget(FireNovaStrike__damageOptions,s__FireNovaStrike__FireBolt_castingHero[this] , hitunit , s__FireNovaStrike__FireBolt_level[this] * 25.0)

               // We wish the missile to explode
               call s__xecollider_terminate(this)
           endif


       endfunction

       function s__FireNovaStrike__FireBolt_onDestroy takes integer this returns nothing
           set s__FireNovaStrike__FireBolt_castingHero[this]=null //perhaps it is a good idea to null it,
                                       //well, it isn't, but I am making a sample
                                       //of how to use onDestroy here!


           // call DestroyEffect( AddSpecialEffect(GetAbilityEffectById('AOcl',EFFECT_TYPE_TARGET,0) , this.x , this.y ) )
           // uncomment this and pretty lightning effects will appear whenever one of our fire bolts
           // dies, just so you notice how onDestroy is called both after someone calls terminate()
           // and after the expiration time ends...
       endfunction

       //===============================================================================
       // just for a sample will use the loopControl event, all right, will make the
       // missile 'flash' randomly. 
       //
       function s__FireNovaStrike__FireBolt_loopControl takes integer this returns nothing

           if ( GetRandomReal(0, 1) < 0.02 ) then //a random condition, 2% chance to flash
               
               //Please notice, a xecollider object also counts as a xefx, so all xefx's
               //methods and attributes count, in this case we are calling flash
               //
               //It makes a special effect's death animation appear on the missile.
               //
               call s__xefx_flash(s__xecollider_fx[this],"Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl")
           endif

           //Notice loopControl gets called for the missile every XE_ANIMATION_PERIOD seconds
       endfunction


   function FireNovaStrike__spellIdMatch takes nothing returns boolean
       return ( GetSpellAbilityId() == FireNovaStrike__SPELL_ID )
   endfunction

   function FireNovaStrike__onSpellEffect takes nothing returns nothing
    local integer i=0
    local unit tar= GetSpellTargetUnit()
    local unit hero= GetTriggerUnit()

    local real x
    local real y

    local integer fb

    local effect fx=  AddSpecialEffectTarget("Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl", tar, "origin")
                          // A warning effect, will destroy this later.




       loop
           exitwhen i == FireNovaStrike__FIREBALL_COUNT
           set x=GetUnitX(hero)
           set y=GetUnitY(hero)

           // We have pretty much most of the work up there with the fire bolt struct
           // and its fields and event handler methods.
           //
           // Let's finally capitalize that:
           //

           // The creation method for a xecollider object is (x,y, facing) 
           // in this case, we wish to create the fire bolt at the hero's position
           // facing? Since there are 20 missiles, we want to devide all those 2PI
           // radians in 20 equal parts...
           //
           set fb=s__FireNovaStrike__FireBolt__allocate(x , y , i * ( 2 * bj_PI ) / FireNovaStrike__FIREBALL_COUNT)

           call s__xefx__set_fxpath(s__xecollider_fx[fb],"Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl")
           // It is often a good idea to give them missiles a model... Let's use the
           // red dragon's missile model.

           set s__xecollider_speed[fb]=100.0 // We'll use acceleration for these bolts
           set s__xecollider_acceleration[fb]=250.0 // let them begin with a 100.0  speed, accelerate
           set s__xecollider_maxSpeed[fb]=1000.0 // them at a ratio of 250 per second, and cap the
                                        // speed at 1000.0



           call SetUnitFlyHeight(s__xefx_dummy[(s__xecollider_fx[fb])], ((20.0)*1.0), 0) // INLINED!!

           set s__xecollider_angleSpeed[fb]=1.5 // We'll like the firebolts to home to the spell's target
                                   // we'll first need to give it an angleSpeed, a value of
                                   // 1.5 puts it close to 85 degrees per second (remember
                                   // everything is in radians)
                                   // The angle speed is just how much can the direction
                                   // vary in a second, it determines the homing's accuracy.
                                   //
                                   // Notice how large values here turn the spell into some sort
                                   // of giant homing fire ball, while low values make it
                                   // much closer to a traditional nova. 

           call s__xecollider__set_targetUnit(fb,tar) // As I said, we want the firebolts to home towards
                                   // so, we use the targetUnit field for that.
                                   //
                                   // Try commenting that line out.

           set s__xecollider_expirationTime[fb]=GetRandomReal(2.0, 3.0)
           // expirationTime determines the duration of the missile, I made things interesting
           // by adding a call to random, so not all the fire missiles will end at the same time
           // looks less fabricated this way.

           // Now, this is good stuff, remember the FireBolt struct is not just a xecollider
           // it is also a custom struct we just declared, we added these fields since they
           // are useful for the missile's damage:
           //
           set s__FireNovaStrike__FireBolt_castingHero[fb]=hero
           set s__FireNovaStrike__FireBolt_level[fb]=GetUnitAbilityLevel(hero, FireNovaStrike__SPELL_ID)

           set i=i + 1
       endloop
       call TriggerSleepAction(0.0)
       call SetUnitAnimation(hero, "attack")
       call DestroyEffect(fx)

    set fx=null
    set tar=null // it is good to null handle variables at the end of a function...
    set hero=null
   endfunction

   //=====================================================================================================
   // Init stuff:
   //
   function FireNovaStrike__init takes nothing returns nothing
    local trigger t=CreateTrigger()

       // Initializing the damage options:
       set FireNovaStrike__damageOptions=s__xedamage__allocate() // first instanciate a xeobject.
       call FireNovaStrike__setupDamageOptions(FireNovaStrike__damageOptions) // now call the function we saw before.

       //Setting up the spell's trigger:
       call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
       call TriggerAddCondition(t, Condition(function FireNovaStrike__spellIdMatch))
       call TriggerAddAction(t, function FireNovaStrike__onSpellEffect)
    set t=null
   endfunction

//endlibrary FireNovaStrike
//library Fireblast
//**************************************************************************************
//* Fireblast
//* ---------------
//*  A simple xedamage + xemissile demo.
//*  Launches a large projectile which fires smaller projectiles at nearby enemy units
//* as it moves. When the large projectile lands, it will fire one last wave of smaller
//* projectiles at all nearby enemy units.
//*  Requirements:
//*      - xemissile, xedamage
//*      - A triggerer ability, with a point target. An example would be
//*        the Fireblast ability you can find in this map's object editor.
//*      
//*************************************************************************************

    //==================================================================================
    // Config:
    //
    //
    
    constant function Fireblast___Damage takes integer level returns real
        return 20.0 * level // How much damage each child missile deals.
    endfunction

    //==================================================================================
    // Let's set the damage options up, this function takes a xedamage object d
    // which something else probably instantiated and we would like to configure.
    //
    function Fireblast___setupDamageOptions takes integer d returns nothing
       set s__xedamage_dtype[d]=DAMAGE_TYPE_FIRE // Do spell, fire (magic) damage
       set s__xedamage_atype[d]=ATTACK_TYPE_NORMAL //

       call s__xedamage__set_exception(d,UNIT_TYPE_STRUCTURE) // Do not hit buildings.
       // For everything else, the default xedamage settings should do fine.
    endfunction

    //**********************************************************************************



    //==================================================================================
    //  FireblastChild struct: these are our damage-dealing missiles that deal damage.
    // If you have used xecollider before, this should look familiar: by extending an
    // xehomingmissile we can create our own custom homing missile that includes custom
    // data and code.
    //
    //

        //==============================================================================
        //  We can declare a custom create method for our missile, note the parameters used
        // when calling .allocate, they must match those of xehomingmissile's create method.
        //
        function s__FireblastChild_create takes unit caster,integer level,real x,real y,real z,unit target returns integer
         local integer this= s__FireblastChild__allocate(x , y , z , target , 60.0)

            // Let us configure our projectile's custom data:
            set s__FireblastChild_caster[this]=caster
            set s__FireblastChild_level[this]=level

            // Time to configure the delegate xefx properties:
            call s__xefx__set_fxpath(s__xemissile__missile_fx[this],Fireblast___CHILD_MODEL)
            call s__xefx__set_scale(s__xemissile__missile_fx[this],Fireblast___CHILD_SCALE)

            // Launch the newly created missile:
            call s__xemissile__missile_launch(this,Fireblast___CHILD_SPEED , Fireblast___CHILD_ARC)

         return this
        endfunction

        //==============================================================================
        //  The onHit method will be called when the missile reaches its target.
        // In this case, we use it to deal damage to the targeted unit.
        //
        function s__FireblastChild_onHit takes integer this returns nothing
            call s__xedamage_damageTarget(Fireblast___damageOptions,s__FireblastChild_caster[this] , (s__xemissile__missile_tu[(this)]) , (20.0 * (s__FireblastChild_level[this]))) // INLINED!!
        endfunction



    //==================================================================================
    //  FireblastMain struct: the main spell missile. Since it is not a homing missile,
    // it extends xemissile instead of xehomingmissile. Again, it contains custom data
    // and code that make it a different missile from the FireblastChild one.
    //
    //

        //==============================================================================
        //  We can declare a custom create method for our missile, note the parameters used
        // when calling .allocate, they must match those of xemissile's create method.
        //
        function s__FireblastMain_create takes unit caster,integer level,real tx,real ty returns integer
         local real x= GetUnitX(caster)
         local real y= GetUnitY(caster)
         local real z= GetUnitFlyHeight(caster) + Fireblast___MAIN_LAUNCH_OFFSET
         local integer this= s__FireblastMain__allocate(x , y , z , tx , ty , 0.0)

            // Let us configure our projectile's custom data:
            set s__FireblastMain_caster[this]=caster
            set s__FireblastMain_level[this]=level

            // Time to configure the delegate xefx properties:
            call s__xefx__set_fxpath(s__xemissile__missile_fx[this],Fireblast___MAIN_MODEL)
            call s__xefx__set_scale(s__xemissile__missile_fx[this],Fireblast___MAIN_SCALE)

            // Launch the newly created missile:
            call s__xemissile__missile_launch(this,Fireblast___MAIN_SPEED , Fireblast___MAIN_ARC)

         return this
        endfunction
        
     // Used for launching child missiles periodically:
     
     // Used for obtaining the closest target:
     
        function s__FireblastMain_targetEnum takes nothing returns boolean
         local unit u= GetFilterUnit()
         local real dx= GetUnitX(u) - (s__xemissile__missile_mx[(s__FireblastMain_current)]) // INLINED!!
         local real dy= GetUnitY(u) - (s__xemissile__missile_my[(s__FireblastMain_current)]) // INLINED!!
         local real distance= dx * dx + dy * dy
            if distance < s__FireblastMain_closestDistance and ( (s__xedamage_getTargetFactorCore((Fireblast___damageOptions),(s__FireblastMain_caster[s__FireblastMain_current] ) , ( u) , false) != 0.0) ) then // INLINED!!
                set s__FireblastMain_closestDistance=distance
                set s__FireblastMain_closestTarget=u
            endif
         set u=null
         return false
        endfunction

        //===============================================================================
        // Let us use the loopControl event to spawn the child missiles periodically.
        // We will also use this method to tweak the missile's trajectory.
        //
        function s__FireblastMain_loopControl takes integer this returns nothing
            // Notice loopControl gets called for the missile every XE_ANIMATION_PERIOD seconds
            set s__FireblastMain_launchtime[this]=s__FireblastMain_launchtime[this] + XE_ANIMATION_PERIOD
           
            // Fire a new child missile every LAUNCH_PERIOD seconds:
            // I use a loop in case LAUNCH_PERIOD is less than XE_ANIMATION_PERIOD,
            // in which case multiple missiles may get launched per update.
            loop
             exitwhen s__FireblastMain_launchtime[this] < Fireblast___LAUNCH_PERIOD
                set s__FireblastMain_launchtime[this]=s__FireblastMain_launchtime[this] - Fireblast___LAUNCH_PERIOD
                // Find the nearest enemy unit:
                set s__FireblastMain_current=this
                set s__FireblastMain_closestTarget=null
                set s__FireblastMain_closestDistance=Fireblast___TARGET_RADIUS * Fireblast___TARGET_RADIUS
                call GroupEnumUnitsInRange(s__FireblastMain_g, (s__xemissile__missile_mx[(this)]), (s__xemissile__missile_my[(this)]), Fireblast___TARGET_RADIUS, Condition(function s__FireblastMain_targetEnum)) // INLINED!!
                if s__FireblastMain_closestTarget != null then
                    // Create the child missile, its create method should handle the rest.
                    call s__FireblastChild_create(s__FireblastMain_caster[this] , s__FireblastMain_level[this] , (s__xemissile__missile_mx[(this)]) , (s__xemissile__missile_my[(this)]) , s__xemissile__missile__get_z(this) , s__FireblastMain_closestTarget) // INLINED!!
                endif
            endloop
           
            // Also, constantly re-launch the missile to get a more unique movement arc
            call s__xemissile__missile_launch(this,Fireblast___MAIN_SPEED , Fireblast___MAIN_ARC)
        endfunction
        
        //==============================================================================

        function s__FireblastMain_finalEnum takes nothing returns boolean
         local unit u= GetFilterUnit()
         local integer this= s__FireblastMain_current
            if ( (s__xedamage_getTargetFactorCore((Fireblast___damageOptions),(s__FireblastMain_caster[this] ) , ( u) , false) != 0.0) ) then // INLINED!!
                call s__FireblastChild_create(s__FireblastMain_caster[this] , s__FireblastMain_level[this] , (s__xemissile__missile_mx[(this)]) , (s__xemissile__missile_my[(this)]) , s__xemissile__missile__get_z(this) , u) // INLINED!!
            endif
         set u=null
         return false
        endfunction

        //==============================================================================
        //  The onHit method will be called when the missile reaches its target.
        // In this case, we use it to spawn one last wave of child missiles.
        // We could also do this in the onDestroy method, in that case the last
        // wave of missiles would be launched even if the main missile was
        // prematurely terminated.
        //
        function s__FireblastMain_onHit takes integer this returns nothing
            set s__FireblastMain_current=this
            call GroupEnumUnitsInRange(s__FireblastMain_g, (s__xemissile__missile_mx[(this)]), (s__xemissile__missile_my[(this)]), Fireblast___TARGET_RADIUS, Condition(function s__FireblastMain_finalEnum)) // INLINED!!
        endfunction




   //=====================================================================================================

    function Fireblast___spellIdMatch takes nothing returns boolean
        return ( GetSpellAbilityId() == Fireblast___SPELL_ID )
    endfunction

    function Fireblast___onSpellEffect takes nothing returns nothing
     local real tx= GetSpellTargetX()
     local real ty= GetSpellTargetY()
     local unit hero= GetTriggerUnit()
     local integer level= GetUnitAbilityLevel(hero, Fireblast___SPELL_ID)
    
     local integer fb= s__FireblastMain_create(hero , level , tx , ty)

     set hero=null // it is good to null handle variables at the end of a function...
    endfunction

   //=====================================================================================================
   // Init stuff:
   //
   function Fireblast___Init takes nothing returns nothing
    local trigger t=CreateTrigger()

        // Initializing the damage options:
        set Fireblast___damageOptions=s__xedamage__allocate() // first instanciate a xeobject.
        call Fireblast___setupDamageOptions(Fireblast___damageOptions) // now call the function we saw before.

        //Setting up the spell's trigger:
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function Fireblast___spellIdMatch))
        call TriggerAddAction(t, function Fireblast___onSpellEffect)
     set t=null
    endfunction

//endlibrary Fireblast
//===========================================================================
// 
// xe 0.9
// 
//   Warcraft III map script
//   Generated by the Warcraft III World Editor
//   Date: Mon Dec 12 18:00:00 2011
//   Map Author: Vexorian, Anitarf, Blizzard(map)
// 
//===========================================================================

//***************************************************************************
//*
//*  Global Variables
//*
//***************************************************************************


function InitGlobals takes nothing returns nothing
endfunction

//***************************************************************************
//*
//*  Unit Item Tables
//*
//***************************************************************************

function Unit000022_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 4), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000027_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_CHARGED, 3), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000037_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000038_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_CHARGED, 3), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000041_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 3), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000043_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 3), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem('rwat', 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000046_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 4), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000047_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 4), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000048_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000051_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 3), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem('rwat', 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000059_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 4), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000061_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000063_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000065_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000068_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000073_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000078_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_CHARGED, 3), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000081_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000086_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 5), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000088_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000089_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 5), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000090_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_CHARGED, 3), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000092_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000093_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem('rhe2', 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000094_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000098_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000103_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000106_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 2), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000110_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_PERMANENT, 3), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

        // Item set 1
        call RandomDistReset()
        call RandomDistAddItem(ChooseRandomItemEx(ITEM_TYPE_POWERUP, 1), 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Unit000114_DropItems takes nothing returns nothing
    local widget trigWidget= null
    local unit trigUnit= null
    local integer itemID= 0
    local boolean canDrop= true

    set trigWidget=bj_lastDyingWidget
    if ( trigWidget == null ) then
        set trigUnit=GetTriggerUnit()
    endif

    if ( trigUnit != null ) then
        set canDrop=not IsUnitHidden(trigUnit)
        if ( canDrop and GetChangingUnit() != null ) then
            set canDrop=( GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
        endif
    endif

    if ( canDrop ) then
        // Item set 0
        call RandomDistReset()
        call RandomDistAddItem('rhe2', 100)
        set itemID=RandomDistChoose()
        if ( trigUnit != null ) then
            call UnitDropItem(trigUnit, itemID)
        else
            call WidgetDropItem(trigWidget, itemID)
        endif

    endif

    set bj_lastDyingWidget=null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction


//***************************************************************************
//*
//*  Items
//*
//***************************************************************************

function CreateAllItems takes nothing returns nothing
    local integer itemID

    call CreateItem('I001', - 512.3, 466.9)
endfunction

//***************************************************************************
//*
//*  Unit Creation
//*
//***************************************************************************

//===========================================================================
function CreateNeutralHostile takes nothing returns nothing
    local player p= Player(PLAYER_NEUTRAL_AGGRESSIVE)
    local unit u
    local integer unitID
    local trigger t
    local real life

    set u=CreateUnit(p, 'nmrr', 4084.1, - 3575.0, 154.804)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nogl', 4621.4, 4324.2, 233.760)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000089_DropItems)
    set u=CreateUnit(p, 'ntrg', - 3976.1, 3593.6, 311.370)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000041_DropItems)
    set u=CreateUnit(p, 'nftb', 4535.7, 4627.7, 255.283)
    set u=CreateUnit(p, 'nftb', 4828.3, 4297.5, 191.098)
    set u=CreateUnit(p, 'nogr', 4690.8, 4124.2, 225.468)
    set u=CreateUnit(p, 'nogr', 4443.7, 4281.5, 221.065)
    set u=CreateUnit(p, 'nomg', - 2789.3, - 3501.1, 44.490)
    call SetUnitState(u, UNIT_STATE_MANA, 0)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000043_DropItems)
    set u=CreateUnit(p, 'nomg', - 3852.7, - 4890.5, 57.770)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000093_DropItems)
    set u=CreateUnit(p, 'nftt', - 2703.1, - 3706.6, 51.115)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftt', - 2989.1, - 3409.7, 20.930)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000098_DropItems)
    set u=CreateUnit(p, 'ntrg', 137.3, - 2685.8, 130.730)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000038_DropItems)
    set u=CreateUnit(p, 'ntrt', - 20.7, - 2876.7, 154.031)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nmrm', - 3799.5, 3698.2, 333.420)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrg', 2800.7, - 58.3, 145.500)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000078_DropItems)
    set u=CreateUnit(p, 'nmrm', 4242.8, - 3593.9, 165.818)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nmrr', 3964.6, - 3748.6, 129.869)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nomg', 3124.9, 2733.6, 227.390)
    call SetUnitState(u, UNIT_STATE_MANA, 0)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000051_DropItems)
    set u=CreateUnit(p, 'nmrm', 4065.5, - 3916.4, 165.818)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrg', 4275.6, - 3814.7, 163.070)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000110_DropItems)
    set u=CreateUnit(p, 'ntrt', 3881.2, - 732.1, 0.000)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000061_DropItems)
    set u=CreateUnit(p, 'ntrh', 3759.8, - 819.5, 254.169)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftt', 3018.4, 2930.2, 223.180)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000048_DropItems)
    set u=CreateUnit(p, 'nmrm', - 4103.5, 3374.9, 333.420)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nmrr', - 3722.5, 3502.1, 297.471)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nogr', 2973.2, 2765.5, 241.220)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nogr', 3235.3, 2573.2, 220.447)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nomg', 4414.0, 4481.8, 244.580)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000114_DropItems)
    set u=CreateUnit(p, 'ntrg', 336.1, 2010.8, 322.840)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000027_DropItems)
    set u=CreateUnit(p, 'ntrt', 373.5, 2246.8, 332.000)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrg', - 2299.5, - 751.2, 322.840)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000090_DropItems)
    set u=CreateUnit(p, 'ntrt', 2775.2, - 290.0, 174.368)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftt', 3327.8, 2716.8, 223.180)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nmrr', - 4113.2, 3168.9, 322.405)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrt', 2982.1, 69.8, 104.946)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrt', 142.8, 1960.2, 262.573)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrt', - 2283.4, - 502.1, 350.835)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nogr', - 2838.2, - 3291.4, 33.151)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrt', - 2405.4, - 914.1, 281.412)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nogl', - 4081.5, - 4687.7, 61.750)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000086_DropItems)
    set u=CreateUnit(p, 'nogr', - 2642.6, - 3575.1, 71.262)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrh', 3876.0, - 593.1, 23.262)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nogr', - 1183.1, - 5382.3, 87.270)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000081_DropItems)
    set u=CreateUnit(p, 'nogr', - 986.1, - 5452.0, 79.122)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftr', - 1215.4, - 5596.4, 59.813)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftr', - 1028.1, - 5637.2, 83.329)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrt', 1064.6, - 3659.8, 0.000)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000088_DropItems)
    set u=CreateUnit(p, 'nogr', 5190.2, 1437.3, 145.910)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000073_DropItems)
    set u=CreateUnit(p, 'nogr', 5210.5, 1662.2, 171.938)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftr', 5335.6, 1429.7, 152.630)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrt', 337.2, - 2580.7, 84.609)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftr', 5321.7, 1687.8, 176.146)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrh', 984.8, - 3780.4, 238.626)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nogr', 1572.9, 5482.1, 287.590)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000037_DropItems)
    set u=CreateUnit(p, 'nogr', 1296.0, 5473.7, 273.680)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftr', 1545.9, 5653.9, 254.371)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftr', 1364.1, 5623.6, 277.888)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nogr', - 5202.7, - 2150.2, 359.310)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000068_DropItems)
    set u=CreateUnit(p, 'nftk', - 5445.2, 1890.3, 303.390)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000022_DropItems)
    set u=CreateUnit(p, 'nogr', - 5154.5, - 2437.2, 7.669)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftr', - 5337.9, - 2247.4, 348.360)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftr', - 5254.6, - 2492.1, 11.877)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'nftb', - 4006.9, - 4906.4, 93.427)
    set u=CreateUnit(p, 'nftb', - 4291.4, - 4696.6, 29.242)
    set u=CreateUnit(p, 'nogr', - 4231.2, - 4500.9, 63.612)
    set u=CreateUnit(p, 'nogr', - 3892.9, - 4689.1, 59.209)
    set u=CreateUnit(p, 'nftk', - 2361.6, 4873.3, 303.390)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000047_DropItems)
    set u=CreateUnit(p, 'nftb', - 2540.7, 4867.8, 326.670)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000092_DropItems)
    set u=CreateUnit(p, 'nftk', 2789.3, - 5502.6, 114.870)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000059_DropItems)
    set u=CreateUnit(p, 'nftb', - 5624.3, 1884.8, 326.670)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000094_DropItems)
    set u=CreateUnit(p, 'nftb', - 5437.1, 2135.7, 301.627)
    set u=CreateUnit(p, 'nogr', - 5500.0, 1652.6, 327.682)
    set u=CreateUnit(p, 'nogr', - 5244.8, 1932.7, 300.611)
    set u=CreateUnit(p, 'nftk', 5477.2, - 2364.2, 114.870)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000046_DropItems)
    set u=CreateUnit(p, 'nftb', 5655.2, - 2385.3, 138.154)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000103_DropItems)
    set u=CreateUnit(p, 'nftb', - 2316.6, 5090.0, 301.627)
    set u=CreateUnit(p, 'nogr', - 2379.5, 4606.9, 327.682)
    set u=CreateUnit(p, 'nogr', - 2124.4, 4887.0, 300.611)
    set u=CreateUnit(p, 'nftb', 2967.2, - 5523.7, 138.154)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000106_DropItems)
    set u=CreateUnit(p, 'nftb', 5372.3, - 2546.5, 120.105)
    set u=CreateUnit(p, 'nogr', 5448.0, - 2065.3, 146.160)
    set u=CreateUnit(p, 'nogr', 5185.5, - 2338.5, 119.089)
    set u=CreateUnit(p, 'nftb', 2745.6, - 5705.0, 120.105)
    set u=CreateUnit(p, 'nogr', 2821.3, - 5223.8, 146.160)
    set u=CreateUnit(p, 'nogr', 2558.9, - 5497.0, 119.089)
    set u=CreateUnit(p, 'ntrh', 1177.4, - 3557.9, 345.607)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrt', - 3412.4, 20.0, 141.088)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000063_DropItems)
    set u=CreateUnit(p, 'ntrh', - 3514.8, - 119.0, 209.689)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrh', - 3333.5, 129.5, 57.040)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrt', - 384.0, 3071.4, 140.886)
    call SetUnitAcquireRange(u, 200.0)
    set t=CreateTrigger()
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DEATH)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_CHANGE_OWNER)
    call TriggerAddAction(t, function Unit000065_DropItems)
    set u=CreateUnit(p, 'ntrh', - 447.4, 2967.9, 217.359)
    call SetUnitAcquireRange(u, 200.0)
    set u=CreateUnit(p, 'ntrh', - 295.8, 3159.1, 348.891)
    call SetUnitAcquireRange(u, 200.0)
endfunction

//===========================================================================
function CreateNeutralPassiveBuildings takes nothing returns nothing
    local player p= Player(PLAYER_NEUTRAL_PASSIVE)
    local unit u
    local integer unitID
    local trigger t
    local real life

    set u=CreateUnit(p, 'ngol', - 5760.0, 2176.0, 270.000)
    call SetResourceAmount(u, 12500)
    set u=CreateUnit(p, 'ngol', 5888.0, - 2688.0, 270.000)
    call SetResourceAmount(u, 12500)
    set u=CreateUnit(p, 'ngol', - 2560.0, 5248.0, 270.000)
    call SetResourceAmount(u, 12500)
    set u=CreateUnit(p, 'ngol', 3072.0, - 5888.0, 270.000)
    call SetResourceAmount(u, 12500)
    set u=CreateUnit(p, 'ngol', 3072.0, - 256.0, 270.000)
    call SetResourceAmount(u, 15000)
    set u=CreateUnit(p, 'ngol', 256.0, - 2944.0, 270.000)
    call SetResourceAmount(u, 15000)
    set u=CreateUnit(p, 'ngol', 4800.0, 4544.0, 270.000)
    call SetResourceAmount(u, 10000)
    set u=CreateUnit(p, 'nmh0', - 4256.0, 3232.0, 270.000)
    set u=CreateUnit(p, 'ngol', - 4288.0, - 4928.0, 270.000)
    call SetResourceAmount(u, 10000)
    set u=CreateUnit(p, 'nmh1', 4192.0, - 4128.0, 270.000)
    set u=CreateUnit(p, 'nmh0', - 3872.0, 3936.0, 270.000)
    set u=CreateUnit(p, 'ngme', - 2944.0, - 3712.0, 270.000)
    set u=CreateUnit(p, 'nmh0', 4512.0, - 3552.0, 270.000)
    set u=CreateUnit(p, 'nmh0', 4512.0, - 3936.0, 270.000)
    set u=CreateUnit(p, 'ngme', 3264.0, 2944.0, 270.000)
    set u=CreateUnit(p, 'nmh1', - 4192.0, 3616.0, 270.000)
    set u=CreateUnit(p, 'ntav', 512.0, - 256.0, 270.000)
    call SetUnitColor(u, ConvertPlayerColor(0))
    set u=CreateUnit(p, 'ngol', 128.0, 2240.0, 270.000)
    call SetResourceAmount(u, 15000)
    set u=CreateUnit(p, 'ngol', - 2560.0, - 640.0, 270.000)
    call SetResourceAmount(u, 15000)
endfunction

//===========================================================================
function CreateNeutralPassive takes nothing returns nothing
    local player p= Player(PLAYER_NEUTRAL_PASSIVE)
    local unit u
    local integer unitID
    local trigger t
    local real life

    set u=CreateUnit(p, 'nech', 528.7, 100.3, 65.788)
    set u=CreateUnit(p, 'nfro', 2419.8, - 2830.5, 201.561)
    set u=CreateUnit(p, 'nfro', 3847.6, - 3612.3, 27.577)
    set u=CreateUnit(p, 'necr', 1347.5, - 4522.6, 327.095)
    set u=CreateUnit(p, 'necr', - 4379.1, - 4344.4, 31.081)
    set u=CreateUnit(p, 'necr', - 5218.1, 2268.3, 197.288)
    set u=CreateUnit(p, 'necr', - 2890.8, 4953.1, 15.480)
    set u=CreateUnit(p, 'necr', 4772.7, 3262.1, 98.473)
    set u=CreateUnit(p, 'necr', 5589.5, - 1303.4, 47.078)
    set u=CreateUnit(p, 'nech', 474.1, 1941.1, 0.989)
    set u=CreateUnit(p, 'nfro', - 4532.9, - 2144.6, 114.547)
    set u=CreateUnit(p, 'nfro', - 1341.2, - 3800.8, 127.764)
    set u=CreateUnit(p, 'nvul', 677.6, - 251.9, 285.170)
    set u=CreateUnit(p, 'nvul', 541.3, - 478.9, 332.270)
    set u=CreateUnit(p, 'nvul', 294.6, - 234.5, 139.717)
    set u=CreateUnit(p, 'nvul', 554.5, - 33.4, 235.741)
endfunction

//===========================================================================
function CreatePlayerBuildings takes nothing returns nothing
endfunction

//===========================================================================
function CreatePlayerUnits takes nothing returns nothing
endfunction

//===========================================================================
function CreateAllUnits takes nothing returns nothing
    call CreateNeutralPassiveBuildings()
    call CreatePlayerBuildings()
    call CreateNeutralHostile()
    call CreateNeutralPassive()
    call CreatePlayerUnits()
endfunction

//***************************************************************************
//*
//*  Triggers
//*
//***************************************************************************

//===========================================================================
// Trigger: Melee Initialization
//
// Default melee game initialization for all players
//===========================================================================
function Trig_Melee_Initialization_Actions takes nothing returns nothing
    call MeleeStartingVisibility()
    call MeleeStartingHeroLimit()
    call MeleeGrantHeroItems()
    call MeleeStartingResources()
    call MeleeClearExcessUnits()
    call MeleeStartingUnits()
    call MeleeStartingAI()
endfunction

//===========================================================================
function InitTrig_Melee_Initialization takes nothing returns nothing
    set gg_trg_Melee_Initialization=CreateTrigger()
    call TriggerAddAction(gg_trg_Melee_Initialization, function Trig_Melee_Initialization_Actions)
endfunction

//===========================================================================
// Trigger: xebasic
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0


//===========================================================================
// Trigger: xepreload
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: xedummy
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: xecast
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0

//===========================================================================
// Trigger: xefx
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0



//===========================================================================
// Trigger: xedamage
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0


//===========================================================================
// Trigger: xecollider
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0

//===========================================================================
// Trigger: xemissile
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: Table
//
// Table is not part of xe.
//===========================================================================


//===========================================================================
// Trigger: BoundSentinel
//===========================================================================

//===========================================================================
// Trigger: IllusionRune
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
//**********************************************
//* Rune of Illusions
//*
//* A quick sample for xecast
//*
//*
//I003 : rune of illusion
//A009 : Illusions (dummy)
//----------------------------------------------
// scope IllusionRune begins

    function IllusionRune___itemIdMatch takes nothing returns boolean
      return ( GetItemTypeId(GetManipulatedItem()) == 'I003' ) //matches I003 ...
    endfunction                                                 //

    //====================================================
    //: This time we'll use a single xecast instance for
    //: all the cases the rune is used. It is recommended
    //: to do this since it is more efficient.
    //
    function IllusionRune___setItUp takes nothing returns nothing
        set IllusionRune___cast=s__xecast__allocate() //  we do some basic setup
        set s__xecast_abilityid[IllusionRune___cast]='A009' //The ability Id for our dummy illusions ability
        set s__xecast_oid[(IllusionRune___cast)]=(852274) //The order id. // INLINED!!
        //: The illusions ability is a special case since it does not have an orderstring
        //  so we are just going to use its order id, every active ability has one,
        // I got the id using a detector trigger, but most people would prefer to use
        // the order id guide: http://www.wc3campaigns.net/tools/weu/ORDERIDS.xls
        //
        //
        //
    endfunction

    function IllusionRune___onItemPick takes nothing returns nothing
     local unit u= GetTriggerUnit()

        set s__xecast_owningplayer[IllusionRune___cast]=GetOwningPlayer(u) //* The owning player, determines who will own the illusion.
        call s__xecast_castOnTarget(IllusionRune___cast,u) //Let's call the castOnTarget method on the Triggering unit.

     set u=null
    endfunction


    function IllusionRune___init takes nothing returns nothing
     local trigger t=CreateTrigger()
       call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM) //: Unit pickups item
       call TriggerAddCondition(t, Condition(function IllusionRune___itemIdMatch)) //:
       call TriggerAddAction(t, function IllusionRune___onItemPick)

       call IllusionRune___setItUp() //call our xecast setup function...
    endfunction

// scope IllusionRune ends



//===========================================================================
// Trigger: SheepStaff
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
//**********************************************
//* Sheep staff.
//*
//* A quick sample for xecast.AOEloc
//*
//*

//----------------------------------------------
// scope SheepStaff begins

    function SheepStaff__spellIdMatch takes nothing returns boolean
      return ( GetSpellAbilityId() == 'A006' )
    endfunction

    function SheepStaff__onSpellCast takes nothing returns nothing
     local integer xc= s__xecast_createA()
     local unit u= GetTriggerUnit()
     local location loc= GetSpellTargetLoc()

        call SetUnitAnimation(u, "attack") // Let's focus on the look of the item cast for a second...


        //==============================================
        // Here, we do assignments:
        //
        set s__xecast_abilityid[xc]='A005' //* Cast ability A005
        set s__xecast_level[xc]=GetUnitAbilityLevel(u, 'A006') //* Same level as trigger ability
        set s__xecast_oid[(xc)]=OrderId(("polymorph")) //* The order is polymorph // INLINED!!
        set s__xecast_owningplayer[xc]=GetOwningPlayer(u) //* The owning player, determines targets and bounty credits
       
        call s__xecast_castOnAOELoc(xc,loc , 200.0) //* Our castOnAOE call, using the location version
                                                              //* A radius of 200.0
                                                              // Since createA was used, no need to destroy the xecast object

        call RemoveLocation(loc) //We need to clean the point.

     set loc=null
     set u=null
    endfunction


    function SheepStaff__init takes nothing returns nothing
     local trigger t=CreateTrigger()
        call TriggerAddCondition(t, Condition(function SheepStaff__spellIdMatch))
        call TriggerAddAction(t, function SheepStaff__onSpellCast)
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)

     set t=null
    endfunction

// scope SheepStaff ends



//===========================================================================
// Trigger: BiGreenFire
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
//**********************************************
//* Double gem of green fire!
//* --------------------------
//* A quick sample for xecollider
//*
//*

//----------------------------------------------
// scope BiGreenFire begins

    //
    //   Yes, usually you'll need to make a struct to use xecollider.
    // basically, xecolliders need to know what to do when they hit
    // something, when you make your own struct that extends xecollider
    // you can declare your own onUnitHit method that will be executed
    // everytime the collider hits a unit.
    //
    //   The good thing is that you can use this struct to store
    // the missile's information as well.
    //
        //
        // For example, I am storing the owner of the green missile here.
        // owner would be the hero that used the item.
        //

        //
        // So, the onUnitHit will fire whenever there is a collision
        // between the collider and some unit, notice you can use the
        // struct's members in this method, this is actualyl a xecollider
        // as well, so you can use all xecollider's members and methods in it.
        //
        function s__BiGreenFire___greenMissile_onUnitHit takes integer this,unit target returns nothing

            // Don't explode if the owner is "hit", often when creating the missile
            // it would think it hit the unit that created it...
            if ( s__BiGreenFire___greenMissile_owner[this] != target ) then

                // perform the damage stuff, credit the owner.
                call UnitDamageTarget(s__BiGreenFire___greenMissile_owner[this], target, 100.0, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS)

                // No, do not call .destroy(), terminate is better
                call s__xecollider_terminate(this)
            endif
        endfunction

    //
    // This is the function we set to run whenever the triggerer ability is 
    // casted.
    //
    function BiGreenFire___onSpellCast takes nothing returns nothing
     local unit u= GetTriggerUnit()
     local location loc= GetSpellTargetLoc()

     local real x= GetUnitX(u)
     local real y= GetUnitY(u)

     local real ang= Atan2(GetLocationY(loc) - y, GetLocationX(loc) - x)

     local real ang2
     local integer i

     local real mx
     local real my

     local integer xc

        call SetUnitAnimation(u, "attack") // Let's focus on the look of the item cast for a second...
        call TriggerSleepAction(0.0)

        // ang2 would be perpendicular to the other angle, we are using radians so to get
        // ang2 we add PI/2 which is equivalent to 90 degrees.
        set ang2=ang + bj_PI / 2
        set i=0 //
        loop // we are creating two missiles but that's too much hassle and repetitive
            exitwhen ( i == BiGreenFire___FIRE_BALL_COUNT ) // code, just use a loop and one trick for the angle you shall see bellow
            if ( ( i == BiGreenFire___FIRE_BALL_COUNT - 1 ) and ( ModuloInteger(BiGreenFire___FIRE_BALL_COUNT, 2) == 1 ) ) then
                set mx=x // When FIRE_BALL_COUNT is odd, create the last fire ball
                set my=y // right in the middle.
            else
                set mx=x + ( BiGreenFire___DISTANCE * ( i / 2 + 1 ) ) * Cos(ang2) //Getting the position for the missile using a polar 
                set my=y + ( BiGreenFire___DISTANCE * ( i / 2 + 1 ) ) * Sin(ang2) //projections. Increase distance by 75 every 2 steps.
            endif


            set xc=s__BiGreenFire___greenMissile__allocate(mx , my , ang) //create the missile, notice we are using greenMissile for create as well.
            
            // set the model path:
            call s__xefx__set_fxpath(s__xecollider_fx[xc],"Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl")

            // a flash, see xefx's readme, it just plays a dead animation.
            call s__xefx_flash(s__xecollider_fx[xc],"Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl")

            set s__xecollider_acceleration[xc]=1000.0 // The missile starts with a speed of 0, acceleration of 1000
            set s__xecollider_maxSpeed[xc]=500.0 // and a speed cap of 500.0,
            set s__xecollider_expirationTime[xc]=20000.0 // it expires after 2 seconds.
                                           // So, try visualizing those things

            call SetUnitFlyHeight(s__xefx_dummy[(s__xecollider_fx[xc])], ((50.0)*1.0), 0) // some height, since missiles often fly... // INLINED!!

            set s__BiGreenFire___greenMissile_owner[xc]=u // important stuff, see how our collider is using the greenMissile struct
                             // so we can assign the owner, as you saw above the owner determines
                             // what can hit the missile and who to credit the damage for.


            set ang2=bj_PI + ang2 //this is the trick, the second angle will be the opposite to the
                                   // current one.
            set i=i + 1
        endloop

        call RemoveLocation(loc) //We need to clean the point.

     set u=null
     set loc=null // good idea to null handle local variables.
    endfunction

    //:
    //:  Now some usual stuff, conditions, events... This is normal Jass, nothing to do with xecollider.
    //: So I think I can get away without commenting it...
    //:
    function BiGreenFire___spellIdMatch takes nothing returns boolean
      return ( GetSpellAbilityId() == 'A00A' )
    endfunction


    function BiGreenFire___init takes nothing returns nothing
     local trigger t=CreateTrigger()
        call TriggerAddCondition(t, Condition(function BiGreenFire___spellIdMatch))
        call TriggerAddAction(t, function BiGreenFire___onSpellCast)
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)

     set t=null
    endfunction

// scope BiGreenFire ends


//===========================================================================
// Trigger: FireNovaStrike
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0


//===========================================================================
// Trigger: StormyDreams
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0


//===========================================================================
// Trigger: ChainInferno
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
//===========================================================================
// Trigger: Fireblast
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
//===========================================================================
// Trigger: sandbox
//===========================================================================

//===========================================================================
// Trigger: DemoMap
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0


//library DemoMap initializer init requires CasterSystem, BoolexprUtils



//===========================================================================
function InitCustomTriggers takes nothing returns nothing
    call InitTrig_Melee_Initialization()
    //Function not found: call InitTrig_xebasic()
    //Function not found: call InitTrig_xepreload()
    //Function not found: call InitTrig_xedummy()
    //Function not found: call InitTrig_xecast()
    //Function not found: call InitTrig_xefx()
    //Function not found: call InitTrig_xedamage()
    //Function not found: call InitTrig_xecollider()
    //Function not found: call InitTrig_xemissile()
    //Function not found: call InitTrig_Table()
    //Function not found: call InitTrig_BoundSentinel()
    //Function not found: call InitTrig_IllusionRune()
    //Function not found: call InitTrig_SheepStaff()
    //Function not found: call InitTrig_BiGreenFire()
    //Function not found: call InitTrig_FireNovaStrike()
    //Function not found: call InitTrig_StormyDreams()
    //Function not found: call InitTrig_ChainInferno()
    //Function not found: call InitTrig_Fireblast()
    //Function not found: call InitTrig_sandbox()
    //Function not found: call InitTrig_DemoMap()
endfunction

//===========================================================================
function RunInitializationTriggers takes nothing returns nothing
    call ConditionalTriggerExecute(gg_trg_Melee_Initialization)
endfunction

//***************************************************************************
//*
//*  Players
//*
//***************************************************************************

function InitCustomPlayerSlots takes nothing returns nothing

    // Player 0
    call SetPlayerStartLocation(Player(0), 0)
    call SetPlayerColor(Player(0), ConvertPlayerColor(0))
    call SetPlayerRacePreference(Player(0), RACE_PREF_HUMAN)
    call SetPlayerRaceSelectable(Player(0), true)
    call SetPlayerController(Player(0), MAP_CONTROL_USER)

    // Player 1
    call SetPlayerStartLocation(Player(1), 1)
    call SetPlayerColor(Player(1), ConvertPlayerColor(1))
    call SetPlayerRacePreference(Player(1), RACE_PREF_ORC)
    call SetPlayerRaceSelectable(Player(1), true)
    call SetPlayerController(Player(1), MAP_CONTROL_USER)

    // Player 2
    call SetPlayerStartLocation(Player(2), 2)
    call SetPlayerColor(Player(2), ConvertPlayerColor(2))
    call SetPlayerRacePreference(Player(2), RACE_PREF_UNDEAD)
    call SetPlayerRaceSelectable(Player(2), true)
    call SetPlayerController(Player(2), MAP_CONTROL_USER)

    // Player 3
    call SetPlayerStartLocation(Player(3), 3)
    call SetPlayerColor(Player(3), ConvertPlayerColor(3))
    call SetPlayerRacePreference(Player(3), RACE_PREF_NIGHTELF)
    call SetPlayerRaceSelectable(Player(3), true)
    call SetPlayerController(Player(3), MAP_CONTROL_USER)

endfunction

function InitCustomTeams takes nothing returns nothing
    // Force: Force 1
    call SetPlayerTeam(Player(0), 0)
    call SetPlayerTeam(Player(1), 0)
    call SetPlayerTeam(Player(2), 0)
    call SetPlayerTeam(Player(3), 0)

endfunction

function InitAllyPriorities takes nothing returns nothing

    call SetStartLocPrioCount(0, 1)
    call SetStartLocPrio(0, 0, 3, MAP_LOC_PRIO_HIGH)

    call SetStartLocPrioCount(1, 1)
    call SetStartLocPrio(1, 0, 2, MAP_LOC_PRIO_HIGH)

    call SetStartLocPrioCount(2, 1)
    call SetStartLocPrio(2, 0, 1, MAP_LOC_PRIO_HIGH)

    call SetStartLocPrioCount(3, 1)
    call SetStartLocPrio(3, 0, 0, MAP_LOC_PRIO_HIGH)
endfunction

//***************************************************************************
//*
//*  Main Initialization
//*
//***************************************************************************

//===========================================================================
function main takes nothing returns nothing
    call SetCameraBounds(- 6656.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), - 6784.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM), 6656.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), 6528.0 - GetCameraMargin(CAMERA_MARGIN_TOP), - 6656.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), 6528.0 - GetCameraMargin(CAMERA_MARGIN_TOP), 6656.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), - 6784.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM))
    call SetDayNightModels("Environment\\DNC\\DNCLordaeron\\DNCLordaeronTerrain\\DNCLordaeronTerrain.mdl", "Environment\\DNC\\DNCLordaeron\\DNCLordaeronUnit\\DNCLordaeronUnit.mdl")
    call NewSoundEnvironment("Default")
    call SetAmbientDaySound("LordaeronSummerDay")
    call SetAmbientNightSound("LordaeronSummerNight")
    call SetMapMusic("Music", true, 0)
    call CreateAllItems()
    call CreateAllUnits()
    call InitBlizzard()

call ExecuteFunc("jasshelper__initstructs1803")
call ExecuteFunc("BoolexprUtils___init")
call ExecuteFunc("BoundSentinel__init")
call ExecuteFunc("DemoMap__init")
call ExecuteFunc("xecast__init")
call ExecuteFunc("xedamage__init")
call ExecuteFunc("xefx___init")
call ExecuteFunc("StormyDreams___init")
call ExecuteFunc("xecollider___init")
call ExecuteFunc("ChainInferno__onInit")
call ExecuteFunc("FireNovaStrike__init")
call ExecuteFunc("Fireblast___Init")
call IllusionRune___init()
call SheepStaff__init()
call BiGreenFire___init()

    call InitGlobals()
    call InitTrig_Melee_Initialization() // INLINED!!
    call ConditionalTriggerExecute(gg_trg_Melee_Initialization) // INLINED!!

endfunction

//***************************************************************************
//*
//*  Map Configuration
//*
//***************************************************************************

function config takes nothing returns nothing
    call SetMapName("TRIGSTR_020")
    call SetMapDescription("TRIGSTR_022")
    call SetPlayers(4)
    call SetTeams(4)
    call SetGamePlacement(MAP_PLACEMENT_TEAMS_TOGETHER)

    call DefineStartLocation(0, - 2112.0, 4608.0)
    call DefineStartLocation(1, 5376.0, - 2112.0)
    call DefineStartLocation(2, 2624.0, - 5248.0)
    call DefineStartLocation(3, - 5248.0, 1600.0)

    // Player setup
    call InitCustomPlayerSlots()
    call SetPlayerSlotAvailable(Player(0), MAP_CONTROL_USER)
    call SetPlayerSlotAvailable(Player(1), MAP_CONTROL_USER)
    call SetPlayerSlotAvailable(Player(2), MAP_CONTROL_USER)
    call SetPlayerSlotAvailable(Player(3), MAP_CONTROL_USER)
    call InitGenericPlayerSlots()
    call InitAllyPriorities()
endfunction




//Struct method generated initializers/callers:
function sa__Table___GTable_onDestroy takes nothing returns boolean
local integer this=f__arg_this
            call FlushChildHashtable(Table___ht, ((this))) // INLINED!!
   return true
endfunction
function sa__xemissile__missile_create takes nothing returns boolean
local real x=f__arg_real1
local real y=f__arg_real2
local real z=f__arg_real3
local real a=f__arg_real4
         local integer this=s__xemissile__missile__allocate()
            set s__xemissile__missile_mx[this]=x
            set s__xemissile__missile_my[this]=y
            call MoveLocation(s__xemissile__missile_l, x, y)
            set s__xemissile__missile_mz[this]=z + GetLocationZ(s__xemissile__missile_l)
            set s__xemissile__missile_fx[this]=s__xefx_create(x , y , a)
            call SetUnitFlyHeight(s__xefx_dummy[(s__xemissile__missile_fx[this])], ((z)*1.0), 0) // INLINED!!
set f__result_integer= this
   return true
endfunction
function sa__xecollider_create takes nothing returns boolean
local real x=f__arg_real1
local real y=f__arg_real2
local real dir=f__arg_real3
         local integer xc= s__xecollider__allocate()
            set s__xecollider_fx[xc]=s__xefx_create(x , y , dir)
            set s__xecollider_dir[xc]=dir
            set s__xecollider_V[s__xecollider_N]=xc
            set s__xecollider_N=s__xecollider_N + 1
            if ( s__xecollider_N == 1 ) then
                call TimerStart(s__xecollider_T, XE_ANIMATION_PERIOD, true, s__xecollider_timerLoopFunction)
            endif
            if ( s__xecollider_lastSeen < (xc) ) then //with this I do group recycling
                set s__xecollider_lastSeen=(xc)
                set s__xecollider_seen[xc]=CreateGroup()
            endif
set f__result_integer= xc
   return true
endfunction
function sa__BiGreenFire___greenMissile_onUnitHit takes nothing returns boolean
    call s__BiGreenFire___greenMissile_onUnitHit(f__arg_this,f__arg_unit1)
   return true
endfunction
function sa__xemissile_create takes nothing returns boolean
local real x=f__arg_real1
local real y=f__arg_real2
local real z=f__arg_real3
local real tx=f__arg_real4
local real ty=f__arg_real5
local real tz=f__arg_real6
         local integer xm= s__xemissile__allocate(x , y , z , Atan2(ty - y, tx - x))
            call s__xemissile__missile_setTargetPoint(xm,tx , ty , tz)
set f__result_integer= xm
   return true
endfunction
function sa__xehomingmissile_create takes nothing returns boolean
    set f__result_integer=s__xehomingmissile_create(f__arg_real1,f__arg_real2,f__arg_real3,f__arg_unit1,f__arg_real4)
   return true
endfunction
function sa__ChainInferno__missile_onUnitHit takes nothing returns boolean
    call s__ChainInferno__missile_onUnitHit(f__arg_this,f__arg_unit1)
   return true
endfunction
function sa__FireNovaStrike__FireBolt_onUnitHit takes nothing returns boolean
    call s__FireNovaStrike__FireBolt_onUnitHit(f__arg_this,f__arg_unit1)
   return true
endfunction
function sa__FireNovaStrike__FireBolt_onDestroy takes nothing returns boolean
local integer this=f__arg_this
           set s__FireNovaStrike__FireBolt_castingHero[this]=null //perhaps it is a good idea to null it,
    set f__arg_this=this
   return true
endfunction
function sa__FireNovaStrike__FireBolt_loopControl takes nothing returns boolean
local integer this=f__arg_this
           if ( GetRandomReal(0, 1) < 0.02 ) then //a random condition, 2% chance to flash
               call s__xefx_flash(s__xecollider_fx[this],"Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl")
           endif
   return true
endfunction
function sa__FireblastChild_onHit takes nothing returns boolean
local integer this=f__arg_this
            call s__xedamage_damageTarget(Fireblast___damageOptions,s__FireblastChild_caster[this] , (s__xemissile__missile_tu[(this)]) , (20.0 * (s__FireblastChild_level[this]))) // INLINED!!
   return true
endfunction
function sa__FireblastMain_loopControl takes nothing returns boolean
local integer this=f__arg_this
            set s__FireblastMain_launchtime[this]=s__FireblastMain_launchtime[this] + XE_ANIMATION_PERIOD
            loop
             exitwhen s__FireblastMain_launchtime[this] < Fireblast___LAUNCH_PERIOD
                set s__FireblastMain_launchtime[this]=s__FireblastMain_launchtime[this] - Fireblast___LAUNCH_PERIOD
                set s__FireblastMain_current=this
                set s__FireblastMain_closestTarget=null
                set s__FireblastMain_closestDistance=Fireblast___TARGET_RADIUS * Fireblast___TARGET_RADIUS
                call GroupEnumUnitsInRange(s__FireblastMain_g, (s__xemissile__missile_mx[(this)]), (s__xemissile__missile_my[(this)]), Fireblast___TARGET_RADIUS, Condition(function s__FireblastMain_targetEnum)) // INLINED!!
                if s__FireblastMain_closestTarget != null then
                    call s__FireblastChild_create(s__FireblastMain_caster[this] , s__FireblastMain_level[this] , (s__xemissile__missile_mx[(this)]) , (s__xemissile__missile_my[(this)]) , s__xemissile__missile__get_z(this) , s__FireblastMain_closestTarget) // INLINED!!
                endif
            endloop
            call s__xemissile__missile_launch(this,Fireblast___MAIN_SPEED , Fireblast___MAIN_ARC)
   return true
endfunction
function sa__FireblastMain_onHit takes nothing returns boolean
local integer this=f__arg_this
            set s__FireblastMain_current=this
            call GroupEnumUnitsInRange(s__FireblastMain_g, (s__xemissile__missile_mx[(this)]), (s__xemissile__missile_my[(this)]), Fireblast___TARGET_RADIUS, Condition(function s__FireblastMain_finalEnum)) // INLINED!!
   return true
endfunction
function sa___prototype11_xepreload__DebugIdInteger2IdString takes nothing returns boolean
 local integer value=f__arg_integer1

     local string charMap= ".................................!.#$%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."
     local string result= ""
     local integer remainingValue= value
     local integer charValue
     local integer byteno
     set byteno=0
     loop
         set charValue=ModuloInteger(remainingValue, 256)
         set remainingValue=remainingValue / 256
         set result=SubString(charMap, charValue, charValue + 1) + result
         set byteno=byteno + 1
         exitwhen byteno == 4
     endloop
    set f__result_string= result
    return true
endfunction

function jasshelper__initstructs1803 takes nothing returns nothing
    set st__Table___GTable_onDestroy[1]=CreateTrigger()
    set st__Table___GTable_onDestroy[2]=st__Table___GTable_onDestroy[1]
    set st__Table___GTable_onDestroy[3]=st__Table___GTable_onDestroy[1]
    set st__Table___GTable_onDestroy[4]=st__Table___GTable_onDestroy[1]
    call TriggerAddCondition(st__Table___GTable_onDestroy[1],Condition( function sa__Table___GTable_onDestroy))
    set st__xemissile__eventHandler_onHit[24]=null
    set st__xemissile__eventHandler_onHit[25]=null
    set st__xemissile__eventHandler_onHit[26]=null
    set st__xemissile__eventHandler_loopControl[24]=null
    set st__xemissile__eventHandler_loopControl[25]=null
    set st__xemissile__eventHandler_loopControl[26]=null
    set st__xemissile__eventHandler_loopControl[29]=null
    set st__xecollider___eventHandler_onUnitHit[22]=null
    set st__xecollider___eventHandler_loopControl[22]=null
    set st__xecollider___eventHandler_loopControl[27]=null
    set st__xecollider___eventHandler_loopControl[31]=null
    set st__xemissile__missile_create=CreateTrigger()
    call TriggerAddCondition(st__xemissile__missile_create,Condition( function sa__xemissile__missile_create))
    set st__xemissile__eventHandler_onDestroy[24]=null
    set st__xemissile__eventHandler_onDestroy[25]=null
    set st__xemissile__eventHandler_onDestroy[26]=null
    set st__xemissile__eventHandler_onDestroy[29]=null
    set st__xemissile__eventHandler_onDestroy[30]=null
    set st__xecollider_create=CreateTrigger()
    call TriggerAddCondition(st__xecollider_create,Condition( function sa__xecollider_create))
    set st__xecollider___eventHandler_onDestroy[22]=null
    set st__xecollider___eventHandler_onDestroy[27]=null
    set st__xecollider___eventHandler_onDestroy[31]=null
    set st__xecollider___eventHandler_onUnitHit[31]=CreateTrigger()
    call TriggerAddCondition(st__xecollider___eventHandler_onUnitHit[31],Condition( function sa__BiGreenFire___greenMissile_onUnitHit))
    call TriggerAddAction(st__xecollider___eventHandler_onUnitHit[31], function sa__BiGreenFire___greenMissile_onUnitHit)
    set st__xemissile_create=CreateTrigger()
    call TriggerAddCondition(st__xemissile_create,Condition( function sa__xemissile_create))
    set st__xehomingmissile_create=CreateTrigger()
    call TriggerAddCondition(st__xehomingmissile_create,Condition( function sa__xehomingmissile_create))
    set st__xecollider___eventHandler_onUnitHit[27]=CreateTrigger()
    call TriggerAddCondition(st__xecollider___eventHandler_onUnitHit[27],Condition( function sa__ChainInferno__missile_onUnitHit))
    call TriggerAddAction(st__xecollider___eventHandler_onUnitHit[27], function sa__ChainInferno__missile_onUnitHit)
    set st__xecollider___eventHandler_onUnitHit[28]=CreateTrigger()
    call TriggerAddCondition(st__xecollider___eventHandler_onUnitHit[28],Condition( function sa__FireNovaStrike__FireBolt_onUnitHit))
    call TriggerAddAction(st__xecollider___eventHandler_onUnitHit[28], function sa__FireNovaStrike__FireBolt_onUnitHit)
    set st__xecollider___eventHandler_loopControl[28]=CreateTrigger()
    call TriggerAddCondition(st__xecollider___eventHandler_loopControl[28],Condition( function sa__FireNovaStrike__FireBolt_loopControl))
    call TriggerAddAction(st__xecollider___eventHandler_loopControl[28], function sa__FireNovaStrike__FireBolt_loopControl)
    set st__xecollider___eventHandler_onDestroy[28]=CreateTrigger()
    call TriggerAddCondition(st__xecollider___eventHandler_onDestroy[28],Condition( function sa__FireNovaStrike__FireBolt_onDestroy))
    set st__xemissile__eventHandler_onHit[29]=CreateTrigger()
    call TriggerAddCondition(st__xemissile__eventHandler_onHit[29],Condition( function sa__FireblastChild_onHit))
    call TriggerAddAction(st__xemissile__eventHandler_onHit[29], function sa__FireblastChild_onHit)
    set st__xemissile__eventHandler_loopControl[30]=CreateTrigger()
    call TriggerAddCondition(st__xemissile__eventHandler_loopControl[30],Condition( function sa__FireblastMain_loopControl))
    call TriggerAddAction(st__xemissile__eventHandler_loopControl[30], function sa__FireblastMain_loopControl)
    set st__xemissile__eventHandler_onHit[30]=CreateTrigger()
    call TriggerAddCondition(st__xemissile__eventHandler_onHit[30],Condition( function sa__FireblastMain_onHit))
    call TriggerAddAction(st__xemissile__eventHandler_onHit[30], function sa__FireblastMain_onHit)
    set st___prototype11[1]=CreateTrigger()
    call TriggerAddAction(st___prototype11[1],function sa___prototype11_xepreload__DebugIdInteger2IdString)
    call TriggerAddCondition(st___prototype11[1],Condition(function sa___prototype11_xepreload__DebugIdInteger2IdString))
































    call ExecuteFunc("s__Table___GTable_onInit")
    call ExecuteFunc("s__xedummy___recycleQueue_onInit")
    call ExecuteFunc("s__xedummy___xedummy_onInit")
    call ExecuteFunc("s__xepreload__init_onInit")
    call ExecuteFunc("s__xemissile__missile_onInit")
endfunction


