• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

How's my AI? <:

Status
Not open for further replies.

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Meh, this could be the cutest thing (AI) I have ever made. Check out the map! Empty slots will be automatically filled by AI players.

It's just the rough gameplay and still far from complete tho. To slide your unit just move cursor around your own goal line. To pump, use left/right click. Enjoy the game! :D

There are still some failures in animation part. And don't bother asking why the coconuts come from nowhere? cz I don't have the answer. Figure it out yourself :>

The map is protected!

Newest version is here.
 

Attachments

  • Coconut Party.w3x
    1.1 MB · Views: 74
Last edited:
Okay, first off, there's mouse tracking??? I had no idea this was possible in wc3 o_O. Does that mean it's possible to have some way to have different AoE telegraphs (cones, arrows, arcs, etc) by using the mouse tracking and special effects (or ubersplats, if local player is usable with ubersplats... and ubersplats can face different angles) that follow the mouse?

Secondly, that is pretty impressive. Is this AI configurable/modular or will is only work for pong-type gameplay?
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Okay, first off, there's mouse tracking??? I had no idea this was possible in wc3 o_O. Does that mean it's possible to have some way to have different AoE telegraphs (cones, arrows, arcs, etc) by using the mouse tracking and special effects (or ubersplats, if local player is usable with ubersplats... and ubersplats can face different angles) that follow the mouse?

Secondly, that is pretty impressive. Is this AI configurable/modular or will is only work for pong-type gameplay?

Use trackables.

I'm not creating an AI system, but a new map. The AI is specifically made for my map.

Well, thanks for testing and the feedback. :)
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
So you wish not to share code with us ( yet )? :)

Yeah, perhaps not yet. I prefer to let people wonder without knowing the secret. Even tho I'm pretty sure I'm not the only one to create AI at this level, and maybe some people have already understood the algorithm I use at first sight. So it's not really a big secret after all.

But maybe I will spill everything some times after the map is released.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,190
So you post us a map and expect us to not know how it works?
The Lab This is a place allocated for you to post prototypes of resources, GUI/JASS discussions and even JASS hacks.

You could have at least optimized the script if you wanted to keep the inner workings secret.

JASS:
globals
//globals from AngleDiff:
constant boolean LIBRARY_AngleDiff=true
//endglobals from AngleDiff
//globals from ErrorMessage:
constant boolean LIBRARY_ErrorMessage=true
//endglobals from ErrorMessage
//globals from Event:
constant boolean LIBRARY_Event=true
real Event___q=0
//endglobals from Event
//globals from GetTerrainZ:
constant boolean LIBRARY_GetTerrainZ=true
constant location GetTerrainZ___L= Location(0, 0)
//endglobals from GetTerrainZ
//globals from PathingType:
constant boolean LIBRARY_PathingType=true
        
constant integer PathingType___PATH_CHECKER= 'h008'
constant integer PathingType___FLY_CHECKER= 'h00A'
constant integer PathingType___WALK_CHECKER= 'h009'
constant integer PathingType___BUILD_CHECKER= 'h00B'
            
constant player PathingType___UNUSED_PLAYER= Player(14)
            
        
unit PathingType___PathChecker
        
constant integer PATHING_COLOR_WHITE= 0
constant integer PATHING_COLOR_MAGENTA= 1
constant integer PATHING_COLOR_CYAN= 2
constant integer PATHING_COLOR_BLUE= 3
constant integer PATHING_COLOR_YELLOW= 4
constant integer PATHING_COLOR_RED= 5
constant integer PATHING_COLOR_GREEN= 6
constant integer PATHING_COLOR_BLACK= 7
        
//endglobals from PathingType
//globals from Table:
constant boolean LIBRARY_Table=true
integer Table___less= 0
integer Table___more= 8190
    //Configure it if you use more than 8190 "key" variables in your map (this will never happen though).
    
hashtable Table___ht= InitHashtable()
constant integer Table___sizeK=3
constant integer Table___listK=4
//endglobals from Table
//globals from TimerUtils:
constant boolean LIBRARY_TimerUtils=true
        //How to tweak timer utils:
        // USE_HASH_TABLE = true  (new blue)
        //  * SAFEST
        //  * SLOWEST (though hash tables are kind of fast)
        //
        // USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true  (orange)
        //  * kinda safe (except there is a limit in the number of timers)
        //  * ALMOST FAST
        //
        // USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red)
        //  * THE FASTEST (though is only  faster than the previous method
        //                  after using the optimizer on the map)
        //  * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to
        //                     work)
        //
constant boolean TimerUtils___USE_HASH_TABLE= true
constant boolean TimerUtils___USE_FLEXIBLE_OFFSET= false

constant integer TimerUtils___OFFSET= 0x100000
integer TimerUtils___VOFFSET= TimerUtils___OFFSET
              
        //Timers to preload at map init:
constant integer TimerUtils___QUANTITY= 8189
        
        //Changing this  to something big will allow you to keep recycling
        // timers even when there are already AN INCREDIBLE AMOUNT of timers in
        // the stack. But it will make things far slower so that's probably a bad idea...
constant integer TimerUtils___ARRAY_SIZE= 8190

// processed:         integer array TimerUtils___data[TimerUtils___ARRAY_SIZE]
hashtable TimerUtils___ht
// processed:         timer array TimerUtils___tT[TimerUtils___ARRAY_SIZE]
integer TimerUtils___tN= 0
constant integer TimerUtils___HELD=0x28829022
        //use a totally random number here, the more improbable someone uses it, the better.
        
boolean TimerUtils___didinit= false
//endglobals from TimerUtils
//globals from WorldBounds:
constant boolean LIBRARY_WorldBounds=true
//endglobals from WorldBounds
//globals from Alloc:
constant boolean LIBRARY_Alloc=true
//endglobals from Alloc
//globals from ExtendedSound:
constant boolean LIBRARY_ExtendedSound=true
        // Actually, just leave this value
constant real ExtendedSound___RAPID_DELAY_FACTOR= 4
//endglobals from ExtendedSound
//globals from Track:
constant boolean LIBRARY_Track=true
constant integer Track___PLATFORM= 'OTip'
//endglobals from Track
//globals from UnitIndexer:
constant boolean LIBRARY_UnitIndexer=true
constant integer ABILITIES_UNIT_INDEXER= 'A000'
trigger UnitIndexer___q=CreateTrigger()
trigger UnitIndexer___l=CreateTrigger()
unit array UnitIndexer___e
integer UnitIndexer___r=0
integer UnitIndexer___y=0
integer UnitIndexer___o=0
boolean UnitIndexer___a=false
integer array UnitIndexer___n
integer array UnitIndexer___p
integer array UnitIndexer___lc
//endglobals from UnitIndexer
//globals from AutoFly:
constant boolean LIBRARY_AutoFly=true
//endglobals from AutoFly
//globals from Missile:
constant boolean LIBRARY_Missile=true
    
        
constant real Missile_TIMER_TIMEOUT= 0.031250000
        
         
constant player Missile_NEUTRAL_PASSIVE= Player(PLAYER_NEUTRAL_PASSIVE)
        
        
constant integer Missile_DUMMY_UNIT_ID= 'h001'
    
        
constant real Missile_MAXIMUM_COLLISION_SIZE= 197.
        
        
//      Set booleans listed below to "true" and the compiler will write 
//      the feature into your map. Otherwise this code is completly ignored.                                        
//          o Yay, I want that           --> "true"
//          o Naah that's useless for me --> "false"

        
constant boolean Missile_USE_DESTRUCTABLE_FILTER= true
        
        
constant boolean Missile_USE_COLLISION_Z_FILTER= true
        
        
constant boolean Missile_WRITE_DELAYED_MISSILE_RECYCLING= true
        
        
constant real Missile___DELAYED_MISSILE_DEATH_ANIMATION_TIME= 2.
trigger Missile___core= CreateTrigger()
timer Missile___clock= CreateTimer()
integer Missile___active= 0
        
integer array Missile___instances
integer array Missile___missileStack
boolexpr array Missile___expression
triggercondition array Missile___condition
//endglobals from Missile
//globals from UnitZ:
constant boolean LIBRARY_UnitZ=true
//endglobals from UnitZ
//globals from Coconut:
constant boolean LIBRARY_Coconut=true
constant real SLOPE_ACCURACY= 0.1
constant real FULL_GRAVITY= 6.5
constant real SLIDER_MASS= 1
constant real TAU= bj_PI * 2
constant real HP= bj_PI / 2
        
integer CocoCount= 0
real array SpawnA
real array SpawnX
real array SpawnY
integer array Cocos
//endglobals from Coconut
    // Generated
rect gg_rct_Rect_000= null
rect gg_rct_Rect_000_Copy= null
rect gg_rct_Rect_000_Copy_2= null
rect gg_rct_Rect_000_Copy_3= null
rect gg_rct_Rect_004= null
rect gg_rct_Rect_004_Copy= null
rect gg_rct_Rect_004_Copy_2= null
rect gg_rct_Rect_004_Copy_3= null
camerasetup gg_cam_Camera_001= null
trigger gg_trg_AI= null
trigger gg_trg_Unit= null
trigger gg_trg_Coconut= null
trigger gg_trg_Control= null
trigger gg_trg_Music= null
trigger gg_trg_GUI= null
trigger gg_trg_test= null
trigger gg_trg_Missile= null
trigger gg_trg_AngleDiff= null
trigger gg_trg_ExSound= null
trigger gg_trg_Track= null
trigger gg_trg_Table= null
trigger gg_trg_AutoFly= null
trigger gg_trg_Unit_Indexer= null
trigger gg_trg_Event= null
trigger gg_trg_Alloc= null
trigger gg_trg_Error_Message= null
trigger gg_trg_WorldBounds= null
trigger gg_trg_PathingType= null
trigger gg_trg_TimerUtils= null
trigger gg_trg_UnitZ= null
trigger gg_trg_GetTerrainZ= null
rect gg_rct_Rect_008= null
timer array AITimer
integer array AITarget
integer array TargetUrgency
unit array Pumpers
constant player PASSIVE= Player(PLAYER_NEUTRAL_PASSIVE)
unit array Control
unit array Unit
real array StartX
real array StartY
real array TargetX
real array TargetY
real array CurrentX
real array CurrentY
boolean array IsAI
integer array Bars

trigger l__library_init

//JASSHelper struct globals:
constant integer si__Event=1
integer s__Event_w=0
trigger array s__Event_e
constant integer si__Table___dex=2
constant integer si__Table___handles=3
constant integer si__Table___agents=4
constant integer si__Table___reals=5
constant integer si__Table___booleans=6
constant integer si__Table___strings=7
constant integer si__Table___integers=8
constant integer si__Table___players=9
constant integer si__Table___widgets=10
constant integer si__Table___destructables=11
constant integer si__Table___items=12
constant integer si__Table___units=13
constant integer si__Table___abilitys=14
constant integer si__Table___timers=15
constant integer si__Table___triggers=16
constant integer si__Table___triggerconditions=17
constant integer si__Table___triggeractions=18
constant integer si__Table___events=19
constant integer si__Table___forces=20
constant integer si__Table___groups=21
constant integer si__Table___locations=22
constant integer si__Table___rects=23
constant integer si__Table___boolexprs=24
constant integer si__Table___sounds=25
constant integer si__Table___effects=26
constant integer si__Table___unitpools=27
constant integer si__Table___itempools=28
constant integer si__Table___quests=29
constant integer si__Table___questitems=30
constant integer si__Table___defeatconditions=31
constant integer si__Table___timerdialogs=32
constant integer si__Table___leaderboards=33
constant integer si__Table___multiboards=34
constant integer si__Table___multiboarditems=35
constant integer si__Table___trackables=36
constant integer si__Table___dialogs=37
constant integer si__Table___buttons=38
constant integer si__Table___texttags=39
constant integer si__Table___lightnings=40
constant integer si__Table___images=41
constant integer si__Table___ubersplats=42
constant integer si__Table___regions=43
constant integer si__Table___fogstates=44
constant integer si__Table___fogmodifiers=45
constant integer si__Table___hashtables=46
constant integer si__Table=47
constant integer si__TableArray=48
integer s__TableArray_tempTable
integer s__TableArray_tempEnd
constant integer si__WorldBounds=49
integer s__WorldBounds_maxX
integer s__WorldBounds_maxY
integer s__WorldBounds_minX
integer s__WorldBounds_minY
integer s__WorldBounds_centerX
integer s__WorldBounds_centerY
rect s__WorldBounds_world
region s__WorldBounds_worldRegion
constant integer si__ExSound=50
integer si__ExSound_F=0
integer si__ExSound_I=0
integer array si__ExSound_V
string array s__ExSound_StrLib
integer s__ExSound_Counter= - 1
constant integer s__ExSound_MAX_COUNT= 4
integer array s__ExSound_ct
integer array s__ExSound_lib
integer array s__ExSound_dex
real array s__ExSound_dur
sound array s___ExSound_snd
constant integer s___ExSound_snd_size=4
integer array s__ExSound_snd
timer array s___ExSound_tmr
constant integer s___ExSound_tmr_size=4
integer array s__ExSound_tmr
constant integer si__Track=53
trigger s__Track_anyClick= CreateTrigger()
trigger s__Track_anyHover= CreateTrigger()
integer s__Track_TrackTable= 0
integer s__Track_instance= 0
trackable s__Track_object= null
player s__Track_tracker= null
integer s__Track_ic= 0
integer s__Track_ir= 0
integer array s__Track_rn
real array s__Track_x
real array s__Track_y
real array s__Track_z
real array s__Track_facing
string array s__Track_model
boolean array s__Track_flag
trigger array s__Track_reg
trigger array s__Track_onClick
trigger array s__Track_onHover
constant integer si__UnitIndexer___PreLoader=54
constant integer si__UnitIndex=55
constant integer si__UnitIndexer=56
integer s__UnitIndexer_INDEX
integer s__UnitIndexer_DEINDEX
boolean s__UnitIndexer_enabled=true
constant integer si__AutoFly___Inits=57
constant integer si__Missile___RecycleBin=58
timer s__Missile___RecycleBin_t= CreateTimer()
integer s__Missile___RecycleBin_alloc= 0
unit array s__Missile___RecycleBin_dummy
real array s__Missile___RecycleBin_time
constant integer si__MissilePosition=59
integer array s__MissilePosition_recycler
integer s__MissilePosition_alloc= 0
location s__MissilePosition_loc= Location(0., 0.)
real array s__MissilePosition_x
real array s__MissilePosition_y
real array s__MissilePosition_z
real array s__MissilePosition_angle
real array s__MissilePosition_distance
real array s__MissilePosition_slope
real array s__MissilePosition_alpha
integer array s__MissilePosition_ref
constant integer si__Missile=60
integer s__Missile_Missile___MissileStructure__collectionCount= 0
integer s__Missile_Missile___MissileStructure__nodeCount= 0
integer array s__Missile_Missile___MissileStructure___list
integer array s__Missile_Missile___MissileStructure___next
integer array s__Missile_Missile___MissileStructure___prev
integer array s__Missile_Missile___MissileStructure___first
integer array s__Missile_Missile___MissileStructure___last
constant string s__Missile_ORIGIN= "origin"
constant real s__Missile_HIT_BOX= ( 2 / 3 )
group s__Missile_enumGroup= CreateGroup()
boolean array s__Missile_allocated
effect array s__Missile_sfx
string array s__Missile_path
real array s__Missile_missileScale
real array s__Missile_angle
real array s__Missile_xPrivate
real array s__Missile_yPrivate
integer array s__Missile_origin
integer array s__Missile_impact
real array s__Missile_terrainZ
real array s__Missile_x
real array s__Missile_y
real array s__Missile_z
unit array s__Missile_dummy
group array s__Missile_unitsHit
boolean array s__Missile_wantDestroy
boolean array s__Missile_recycle
real array s__Missile_distance
unit array s__Missile_target
unit array s__Missile_source
player array s__Missile_owner
real array s__Missile_collision
real array s__Missile_collisionZ
real array s__Missile_speed
real array s__Missile_height
real array s__Missile_turn
real array s__Missile_open
real array s__Missile_damage
real array s__Missile_acceleration
integer array s__Missile_data
rect s__Missile_enumRect= Rect(0., 0., 0., 0.)
integer s__Missile_temp= 0
real s__Missile_tempDist= 0
constant integer si__Coconut___Ground=61
real s__Coconut___Ground_x= 0
real s__Coconut___Ground_y= 0
constant integer si__Coconut=62
integer si__Coconut_F=0
integer si__Coconut_I=0
integer array si__Coconut_V
integer array s__Coconut_source
unit array s__Coconut_missile
integer array s__Coconut_index
real array s__Coconut_x
real array s__Coconut_y
real array s__Coconut_z
real array s__Coconut_zVel
real array s__Coconut_duration
boolean array s__Coconut_isFlying
boolean array s__Coconut_splash
real array s__Coconut_angle
real array s__Coconut_speed
effect array s__Coconut_sfx
timer array s__Coconut_tick
integer s__Coconut_ground
group s__Coconut_G= CreateGroup()
constant integer si__AI=63
integer si__AI_F=0
integer si__AI_I=0
integer array si__AI_V
constant integer si__BarData=64
integer si__BarData_F=0
integer si__BarData_I=0
integer array si__BarData_V
real array s___BarData_x
constant integer s___BarData_x_size=40
integer array s__BarData_x
real array s___BarData_y
constant integer s___BarData_y_size=40
integer array s__BarData_y
integer array s___BarData_t
constant integer s___BarData_t_size=40
integer array s__BarData_t
constant integer si__Controller=68
integer si__Controller_F=0
integer si__Controller_I=0
integer array si__Controller_V
integer array s__TimerUtils___data
timer array s__TimerUtils___tT
trigger st__Coconut_getLowestGr
trigger st__Coconut_slip
trigger array st___prototype9
real f__arg_real1
real f__arg_real2
real f__arg_real3
real f__arg_real4
integer f__arg_this

endglobals


//Generated allocator of Controller
function s__Controller__allocate takes nothing returns integer
 local integer this=si__Controller_F
    if (this!=0) then
        set si__Controller_F=si__Controller_V[this]
    else
        set si__Controller_I=si__Controller_I+1
        set this=si__Controller_I
    endif
    if (this>8190) then
        return 0
    endif

    set si__Controller_V[this]=-1
 return this
endfunction

//Generated destructor of Controller
function s__Controller_deallocate takes integer this returns nothing
    if this==null then
        return
    elseif (si__Controller_V[this]!=-1) then
        return
    endif
    set si__Controller_V[this]=si__Controller_F
    set si__Controller_F=this
endfunction

//Generated allocator of BarData
function s__BarData__allocate takes nothing returns integer
 local integer this=si__BarData_F
    if (this!=0) then
        set si__BarData_F=si__BarData_V[this]
    else
        set si__BarData_I=si__BarData_I+1
        set this=si__BarData_I
    endif
    if (this>203) then
        return 0
    endif
    set s__BarData_x[this]=(this-1)*40
    set s__BarData_y[this]=(this-1)*40
    set s__BarData_t[this]=(this-1)*40
    set si__BarData_V[this]=-1
 return this
endfunction

//Generated destructor of BarData
function s__BarData_deallocate takes integer this returns nothing
    if this==null then
        return
    elseif (si__BarData_V[this]!=-1) then
        return
    endif
    set si__BarData_V[this]=si__BarData_F
    set si__BarData_F=this
endfunction

//Generated allocator of AI
function s__AI__allocate takes nothing returns integer
 local integer this=si__AI_F
    if (this!=0) then
        set si__AI_F=si__AI_V[this]
    else
        set si__AI_I=si__AI_I+1
        set this=si__AI_I
    endif
    if (this>8190) then
        return 0
    endif

    set si__AI_V[this]=-1
 return this
endfunction

//Generated destructor of AI
function s__AI_deallocate takes integer this returns nothing
    if this==null then
        return
    elseif (si__AI_V[this]!=-1) then
        return
    endif
    set si__AI_V[this]=si__AI_F
    set si__AI_F=this
endfunction

//Generated method caller for Coconut.getLowestGr
function sc__Coconut_getLowestGr takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__Coconut_getLowestGr)
endfunction

//Generated method caller for Coconut.slip
function sc__Coconut_slip takes integer this,real speed,real maxspeed,real angle,real rate returns nothing
    set f__arg_this=this
    set f__arg_real1=speed
    set f__arg_real2=maxspeed
    set f__arg_real3=angle
    set f__arg_real4=rate
    call TriggerEvaluate(st__Coconut_slip)
endfunction

//Generated allocator of Coconut
function s__Coconut__allocate takes nothing returns integer
 local integer this=si__Coconut_F
    if (this!=0) then
        set si__Coconut_F=si__Coconut_V[this]
    else
        set si__Coconut_I=si__Coconut_I+1
        set this=si__Coconut_I
    endif
    if (this>8190) then
        return 0
    endif

    set si__Coconut_V[this]=-1
 return this
endfunction

//Generated destructor of Coconut
function s__Coconut_deallocate takes integer this returns nothing
    if this==null then
        return
    elseif (si__Coconut_V[this]!=-1) then
        return
    endif
    set si__Coconut_V[this]=si__Coconut_F
    set si__Coconut_F=this
endfunction

//Generated allocator of ExSound
function s__ExSound__allocate takes nothing returns integer
 local integer this=si__ExSound_F
    if (this!=0) then
        set si__ExSound_F=si__ExSound_V[this]
    else
        set si__ExSound_I=si__ExSound_I+1
        set this=si__ExSound_I
    endif
    if (this>2046) then
        return 0
    endif
    set s__ExSound_snd[this]=(this-1)*4
    set s__ExSound_tmr[this]=(this-1)*4
    set si__ExSound_V[this]=-1
 return this
endfunction

//Generated destructor of ExSound
function s__ExSound_deallocate takes integer this returns nothing
    if this==null then
        return
    elseif (si__ExSound_V[this]!=-1) then
        return
    endif
    set si__ExSound_V[this]=si__ExSound_F
    set si__ExSound_F=this
endfunction
function sc___prototype9_execute takes integer i returns nothing

    call TriggerExecute(st___prototype9[i])
endfunction
function sc___prototype9_evaluate takes integer i returns nothing

    call TriggerEvaluate(st___prototype9[i])

endfunction

//library AngleDiff:
            
    function normalize takes real a returns real
            
        loop
            if a < 0 then
                set a=a + TAU
            elseif a > TAU then
                set a=a - TAU
            else
                exitwhen true
            endif
        endloop
        
        return a
    endfunction
    
    function circularDifference takes real a,real b returns real
            
        local real diff= RAbsBJ(a - b)
        
        if diff * 2 <= TAU then
            return diff
        else
            return TAU - diff
        endif
        
    endfunction
    

//library AngleDiff ends
//library ErrorMessage:



























































//library ErrorMessage ends
//library Event:
        function s__Event_create takes nothing returns integer
            set s__Event_w=s__Event_w + 1
            set s__Event_e[s__Event_w]=CreateTrigger()
            return s__Event_w
        endfunction
        function s__Event_registerTrigger takes integer this,trigger t returns nothing
            call TriggerRegisterVariableEvent(t, "Event___q", EQUAL, this)
        endfunction
        function s__Event_register takes integer this,boolexpr c returns nothing
            call TriggerAddCondition(s__Event_e[this], c)
        endfunction
        function s__Event_fire takes integer this returns nothing
            set Event___q=0
            set Event___q=this
            call TriggerEvaluate(s__Event_e[this])
        endfunction
    function CreateEvent takes nothing returns integer
        return s__Event_create()
    endfunction
    function TriggerRegisterEvent takes trigger t,integer ev returns nothing
        call s__Event_registerTrigger(ev,t)
    endfunction
    function RegisterEvent takes boolexpr c,integer ev returns nothing
        call TriggerAddCondition(s__Event_e[(ev)], (c)) // INLINED!!
    endfunction
    function FireEvent takes integer ev returns nothing
        call s__Event_fire(ev)
    endfunction

//library Event ends
//library GetTerrainZ:


    function GetTerrainZ takes real x,real y returns real
        call MoveLocation(GetTerrainZ___L, x, y)
        return GetLocationZ(GetTerrainZ___L)
    endfunction


//library GetTerrainZ ends
//library PathingType:
    
    // Configuration
    
    
    
    
    
    function IsTerrainFlyable takes real x,real y returns boolean
        return IssueBuildOrderById(PathingType___PathChecker, PathingType___FLY_CHECKER, x, y)
    endfunction
    
    function IsTerrainWalkable takes real x,real y returns boolean
        return IssueBuildOrderById(PathingType___PathChecker, PathingType___WALK_CHECKER, x, y)
    endfunction
    
    function IsTerrainBuildable takes real x,real y returns boolean
        return IssueBuildOrderById(PathingType___PathChecker, PathingType___BUILD_CHECKER, x, y)
    endfunction
    
    function GetTerrainPathingColor takes real x,real y returns integer
        
        local integer color= 0
        
        if (IssueBuildOrderById(PathingType___PathChecker, PathingType___FLY_CHECKER, ((x )*1.0), (( y)*1.0))) then // INLINED!!
            set color=color + 1
        endif
        
        if (IssueBuildOrderById(PathingType___PathChecker, PathingType___WALK_CHECKER, ((x )*1.0), (( y)*1.0))) then // INLINED!!
            set color=color + 2
        endif
        
        if (IssueBuildOrderById(PathingType___PathChecker, PathingType___BUILD_CHECKER, ((x )*1.0), (( y)*1.0))) then // INLINED!!
            set color=color + 4
        endif
        
        return color
    endfunction
    
    function PathingType___onInit takes nothing returns nothing
    
        set PathingType___PathChecker=CreateUnit(PathingType___UNUSED_PLAYER, PathingType___PATH_CHECKER, 0, 0, 0)
        call UnitRemoveAbility(PathingType___PathChecker, 'Amov')
        call ShowUnit(PathingType___PathChecker, false)
        
        if GetLocalPlayer() == PathingType___UNUSED_PLAYER then
            call FogEnable(false)
            call FogMaskEnable(false)
        endif
        
    endfunction
    

//library PathingType ends
//library Table:
    
    
    function s__Table___dex__get_size takes nothing returns integer
        return Table___sizeK
    endfunction
    function s__Table___dex__get_list takes nothing returns integer
        return Table___listK
    endfunction
    
    function s__Table___handles_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___handles_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
    
    function s__Table___agents__setindex takes integer this,integer key,agent value returns nothing
        call SaveAgentHandle(Table___ht, this, key, value)
    endfunction
    
    
    
//Run these textmacros to include the entire hashtable API as wrappers.
//Don't be intimidated by the number of macros - Vexorian's map optimizer is
//supposed to kill functions which inline (all of these functions inline).
//textmacro instance: NEW_ARRAY_BASIC("Real", "Real", "real")
    function s__Table___reals__getindex takes integer this,integer key returns real
        return LoadReal(Table___ht, this, key)
    endfunction
    function s__Table___reals__setindex takes integer this,integer key,real value returns nothing
        call SaveReal(Table___ht, this, key, value)
    endfunction
    function s__Table___reals_has takes integer this,integer key returns boolean
        return HaveSavedReal(Table___ht, this, key)
    endfunction
    function s__Table___reals_remove takes integer this,integer key returns nothing
        call RemoveSavedReal(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY_BASIC("Real", "Real", "real")
//textmacro instance: NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
    function s__Table___booleans__getindex takes integer this,integer key returns boolean
        return LoadBoolean(Table___ht, this, key)
    endfunction
    function s__Table___booleans__setindex takes integer this,integer key,boolean value returns nothing
        call SaveBoolean(Table___ht, this, key, value)
    endfunction
    function s__Table___booleans_has takes integer this,integer key returns boolean
        return HaveSavedBoolean(Table___ht, this, key)
    endfunction
    function s__Table___booleans_remove takes integer this,integer key returns nothing
        call RemoveSavedBoolean(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//textmacro instance: NEW_ARRAY_BASIC("String", "Str", "string")
    function s__Table___strings__getindex takes integer this,integer key returns string
        return LoadStr(Table___ht, this, key)
    endfunction
    function s__Table___strings__setindex takes integer this,integer key,string value returns nothing
        call SaveStr(Table___ht, this, key, value)
    endfunction
    function s__Table___strings_has takes integer this,integer key returns boolean
        return HaveSavedString(Table___ht, this, key)
    endfunction
    function s__Table___strings_remove takes integer this,integer key returns nothing
        call RemoveSavedString(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY_BASIC("String", "Str", "string")
//New textmacro to allow table.integer[] syntax for compatibility with textmacros that might desire it.
//textmacro instance: NEW_ARRAY_BASIC("Integer", "Integer", "integer")
    function s__Table___integers__getindex takes integer this,integer key returns integer
        return LoadInteger(Table___ht, this, key)
    endfunction
    function s__Table___integers__setindex takes integer this,integer key,integer value returns nothing
        call SaveInteger(Table___ht, this, key, value)
    endfunction
    function s__Table___integers_has takes integer this,integer key returns boolean
        return HaveSavedInteger(Table___ht, this, key)
    endfunction
    function s__Table___integers_remove takes integer this,integer key returns nothing
        call RemoveSavedInteger(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY_BASIC("Integer", "Integer", "integer")
    
//textmacro instance: NEW_ARRAY("Player", "player")
    function s__Table___players__getindex takes integer this,integer key returns player
        return LoadPlayerHandle(Table___ht, this, key)
    endfunction
    function s__Table___players__setindex takes integer this,integer key,player value returns nothing
        call SavePlayerHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___players_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___players_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Player", "player")
//textmacro instance: NEW_ARRAY("Widget", "widget")
    function s__Table___widgets__getindex takes integer this,integer key returns widget
        return LoadWidgetHandle(Table___ht, this, key)
    endfunction
    function s__Table___widgets__setindex takes integer this,integer key,widget value returns nothing
        call SaveWidgetHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___widgets_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___widgets_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Widget", "widget")
//textmacro instance: NEW_ARRAY("Destructable", "destructable")
    function s__Table___destructables__getindex takes integer this,integer key returns destructable
        return LoadDestructableHandle(Table___ht, this, key)
    endfunction
    function s__Table___destructables__setindex takes integer this,integer key,destructable value returns nothing
        call SaveDestructableHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___destructables_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___destructables_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Destructable", "destructable")
//textmacro instance: NEW_ARRAY("Item", "item")
    function s__Table___items__getindex takes integer this,integer key returns item
        return LoadItemHandle(Table___ht, this, key)
    endfunction
    function s__Table___items__setindex takes integer this,integer key,item value returns nothing
        call SaveItemHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___items_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___items_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Item", "item")
//textmacro instance: NEW_ARRAY("Unit", "unit")
    function s__Table___units__getindex takes integer this,integer key returns unit
        return LoadUnitHandle(Table___ht, this, key)
    endfunction
    function s__Table___units__setindex takes integer this,integer key,unit value returns nothing
        call SaveUnitHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___units_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___units_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Unit", "unit")
//textmacro instance: NEW_ARRAY("Ability", "ability")
    function s__Table___abilitys__getindex takes integer this,integer key returns ability
        return LoadAbilityHandle(Table___ht, this, key)
    endfunction
    function s__Table___abilitys__setindex takes integer this,integer key,ability value returns nothing
        call SaveAbilityHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___abilitys_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___abilitys_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Ability", "ability")
//textmacro instance: NEW_ARRAY("Timer", "timer")
    function s__Table___timers__getindex takes integer this,integer key returns timer
        return LoadTimerHandle(Table___ht, this, key)
    endfunction
    function s__Table___timers__setindex takes integer this,integer key,timer value returns nothing
        call SaveTimerHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___timers_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___timers_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Timer", "timer")
//textmacro instance: NEW_ARRAY("Trigger", "trigger")
    function s__Table___triggers__getindex takes integer this,integer key returns trigger
        return LoadTriggerHandle(Table___ht, this, key)
    endfunction
    function s__Table___triggers__setindex takes integer this,integer key,trigger value returns nothing
        call SaveTriggerHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___triggers_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___triggers_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Trigger", "trigger")
//textmacro instance: NEW_ARRAY("TriggerCondition", "triggercondition")
    function s__Table___triggerconditions__getindex takes integer this,integer key returns triggercondition
        return LoadTriggerConditionHandle(Table___ht, this, key)
    endfunction
    function s__Table___triggerconditions__setindex takes integer this,integer key,triggercondition value returns nothing
        call SaveTriggerConditionHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___triggerconditions_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___triggerconditions_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("TriggerCondition", "triggercondition")
//textmacro instance: NEW_ARRAY("TriggerAction", "triggeraction")
    function s__Table___triggeractions__getindex takes integer this,integer key returns triggeraction
        return LoadTriggerActionHandle(Table___ht, this, key)
    endfunction
    function s__Table___triggeractions__setindex takes integer this,integer key,triggeraction value returns nothing
        call SaveTriggerActionHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___triggeractions_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___triggeractions_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("TriggerAction", "triggeraction")
//textmacro instance: NEW_ARRAY("TriggerEvent", "event")
    function s__Table___events__getindex takes integer this,integer key returns event
        return LoadTriggerEventHandle(Table___ht, this, key)
    endfunction
    function s__Table___events__setindex takes integer this,integer key,event value returns nothing
        call SaveTriggerEventHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___events_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___events_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("TriggerEvent", "event")
//textmacro instance: NEW_ARRAY("Force", "force")
    function s__Table___forces__getindex takes integer this,integer key returns force
        return LoadForceHandle(Table___ht, this, key)
    endfunction
    function s__Table___forces__setindex takes integer this,integer key,force value returns nothing
        call SaveForceHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___forces_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___forces_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Force", "force")
//textmacro instance: NEW_ARRAY("Group", "group")
    function s__Table___groups__getindex takes integer this,integer key returns group
        return LoadGroupHandle(Table___ht, this, key)
    endfunction
    function s__Table___groups__setindex takes integer this,integer key,group value returns nothing
        call SaveGroupHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___groups_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___groups_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Group", "group")
//textmacro instance: NEW_ARRAY("Location", "location")
    function s__Table___locations__getindex takes integer this,integer key returns location
        return LoadLocationHandle(Table___ht, this, key)
    endfunction
    function s__Table___locations__setindex takes integer this,integer key,location value returns nothing
        call SaveLocationHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___locations_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___locations_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Location", "location")
//textmacro instance: NEW_ARRAY("Rect", "rect")
    function s__Table___rects__getindex takes integer this,integer key returns rect
        return LoadRectHandle(Table___ht, this, key)
    endfunction
    function s__Table___rects__setindex takes integer this,integer key,rect value returns nothing
        call SaveRectHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___rects_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___rects_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Rect", "rect")
//textmacro instance: NEW_ARRAY("BooleanExpr", "boolexpr")
    function s__Table___boolexprs__getindex takes integer this,integer key returns boolexpr
        return LoadBooleanExprHandle(Table___ht, this, key)
    endfunction
    function s__Table___boolexprs__setindex takes integer this,integer key,boolexpr value returns nothing
        call SaveBooleanExprHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___boolexprs_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___boolexprs_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("BooleanExpr", "boolexpr")
//textmacro instance: NEW_ARRAY("Sound", "sound")
    function s__Table___sounds__getindex takes integer this,integer key returns sound
        return LoadSoundHandle(Table___ht, this, key)
    endfunction
    function s__Table___sounds__setindex takes integer this,integer key,sound value returns nothing
        call SaveSoundHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___sounds_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___sounds_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Sound", "sound")
//textmacro instance: NEW_ARRAY("Effect", "effect")
    function s__Table___effects__getindex takes integer this,integer key returns effect
        return LoadEffectHandle(Table___ht, this, key)
    endfunction
    function s__Table___effects__setindex takes integer this,integer key,effect value returns nothing
        call SaveEffectHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___effects_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___effects_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Effect", "effect")
//textmacro instance: NEW_ARRAY("UnitPool", "unitpool")
    function s__Table___unitpools__getindex takes integer this,integer key returns unitpool
        return LoadUnitPoolHandle(Table___ht, this, key)
    endfunction
    function s__Table___unitpools__setindex takes integer this,integer key,unitpool value returns nothing
        call SaveUnitPoolHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___unitpools_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___unitpools_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("UnitPool", "unitpool")
//textmacro instance: NEW_ARRAY("ItemPool", "itempool")
    function s__Table___itempools__getindex takes integer this,integer key returns itempool
        return LoadItemPoolHandle(Table___ht, this, key)
    endfunction
    function s__Table___itempools__setindex takes integer this,integer key,itempool value returns nothing
        call SaveItemPoolHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___itempools_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___itempools_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("ItemPool", "itempool")
//textmacro instance: NEW_ARRAY("Quest", "quest")
    function s__Table___quests__getindex takes integer this,integer key returns quest
        return LoadQuestHandle(Table___ht, this, key)
    endfunction
    function s__Table___quests__setindex takes integer this,integer key,quest value returns nothing
        call SaveQuestHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___quests_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___quests_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Quest", "quest")
//textmacro instance: NEW_ARRAY("QuestItem", "questitem")
    function s__Table___questitems__getindex takes integer this,integer key returns questitem
        return LoadQuestItemHandle(Table___ht, this, key)
    endfunction
    function s__Table___questitems__setindex takes integer this,integer key,questitem value returns nothing
        call SaveQuestItemHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___questitems_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___questitems_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("QuestItem", "questitem")
//textmacro instance: NEW_ARRAY("DefeatCondition", "defeatcondition")
    function s__Table___defeatconditions__getindex takes integer this,integer key returns defeatcondition
        return LoadDefeatConditionHandle(Table___ht, this, key)
    endfunction
    function s__Table___defeatconditions__setindex takes integer this,integer key,defeatcondition value returns nothing
        call SaveDefeatConditionHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___defeatconditions_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___defeatconditions_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("DefeatCondition", "defeatcondition")
//textmacro instance: NEW_ARRAY("TimerDialog", "timerdialog")
    function s__Table___timerdialogs__getindex takes integer this,integer key returns timerdialog
        return LoadTimerDialogHandle(Table___ht, this, key)
    endfunction
    function s__Table___timerdialogs__setindex takes integer this,integer key,timerdialog value returns nothing
        call SaveTimerDialogHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___timerdialogs_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___timerdialogs_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("TimerDialog", "timerdialog")
//textmacro instance: NEW_ARRAY("Leaderboard", "leaderboard")
    function s__Table___leaderboards__getindex takes integer this,integer key returns leaderboard
        return LoadLeaderboardHandle(Table___ht, this, key)
    endfunction
    function s__Table___leaderboards__setindex takes integer this,integer key,leaderboard value returns nothing
        call SaveLeaderboardHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___leaderboards_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___leaderboards_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Leaderboard", "leaderboard")
//textmacro instance: NEW_ARRAY("Multiboard", "multiboard")
    function s__Table___multiboards__getindex takes integer this,integer key returns multiboard
        return LoadMultiboardHandle(Table___ht, this, key)
    endfunction
    function s__Table___multiboards__setindex takes integer this,integer key,multiboard value returns nothing
        call SaveMultiboardHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___multiboards_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___multiboards_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Multiboard", "multiboard")
//textmacro instance: NEW_ARRAY("MultiboardItem", "multiboarditem")
    function s__Table___multiboarditems__getindex takes integer this,integer key returns multiboarditem
        return LoadMultiboardItemHandle(Table___ht, this, key)
    endfunction
    function s__Table___multiboarditems__setindex takes integer this,integer key,multiboarditem value returns nothing
        call SaveMultiboardItemHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___multiboarditems_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___multiboarditems_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("MultiboardItem", "multiboarditem")
//textmacro instance: NEW_ARRAY("Trackable", "trackable")
    function s__Table___trackables__getindex takes integer this,integer key returns trackable
        return LoadTrackableHandle(Table___ht, this, key)
    endfunction
    function s__Table___trackables__setindex takes integer this,integer key,trackable value returns nothing
        call SaveTrackableHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___trackables_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___trackables_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Trackable", "trackable")
//textmacro instance: NEW_ARRAY("Dialog", "dialog")
    function s__Table___dialogs__getindex takes integer this,integer key returns dialog
        return LoadDialogHandle(Table___ht, this, key)
    endfunction
    function s__Table___dialogs__setindex takes integer this,integer key,dialog value returns nothing
        call SaveDialogHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___dialogs_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___dialogs_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Dialog", "dialog")
//textmacro instance: NEW_ARRAY("Button", "button")
    function s__Table___buttons__getindex takes integer this,integer key returns button
        return LoadButtonHandle(Table___ht, this, key)
    endfunction
    function s__Table___buttons__setindex takes integer this,integer key,button value returns nothing
        call SaveButtonHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___buttons_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___buttons_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Button", "button")
//textmacro instance: NEW_ARRAY("TextTag", "texttag")
    function s__Table___texttags__getindex takes integer this,integer key returns texttag
        return LoadTextTagHandle(Table___ht, this, key)
    endfunction
    function s__Table___texttags__setindex takes integer this,integer key,texttag value returns nothing
        call SaveTextTagHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___texttags_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___texttags_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("TextTag", "texttag")
//textmacro instance: NEW_ARRAY("Lightning", "lightning")
    function s__Table___lightnings__getindex takes integer this,integer key returns lightning
        return LoadLightningHandle(Table___ht, this, key)
    endfunction
    function s__Table___lightnings__setindex takes integer this,integer key,lightning value returns nothing
        call SaveLightningHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___lightnings_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___lightnings_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Lightning", "lightning")
//textmacro instance: NEW_ARRAY("Image", "image")
    function s__Table___images__getindex takes integer this,integer key returns image
        return LoadImageHandle(Table___ht, this, key)
    endfunction
    function s__Table___images__setindex takes integer this,integer key,image value returns nothing
        call SaveImageHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___images_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___images_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Image", "image")
//textmacro instance: NEW_ARRAY("Ubersplat", "ubersplat")
    function s__Table___ubersplats__getindex takes integer this,integer key returns ubersplat
        return LoadUbersplatHandle(Table___ht, this, key)
    endfunction
    function s__Table___ubersplats__setindex takes integer this,integer key,ubersplat value returns nothing
        call SaveUbersplatHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___ubersplats_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___ubersplats_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Ubersplat", "ubersplat")
//textmacro instance: NEW_ARRAY("Region", "region")
    function s__Table___regions__getindex takes integer this,integer key returns region
        return LoadRegionHandle(Table___ht, this, key)
    endfunction
    function s__Table___regions__setindex takes integer this,integer key,region value returns nothing
        call SaveRegionHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___regions_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___regions_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Region", "region")
//textmacro instance: NEW_ARRAY("FogState", "fogstate")
    function s__Table___fogstates__getindex takes integer this,integer key returns fogstate
        return LoadFogStateHandle(Table___ht, this, key)
    endfunction
    function s__Table___fogstates__setindex takes integer this,integer key,fogstate value returns nothing
        call SaveFogStateHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___fogstates_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___fogstates_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("FogState", "fogstate")
//textmacro instance: NEW_ARRAY("FogModifier", "fogmodifier")
    function s__Table___fogmodifiers__getindex takes integer this,integer key returns fogmodifier
        return LoadFogModifierHandle(Table___ht, this, key)
    endfunction
    function s__Table___fogmodifiers__setindex takes integer this,integer key,fogmodifier value returns nothing
        call SaveFogModifierHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___fogmodifiers_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___fogmodifiers_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("FogModifier", "fogmodifier")
//textmacro instance: NEW_ARRAY("Hashtable", "hashtable")
    function s__Table___hashtables__getindex takes integer this,integer key returns hashtable
        return LoadHashtableHandle(Table___ht, this, key)
    endfunction
    function s__Table___hashtables__setindex takes integer this,integer key,hashtable value returns nothing
        call SaveHashtableHandle(Table___ht, this, key, value)
    endfunction
    function s__Table___hashtables_has takes integer this,integer key returns boolean
        return HaveSavedHandle(Table___ht, this, key)
    endfunction
    function s__Table___hashtables_remove takes integer this,integer key returns nothing
        call RemoveSavedHandle(Table___ht, this, key)
    endfunction
//end of: NEW_ARRAY("Hashtable", "hashtable")
    
    
    // Implement modules for intuitive syntax (tb.handle; tb.unit; etc.)
//Implemented from module Table___realm:
    function s__Table__get_real takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___integerm:
    function s__Table__get_integer takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___booleanm:
    function s__Table__get_boolean takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___stringm:
    function s__Table__get_string takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___playerm:
    function s__Table__get_player takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___widgetm:
    function s__Table__get_widget takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___destructablem:
    function s__Table__get_destructable takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___itemm:
    function s__Table__get_item takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___unitm:
    function s__Table__get_unit takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___abilitym:
    function s__Table__get_ability takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___timerm:
    function s__Table__get_timer takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___triggerm:
    function s__Table__get_trigger takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___triggerconditionm:
    function s__Table__get_triggercondition takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___triggeractionm:
    function s__Table__get_triggeraction takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___eventm:
    function s__Table__get_event takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___forcem:
    function s__Table__get_force takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___groupm:
    function s__Table__get_group takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___locationm:
    function s__Table__get_location takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___rectm:
    function s__Table__get_rect takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___boolexprm:
    function s__Table__get_boolexpr takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___soundm:
    function s__Table__get_sound takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___effectm:
    function s__Table__get_effect takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___unitpoolm:
    function s__Table__get_unitpool takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___itempoolm:
    function s__Table__get_itempool takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___questm:
    function s__Table__get_quest takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___questitemm:
    function s__Table__get_questitem takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___defeatconditionm:
    function s__Table__get_defeatcondition takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___timerdialogm:
    function s__Table__get_timerdialog takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___leaderboardm:
    function s__Table__get_leaderboard takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___multiboardm:
    function s__Table__get_multiboard takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___multiboarditemm:
    function s__Table__get_multiboarditem takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___trackablem:
    function s__Table__get_trackable takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___dialogm:
    function s__Table__get_dialog takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___buttonm:
    function s__Table__get_button takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___texttagm:
    function s__Table__get_texttag takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___lightningm:
    function s__Table__get_lightning takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___imagem:
    function s__Table__get_image takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___ubersplatm:
    function s__Table__get_ubersplat takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___regionm:
    function s__Table__get_region takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___fogstatem:
    function s__Table__get_fogstate takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___fogmodifierm:
    function s__Table__get_fogmodifier takes integer this returns integer
        return this
    endfunction
//Implemented from module Table___hashtablem:
    function s__Table__get_hashtable takes integer this returns integer
        return this
    endfunction
    
    function s__Table__get_handle takes integer this returns integer
        return this
    endfunction
    
    function s__Table__get_agent takes integer this returns integer
        return this
    endfunction
    
    //set this = tb[GetSpellAbilityId()]
    function s__Table__getindex takes integer this,integer key returns integer
        return LoadInteger(Table___ht, this, key) //return this.integer[key]
    endfunction
    
    //set tb[389034] = 8192
    function s__Table__setindex takes integer this,integer key,integer tb returns nothing
        call SaveInteger(Table___ht, this, key, tb) //set this.integer[key] = tb
    endfunction
    
    //set b = tb.has(2493223)
    function s__Table_has takes integer this,integer key returns boolean
        return HaveSavedInteger(Table___ht, this, key) //return this.integer.has(key)
    endfunction
    
    //call tb.remove(294080)
    function s__Table_remove takes integer this,integer key returns nothing
        call RemoveSavedInteger(Table___ht, this, key) //call this.integer.remove(key)
    endfunction
    
    //Remove all data from a Table instance
    function s__Table_flush takes integer this returns nothing
        call FlushChildHashtable(Table___ht, this)
    endfunction
    
    //local Table tb = Table.create()
    function s__Table_create takes nothing returns integer
        local integer this= (LoadInteger(Table___ht, ((Table___listK)), (0))) // INLINED!!
        
        if this == 0 then
            set this=Table___more + 1
            set Table___more=this
        else
            call SaveInteger(Table___ht, ((Table___listK)), (0), ( (LoadInteger(Table___ht, ((Table___listK)), (this))))) // INLINED!!
            call RemoveSavedInteger(Table___ht, ((Table___listK)), (this)) //Clear hashed memory // INLINED!!
        endif
        
        return this
    endfunction
    
    // Removes all data from a Table instance and recycles its index.
    //
    //     call tb.destroy()
    //
    function s__Table_destroy takes integer this returns nothing
        
        call FlushChildHashtable(Table___ht, (this)) // INLINED!!
        
        call SaveInteger(Table___ht, ((Table___listK)), (this), ( (LoadInteger(Table___ht, ((Table___listK)), (0))))) // INLINED!!
        call SaveInteger(Table___ht, ((Table___listK)), (0), ( this)) // INLINED!!
    endfunction
    
//ignored textmacro command: TABLE_BC_METHODS()
    
//ignored textmacro command: TABLE_BC_STRUCTS()
    
    
    //Returns a new TableArray to do your bidding. Simply use:
    //
    //    local TableArray ta = TableArray[array_size]
    //
    function s__TableArray__staticgetindex takes integer array_size returns integer
        local integer tb= (LoadInteger(Table___ht, ((Table___sizeK)), (array_size))) // INLINED!!
        local integer this= (LoadInteger(Table___ht, (tb), (0))) // INLINED!!
        
        
        if this == 0 then
            set this=Table___less - array_size
            set Table___less=this
        else
            call SaveInteger(Table___ht, (tb), (0), ( (LoadInteger(Table___ht, (tb), (this))))) //Set the last destroyed to the last-last destroyed // INLINED!!
            call RemoveSavedInteger(Table___ht, (tb), (this)) //Clear hashed memory // INLINED!!
        endif
        
        call SaveInteger(Table___ht, ((Table___sizeK)), (this), ( array_size)) //This remembers the array size // INLINED!!
        return this
    endfunction
    
    //Returns the size of the TableArray
    function s__TableArray__get_size takes integer this returns integer
        return (LoadInteger(Table___ht, ((Table___sizeK)), (this))) // INLINED!!
    endfunction
    
    //This magic method enables two-dimensional[array][syntax] for Tables,
    //similar to the two-dimensional utility provided by hashtables them-
    //selves.
    //
    //ta[integer a].unit[integer b] = unit u
    //ta[integer a][integer c] = integer d
    //
    //Inline-friendly when not running in debug mode
    //
    function s__TableArray__getindex takes integer this,integer key returns integer










        return this + key
    endfunction
    
    //Destroys a TableArray without flushing it; I assume you call .flush()
    //if you want it flushed too. This is a public method so that you don't
    //have to loop through all TableArray indices to flush them if you don't
    //need to (ie. if you were flushing all child-keys as you used them).
    //
    function s__TableArray_destroy takes integer this returns nothing
        local integer tb= (LoadInteger(Table___ht, ((Table___sizeK)), ((LoadInteger(Table___ht, ((Table___sizeK)), ((this))))))) // INLINED!!
        
        
        if tb == 0 then
            //Create a Table to index recycled instances with their array size
            set tb=s__Table_create()
            call SaveInteger(Table___ht, ((Table___sizeK)), ((LoadInteger(Table___ht, ((Table___sizeK)), ((this))))), ( tb)) // INLINED!!
        endif
        
        call RemoveSavedInteger(Table___ht, ((Table___sizeK)), (this)) //Clear the array size from hash memory // INLINED!!
        
        call SaveInteger(Table___ht, (tb), (this), ( (LoadInteger(Table___ht, (tb), (0))))) // INLINED!!
        call SaveInteger(Table___ht, (tb), (0), ( this)) // INLINED!!
    endfunction
    
    
    //Avoids hitting the op limit
    function s__TableArray_clean takes nothing returns nothing
        local integer tb= s__TableArray_tempTable
        local integer end= tb + 0x1000
        if end < s__TableArray_tempEnd then
            set s__TableArray_tempTable=end
            call ForForce(bj_FORCE_PLAYER[0], function s__TableArray_clean)
        else
            set end=s__TableArray_tempEnd
        endif
        loop
            call FlushChildHashtable(Table___ht, (tb)) // INLINED!!
            set tb=tb + 1
            exitwhen tb == end
        endloop
    endfunction
    
    //Flushes the TableArray and also destroys it. Doesn't get any more
    //similar to the FlushParentHashtable native than this.
    //
    function s__TableArray_flush takes integer this returns nothing
        set s__TableArray_tempTable=this
        set s__TableArray_tempEnd=this + (LoadInteger(Table___ht, ((Table___sizeK)), ((this)))) // INLINED!!
        call ForForce(bj_FORCE_PLAYER[0], function s__TableArray_clean)
        call s__TableArray_destroy(this)
    endfunction
    
    

//library Table ends
//library TimerUtils:
//*********************************************************************
//* TimerUtils (red+blue+orange flavors for 1.24b+) 2.0
//* ----------
//*
//*  To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//*  To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass)   More scripts: htt://www.wc3c.net
//*
//* For your timer needs:
//*  * Attaching
//*  * Recycling (with double-free protection)
//*
//* set t=NewTimer()      : Get a timer (alternative to CreateTimer)
//* set t=NewTimerEx(x)   : Get a timer (alternative to CreateTimer), call
//*                            Initialize timer data as x, instead of 0.
//*
//* ReleaseTimer(t)       : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2)     : Attach value 2 to timer
//* GetTimerData(t)       : Get the timer's value.
//*                         You can assume a timer's value is 0
//*                         after NewTimer.
//*
//* Multi-flavor:
//*    Set USE_HASH_TABLE to true if you don't want to complicate your life.
//*
//* If you like speed and giberish try learning about the other flavors.
//*
//********************************************************************

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

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

    //It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
    function SetTimerData takes timer t,integer value returns nothing

            // new blue
            call SaveInteger(TimerUtils___ht, 0, GetHandleId(t), value)
            

















    endfunction

    function GetTimerData takes timer t returns integer

            // new blue
            return LoadInteger(TimerUtils___ht, 0, GetHandleId(t))
            

















    endfunction

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

    //==========================================================================================
    // I needed to decide between duplicating code ignoring the "Once and only once" rule
    // and using the ugly textmacros. I guess textmacros won.
    //

    function NewTimerEx takes integer value returns timer
        if ( TimerUtils___tN == 0 ) then
            if ( not TimerUtils___didinit ) then
                //This extra if shouldn't represent a major performance drawback
                //because QUANTITY rule is not supposed to be broken every day. 
                call TriggerEvaluate(st___prototype9[(1)]) // INLINED!!
                set TimerUtils___tN=TimerUtils___tN - 1
            else
                //If this happens then the QUANTITY rule has already been broken, try to fix the
                // issue, else fail.
                set s__TimerUtils___tT[0]= CreateTimer()















            endif
        else
            set TimerUtils___tN=TimerUtils___tN - 1
        endif
        call SaveInteger(TimerUtils___ht, 0, GetHandleId((s__TimerUtils___tT[TimerUtils___tN] )), ( value)) // INLINED!!
     return s__TimerUtils___tT[TimerUtils___tN]
    endfunction
    
    function NewTimer takes nothing returns timer
        return NewTimerEx(0)
    endfunction


    //==========================================================================================
    function ReleaseTimer takes timer t returns nothing
        if ( t == null ) then
            return
        endif
        if ( TimerUtils___tN == TimerUtils___ARRAY_SIZE ) then
            //stack is full, the map already has much more troubles than the chance of bug
            call DestroyTimer(t)
        else
            call PauseTimer(t)
            if ( (LoadInteger(TimerUtils___ht, 0, GetHandleId((t)))) == TimerUtils___HELD ) then // INLINED!!
                return
            endif
            call SaveInteger(TimerUtils___ht, 0, GetHandleId((t )), ( TimerUtils___HELD)) // INLINED!!
            set s__TimerUtils___tT[TimerUtils___tN]= t
            set TimerUtils___tN=TimerUtils___tN + 1
        endif
    endfunction

    function TimerUtils___init takes nothing returns nothing
     local integer i=0
     local integer o=- 1
     local boolean oops= false
        if ( TimerUtils___didinit ) then
            return
        else
            set TimerUtils___didinit=true
        endif
     

            set TimerUtils___ht=InitHashtable()
            loop
                exitwhen ( i == TimerUtils___QUANTITY )
                set s__TimerUtils___tT[i]= CreateTimer()
                call SaveInteger(TimerUtils___ht, 0, GetHandleId((s__TimerUtils___tT[i] )), ( TimerUtils___HELD)) // INLINED!!
                set i=i + 1
            endloop
            set TimerUtils___tN=TimerUtils___QUANTITY










































    endfunction


//library TimerUtils ends
//library WorldBounds:

//Implemented from module WorldBounds___WorldBoundInit:
        function s__WorldBounds_WorldBounds___WorldBoundInit__onInit takes nothing returns nothing
            set s__WorldBounds_world=GetWorldBounds()
            set s__WorldBounds_maxX=R2I(GetRectMaxX(s__WorldBounds_world))
            set s__WorldBounds_maxY=R2I(GetRectMaxY(s__WorldBounds_world))
            set s__WorldBounds_minX=R2I(GetRectMinX(s__WorldBounds_world))
            set s__WorldBounds_minY=R2I(GetRectMinY(s__WorldBounds_world))
            set s__WorldBounds_centerX=R2I(( s__WorldBounds_maxX + s__WorldBounds_minX ) / 2)
            set s__WorldBounds_centerY=R2I(( s__WorldBounds_minY + s__WorldBounds_maxY ) / 2)
            set s__WorldBounds_worldRegion=CreateRegion()
            call RegionAddRect(s__WorldBounds_worldRegion, s__WorldBounds_world)
        endfunction

//library WorldBounds ends
//library Alloc:

//library Alloc ends
//library ExtendedSound:

    
    
    
    
        
        
        
        function s__ExSound__get_duration takes integer this returns real
            return s__ExSound_dur[this] * ExtendedSound___RAPID_DELAY_FACTOR
        endfunction
        
        function s__ExSound_kill takes integer this returns nothing
        
            local integer i
            
            set s__ExSound_ct[this]=s__ExSound_ct[this] - 1
            if s__ExSound_ct[this] == 0 then
                set i=0
                loop
                    exitwhen i == s__ExSound_MAX_COUNT
                    
                    call StopSound(s___ExSound_snd[s__ExSound_snd[this]+i], true, false)

                        call ReleaseTimer(s___ExSound_tmr[s__ExSound_tmr[this]+i])



                    
                    set s___ExSound_snd[s__ExSound_snd[this]+i]=null
                    set s___ExSound_tmr[s__ExSound_tmr[this]+i]=null
                    
                    set i=i + 1
                endloop
                
                set s__ExSound_StrLib[s__ExSound_lib[this]]=s__ExSound_StrLib[s__ExSound_Counter]
                set s__ExSound_Counter=s__ExSound_Counter - 1
                call s__ExSound_deallocate(this)
            endif
            
        endfunction
        
        function s__ExSound_stop takes integer this,boolean fadeOut returns nothing
        
            local integer i= 0
            
            loop
                exitwhen i == s__ExSound_MAX_COUNT
                call StopSound(s___ExSound_snd[s__ExSound_snd[this]+i], false, fadeOut)
                set i=i + 1
            endloop
            
        endfunction
        
        function s__ExSound_play takes integer this,real x,real y,real z,integer volume returns nothing
            
            set s__ExSound_dex[this]=s__ExSound_dex[this] + 1
            if s__ExSound_dex[this] == s__ExSound_MAX_COUNT then
                set s__ExSound_dex[this]=0
            endif
            
            if TimerGetRemaining(s___ExSound_tmr[s__ExSound_tmr[this]+s__ExSound_dex[this]]) == 0 then
                call StopSound(s___ExSound_snd[s__ExSound_snd[this]+s__ExSound_dex[this]], false, false)
                call SetSoundPosition(s___ExSound_snd[s__ExSound_snd[this]+s__ExSound_dex[this]], x, y, z)
                call SetSoundVolume(s___ExSound_snd[s__ExSound_snd[this]+s__ExSound_dex[this]], volume)
                call StartSound(s___ExSound_snd[s__ExSound_snd[this]+s__ExSound_dex[this]])
                call TimerStart(s___ExSound_tmr[s__ExSound_tmr[this]+s__ExSound_dex[this]], s__ExSound_dur[this], false, null)
            endif
            
        endfunction
        
        function s__ExSound_create takes string fileName,boolean is3D,boolean autoStop,integer inRate,integer outRate returns integer
        
            local integer this
            local integer i= 0
            local boolean b= true
            
            loop
                exitwhen i > s__ExSound_Counter
                if fileName == s__ExSound_StrLib[i] then
                    set b=false
                    exitwhen true
                endif
                set i=i + 1
            endloop
            
            if b then
                set s__ExSound_Counter=s__ExSound_Counter + 1
                set s__ExSound_StrLib[s__ExSound_Counter]=fileName
                set this=s__ExSound__allocate()
                
                set s__ExSound_ct[this]=1
                set s__ExSound_dex[this]=- 1
                set s__ExSound_lib[this]=s__ExSound_Counter
                set s__ExSound_dur[this]=I2R(GetSoundFileDuration(fileName)) / ( 1000 * ExtendedSound___RAPID_DELAY_FACTOR )
                
                set i=0
                loop
                    exitwhen i == s__ExSound_MAX_COUNT
                    
                    set s___ExSound_snd[s__ExSound_snd[this]+i]=CreateSound(fileName, false, is3D, autoStop, inRate, outRate, "")

                        set s___ExSound_tmr[s__ExSound_tmr[this]+i]=(NewTimerEx(0)) // INLINED!!



                    
                    set i=i + 1
                endloop
            else
                set this=i
                set s__ExSound_ct[this]=s__ExSound_ct[this] + 1
            endif
            
            return this
        endfunction
        
    

//library ExtendedSound ends
//library Track:

    

        
        
        
        
        
        function s__Track_registerAnyClick takes code c returns nothing
            call TriggerAddCondition(s__Track_anyClick, Filter(c))
        endfunction
        function s__Track_registerAnyHover takes code c returns nothing
            call TriggerAddCondition(s__Track_anyHover, Filter(c))
        endfunction
        
        function s__Track_registerClick takes integer this,code c returns nothing
            if s__Track_onClick[this] == null then
                set s__Track_onClick[this]=CreateTrigger()
            endif
            call TriggerAddCondition(s__Track_onClick[this], Filter(c))
        endfunction
        function s__Track_registerHover takes integer this,code c returns nothing
            if s__Track_onHover[this] == null then
                set s__Track_onHover[this]=CreateTrigger()
            endif
            call TriggerAddCondition(s__Track_onHover[this], Filter(c))
        endfunction
        
        function s__Track_destroy takes integer this returns nothing
            call RemoveSavedInteger(Table___ht, (s__Track_TrackTable), (GetHandleId(s__Track_reg[this]))) // INLINED!!
            call RemoveSavedInteger(Table___ht, (s__Track_TrackTable), (GetHandleId(s__Track_object))) // INLINED!!
			
            call DestroyTrigger(s__Track_reg[this])
            call DestroyTrigger(s__Track_onClick[this])
            call DestroyTrigger(s__Track_onHover[this])
			
            set s__Track_rn[this]=s__Track_ir
            set s__Track_ir=this
        endfunction
        
        function s__Track__set_enabled takes integer this,boolean flag returns nothing
            set s__Track_flag[this]=flag
        endfunction
        function s__Track__get_enabled takes integer this returns boolean
            return s__Track_flag[this]
        endfunction
        
        function s__Track_onInteract takes nothing returns boolean
            local integer temp= s__Track_instance
            local trackable tr
            local player p
            
			set s__Track_instance=(LoadInteger(Table___ht, (s__Track_TrackTable), (GetHandleId(GetTriggeringTrigger())))) // INLINED!!
			
            if s__Track_flag[s__Track_instance] then
				set tr=s__Track_object
				set p=s__Track_tracker
				
				set s__Track_object=GetTriggeringTrackable()
				set s__Track_tracker=Player((LoadInteger(Table___ht, (s__Track_TrackTable), (GetHandleId(s__Track_object))))) // INLINED!!
				
                if GetTriggerEventId() == EVENT_GAME_TRACKABLE_TRACK then
                    call TriggerEvaluate(s__Track_onHover[s__Track_instance])
                    call TriggerEvaluate(s__Track_anyHover)
                else
                    call TriggerEvaluate(s__Track_onClick[s__Track_instance])
                    call TriggerEvaluate(s__Track_anyClick)
                endif
				
				set s__Track_instance=temp
				set s__Track_object=tr
				set s__Track_tracker=p
				
				set tr=null
				set p=null
            endif
			
            return false
        endfunction
        
        function s__Track_createTrack takes string modelPath,real x,real y,real z,real facing,player j returns integer
            local destructable dest= null
            local integer this= s__Track_ir
            local integer i= 11
            local trackable tr
            local player p
            local string s
			
			
            if this == 0 then
                set s__Track_ic=s__Track_ic + 1
                set this=s__Track_ic
            else
                set s__Track_ir=s__Track_rn[this]
            endif
			
			
            if z != 0 then
                set dest=CreateDestructableZ(Track___PLATFORM, x, y, z, 0, 1, 0)
            endif
            if j != null then
                set i=GetPlayerId(j)
            endif
			
            set s__Track_x[this]=x
            set s__Track_y[this]=y
            set s__Track_z[this]=z
            set s__Track_flag[this]=true
            set s__Track_facing[this]=facing
            set s__Track_model[this]=modelPath
            set s__Track_reg[this]=CreateTrigger()
            set s__Track_onClick[this]=null
            set s__Track_onHover[this]=null
			
            call SaveInteger(Table___ht, (s__Track_TrackTable), (GetHandleId(s__Track_reg[this])), ( this)) // INLINED!!
            call TriggerAddCondition(s__Track_reg[this], Condition(function s__Track_onInteract))
			
			
            loop
                set p=Player(i)
                if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER then
                    if GetLocalPlayer() == p then
                        set s=modelPath
                    else
                        set s=""
                    endif
                    set tr=CreateTrackable(s, s__Track_x[this], s__Track_y[this], s__Track_facing[this])
                    call TriggerRegisterTrackableHitEvent(s__Track_reg[this], tr)
                    call TriggerRegisterTrackableTrackEvent(s__Track_reg[this], tr)
                    call SaveInteger(Table___ht, (s__Track_TrackTable), (GetHandleId(tr)), ( i)) // INLINED!!
                    if j != null then
                        exitwhen true
                    endif
                endif
                exitwhen i == 0
                set i=i - 1
            endloop
			
			
            if dest != null then
                call RemoveDestructable(dest)
                set dest=null
            endif
            set p=null
            set tr=null
			
            return this
        endfunction
        
        function s__Track_create takes string modelPath,real x,real y,real z,real facing returns integer
            return s__Track_createTrack(modelPath , x , y , z , facing , null)
        endfunction 
        
        function s__Track_createForPlayer takes string modelPath,real x,real y,real z,real facing,player p returns integer
            if not ( GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER ) then
                return 0
            endif
            return s__Track_createTrack(modelPath , x , y , z , facing , p)
        endfunction
        
//Implemented from module Track___Init:
        function s__Track_Track___Init__onInit takes nothing returns nothing
            set s__Track_TrackTable=s__Table_create()
        endfunction
    
	
	
    function CreateTrack takes string modelPath,real x,real y,real z,real facing returns integer
        return (s__Track_createTrack((modelPath ) , (( x )*1.0) , (( y )*1.0) , (( z )*1.0) , (( facing)*1.0) , null)) // INLINED!!
    endfunction
    
    function CreateTrackForPlayer takes string modelPath,real x,real y,real z,real facing,player who returns integer
        return s__Track_createForPlayer(modelPath , x , y , z , facing , who)
    endfunction
    
    function EnableTrackInstance takes integer instance,boolean flag returns nothing
        set s__Track_flag[(instance)]=(flag) // INLINED!!
    endfunction
    
    function IsTrackInstanceEnabled takes integer instance returns boolean
        return (s__Track_flag[(instance)]) // INLINED!!
    endfunction
    
    function RegisterAnyClickEvent takes code c returns nothing
        call TriggerAddCondition(s__Track_anyClick, Filter((c))) // INLINED!!
    endfunction
    
    function RegisterAnyHoverEvent takes code c returns nothing
        call TriggerAddCondition(s__Track_anyHover, Filter((c))) // INLINED!!
    endfunction
    
    function RegisterClickEvent takes integer obj,code c returns nothing
        call s__Track_registerClick(obj,c)
    endfunction
    
    function RegisterHoverEvent takes integer obj,code c returns nothing
        call s__Track_registerHover(obj,c)
    endfunction
    
    function GetTriggerTrackInstance takes nothing returns integer
        return s__Track_instance
    endfunction
    
    function GetTriggerTrackable takes nothing returns trackable
        return s__Track_object
    endfunction
    
    function GetTriggerTrackablePlayer takes nothing returns player
        return s__Track_tracker
    endfunction

//library Track ends
//library UnitIndexer:

    function GetIndexedUnitId takes nothing returns integer
        return UnitIndexer___o
    endfunction
    function GetIndexedUnit takes nothing returns unit
        return UnitIndexer___e[UnitIndexer___o]
    endfunction
//ignored textmacro command: UNIT_LIST_LIB()
        function s__UnitIndexer___PreLoader_run takes nothing returns nothing
            call DestroyTimer(GetExpiredTimer())
            set UnitIndexer___a=true
        endfunction
        function s__UnitIndexer___PreLoader_eval takes trigger t returns nothing
            local integer f=UnitIndexer___n[0]
            local integer d=UnitIndexer___o
            loop
                exitwhen 0 == f
                if ( IsTriggerEnabled(t) ) then
                    set UnitIndexer___o=f
                    if ( TriggerEvaluate(t) ) then
                        call TriggerExecute(t)
                    endif
                else
                    exitwhen true
                endif
                set f=UnitIndexer___n[f]
            endloop
            set UnitIndexer___o=d
        endfunction
        function s__UnitIndexer___PreLoader_evalb takes boolexpr c returns nothing
            local trigger t=CreateTrigger()
            local integer f=UnitIndexer___n[0]
            local integer d=UnitIndexer___o
            call TriggerAddCondition(t, c)
            loop
                exitwhen 0 == f
                set UnitIndexer___o=f
                call TriggerEvaluate(t)
                set f=UnitIndexer___n[f]
            endloop
            call DestroyTrigger(t)
            set t=null
            set UnitIndexer___o=d
        endfunction
//ignored textmacro command: UNIT_EVENT_MACRO()
        function s__UnitIndex_lock takes integer this returns nothing
                set UnitIndexer___lc[this]=UnitIndexer___lc[this] + 1
        endfunction
        function s__UnitIndex_unlock takes integer this returns nothing
                set UnitIndexer___lc[this]=UnitIndexer___lc[this] - 1
                if ( 0 == UnitIndexer___lc[this] and null == UnitIndexer___e[this] ) then
                    set UnitIndexer___n[this]=UnitIndexer___y
                    set UnitIndexer___y=this
                endif
        endfunction
        function s__UnitIndex__get_unit takes integer this returns unit
            return UnitIndexer___e[this]
        endfunction
        function s__UnitIndex__staticgetindex takes unit whichUnit returns integer
            return GetUnitUserData(whichUnit)
        endfunction
        function s__UnitIndexer_onEnter takes nothing returns boolean
            local unit Q=GetFilterUnit()
            local integer i
            local integer d=UnitIndexer___o
            if ( s__UnitIndexer_enabled and Q != UnitIndexer___e[GetUnitUserData(Q)] and 0 == GetUnitUserData(Q) ) then
                if ( 0 == UnitIndexer___y ) then
                    set UnitIndexer___r=UnitIndexer___r + 1
                    set i=UnitIndexer___r
                else
                    set i=UnitIndexer___y
                    set UnitIndexer___y=UnitIndexer___n[UnitIndexer___y]
                endif
                call UnitAddAbility(Q, ABILITIES_UNIT_INDEXER)
                call UnitMakeAbilityPermanent(Q, true, ABILITIES_UNIT_INDEXER)
                call SetUnitUserData(Q, i)
                set UnitIndexer___e[i]=Q

                    if ( not UnitIndexer___a ) then
                        set UnitIndexer___p[i]=UnitIndexer___p[0]
                        set UnitIndexer___n[UnitIndexer___p[0]]=i
                        set UnitIndexer___n[i]=0
                        set UnitIndexer___p[0]=i
                    endif







                set UnitIndexer___o=i
                call s__Event_fire((s__UnitIndexer_INDEX)) // INLINED!!
                set UnitIndexer___o=d
            endif
            set Q=null
            return false
        endfunction
        function s__UnitIndexer_onLeave takes nothing returns boolean


                local unit u=GetFilterUnit()
                local integer i=GetUnitUserData(u)
                local integer d=UnitIndexer___o
                if ( 0 == GetUnitAbilityLevel(u, ABILITIES_UNIT_INDEXER) and u == UnitIndexer___e[i] ) then

                        if ( not UnitIndexer___a ) then
                            set UnitIndexer___n[UnitIndexer___p[i]]=UnitIndexer___n[i]
                            set UnitIndexer___p[UnitIndexer___n[i]]=UnitIndexer___p[i]
                        endif





                    set UnitIndexer___o=i
                    call s__Event_fire((s__UnitIndexer_DEINDEX)) // INLINED!!
                    set UnitIndexer___o=d
                    if ( 0 == UnitIndexer___lc[i] ) then
                        set UnitIndexer___n[i]=UnitIndexer___y
                        set UnitIndexer___y=i
                    endif
                    set UnitIndexer___e[i]=null
                endif
                set u=null

            return false
        endfunction
//Implemented from module UnitIndexer___UnitIndexerInit:
        function s__UnitIndexer_UnitIndexer___UnitIndexerInit__onInit takes nothing returns nothing
            local integer i=15
            local boolexpr bc=Condition(function s__UnitIndexer_onLeave)
            local boolexpr bc2=Condition(function s__UnitIndexer_onEnter)
            local group g=CreateGroup()
            local player l__UnitIndexer___p
            set s__UnitIndexer_INDEX=(s__Event_create()) // INLINED!!
            set s__UnitIndexer_DEINDEX=(s__Event_create()) // INLINED!!
            call TriggerRegisterEnterRegion(UnitIndexer___q, s__WorldBounds_worldRegion, bc2)
            loop
                set l__UnitIndexer___p=Player(i)
                call TriggerRegisterPlayerUnitEvent(UnitIndexer___l, l__UnitIndexer___p, EVENT_PLAYER_UNIT_ISSUED_ORDER, bc)
                call SetPlayerAbilityAvailable(l__UnitIndexer___p, ABILITIES_UNIT_INDEXER, false)
                call GroupEnumUnitsOfPlayer(g, l__UnitIndexer___p, bc2)
                exitwhen 0 == i
                set i=i - 1
            endloop
            call DestroyGroup(g)
            set bc=null
            set g=null
            set bc2=null
            set l__UnitIndexer___p=null
            call TimerStart(CreateTimer(), 0, false, function s__UnitIndexer___PreLoader_run)
        endfunction
//ignored textmacro command: UNIT_EVENT_MACRO_2()
    function RegisterUnitIndexEvent takes boolexpr c,integer ev returns nothing
        call RegisterEvent(c , ev)
        if ( not UnitIndexer___a and ev == s__UnitIndexer_INDEX and 0 != UnitIndexer___n[0] ) then
            call s__UnitIndexer___PreLoader_evalb(c)
        endif
    endfunction
    function TriggerRegisterUnitIndexEvent takes trigger t,integer ev returns nothing
        call TriggerRegisterEvent(t , ev)
        if ( not UnitIndexer___a and ev == s__UnitIndexer_INDEX and 0 != UnitIndexer___n[0] ) then
            call s__UnitIndexer___PreLoader_eval(t)
        endif
    endfunction
    function GetUnitById takes integer W returns unit
        return UnitIndexer___e[W]
    endfunction
    function GetUnitId takes unit u returns integer
        return GetUnitUserData(u)
    endfunction
    function IsUnitIndexed takes unit u returns boolean
        return u == UnitIndexer___e[GetUnitUserData(u)]
    endfunction
    function IsUnitDeindexing takes unit u returns boolean
        return IsUnitIndexed(u) and 0 == GetUnitAbilityLevel(u, ABILITIES_UNIT_INDEXER)
    endfunction

//library UnitIndexer ends
//library AutoFly:
    function AutoFly___i takes nothing returns boolean
        return UnitAddAbility((UnitIndexer___e[UnitIndexer___o]), 'Amrf') and UnitRemoveAbility((UnitIndexer___e[UnitIndexer___o]), 'Amrf') // INLINED!!
    endfunction
//Implemented from module AutoFly___Init:
        function s__AutoFly___Inits_AutoFly___Init__onInit takes nothing returns nothing
            call RegisterUnitIndexEvent(Condition(function AutoFly___i) , s__UnitIndexer_INDEX)
        endfunction

//library AutoFly ends
//library Missile:

    
    function GetUnitBodySize takes unit whichUnit returns real
        return 100. // LoadReal(hash, GetHandleId(whichUnit), KEY_UNIT_BODY_SIZE)<- Example
    endfunction

    
    function GetDestructableHeight takes destructable whichDestructable returns real
        return GetDestructableOccluderHeight(whichDestructable)
    endfunction
    


// Hello and welcome to Missile.
// I wrote a guideline for every piece of code inside Missile, so you 
// can easily understand how the code gets compiled and evaluated.
//
// Let's go!
       
    // If you set WRITE_DELAYED_MISSILE_RECYCLING from the configs to true, the compiler will write
    // a recycler bin, doing delayed dummy unit recycling, into Missle. 
    // If set to false, no code is created here as the code is ignored via "static if".
    //
    // The code of the macro is located at the bottom of Missile, as it would hurt read-ability if placed here.
//textmacro instance: WRITE_MISSILE_RECYCLE_BIN("WRITE_DELAYED_MISSILE_RECYCLING", "DELAYED_MISSILE_DEATH_ANIMATION_TIME")

        // In order to play a proper death animation,
        // RecycleBin to recycles missiles after 
        // DEFAULT_DEATH_ANIMATION_TIME
     
            function s__Missile___RecycleBin_handlerFunc takes nothing returns nothing
                local integer index= 0
                loop
                    exitwhen index == s__Missile___RecycleBin_alloc
                    set s__Missile___RecycleBin_time[index]=s__Missile___RecycleBin_time[index] - 1
                    if ( 0 >= s__Missile___RecycleBin_time[index] ) then
                    










                            call RemoveUnit(s__Missile___RecycleBin_dummy[index])

                    
                        set s__Missile___RecycleBin_dummy[index]=null
                        set s__Missile___RecycleBin_alloc=s__Missile___RecycleBin_alloc - 1
                        set s__Missile___RecycleBin_dummy[index]=s__Missile___RecycleBin_dummy[s__Missile___RecycleBin_alloc]
                        set s__Missile___RecycleBin_time[index]=s__Missile___RecycleBin_time[s__Missile___RecycleBin_alloc]
                        set s__Missile___RecycleBin_dummy[s__Missile___RecycleBin_alloc]=null
                        set index=index - 1
                    
                        if ( 0 == s__Missile___RecycleBin_alloc ) then
                            call PauseTimer(s__Missile___RecycleBin_t)
                        endif
                    
                    endif
                    set index=index + 1
                endloop
            endfunction
    
            function s__Missile___RecycleBin_recycle takes unit toRecycle returns nothing
                if ( 0 == s__Missile___RecycleBin_alloc ) then
                    call TimerStart(s__Missile___RecycleBin_t, 1., true, function s__Missile___RecycleBin_handlerFunc)
                endif
                set s__Missile___RecycleBin_dummy[s__Missile___RecycleBin_alloc]=toRecycle
                set s__Missile___RecycleBin_time[s__Missile___RecycleBin_alloc]=Missile___DELAYED_MISSILE_DEATH_ANIMATION_TIME + TimerGetRemaining(s__Missile___RecycleBin_t)
                set s__Missile___RecycleBin_alloc=s__Missile___RecycleBin_alloc + 1
            endfunction
    

//end of: WRITE_MISSILE_RECYCLE_BIN("WRITE_DELAYED_MISSILE_RECYCLING", "DELAYED_MISSILE_DEATH_ANIMATION_TIME")
    
    function Missile_GetLocZ takes real x,real y returns real
        call MoveLocation(s__MissilePosition_loc, x, y)
        return GetLocationZ(s__MissilePosition_loc)
    endfunction
    
    // This macro boxes a missiles positions and does the required trigonometry.
    //
    // The code of the macro is located at the bottom of Missile, as it would hurt read-ability if placed here.
//textmacro instance: WRITE_MISSILE_POSITION_CODE()
            
            
            
            function s__MissilePosition_math takes integer a,integer b returns boolean
                set s__MissilePosition_angle[a]=Atan2(s__MissilePosition_y[b] - s__MissilePosition_y[a], s__MissilePosition_x[b] - s__MissilePosition_x[a])
                set s__MissilePosition_distance[a]=SquareRoot(( s__MissilePosition_x[b] - s__MissilePosition_x[a] ) * ( s__MissilePosition_x[b] - s__MissilePosition_x[a] ) + ( s__MissilePosition_y[b] - s__MissilePosition_y[a] ) * ( s__MissilePosition_y[b] - s__MissilePosition_y[a] ))
                if ( s__MissilePosition_distance[a] != 0 ) then
                    set s__MissilePosition_slope[a]=( s__MissilePosition_z[b] - s__MissilePosition_z[a] ) / s__MissilePosition_distance[a]
                else // Error! I decide we do this math again!
                    set s__MissilePosition_x[a]=s__MissilePosition_x[a] + .0001
                    return false
                endif
                set s__MissilePosition_alpha[a]=Atan(s__MissilePosition_slope[a]) * bj_RADTODEG
                
                set s__MissilePosition_angle[b]=s__MissilePosition_angle[a] + bj_PI
                set s__MissilePosition_distance[b]=s__MissilePosition_distance[a]
                set s__MissilePosition_slope[b]=- s__MissilePosition_slope[a]
                set s__MissilePosition_alpha[b]=- s__MissilePosition_alpha[a]
                return true
            endfunction
            
            function s__MissilePosition_link takes integer a,integer b returns nothing
                set s__MissilePosition_ref[a]=b
                set s__MissilePosition_ref[b]=a
                loop
                    exitwhen s__MissilePosition_math(a , b)
                endloop
            endfunction
            
            function s__MissilePosition_move takes integer this,real toX,real toY,real toZ returns nothing
                call MoveLocation(s__MissilePosition_loc, toX, toY)
                set s__MissilePosition_x[this]=toX
                set s__MissilePosition_y[this]=toY
                set s__MissilePosition_z[this]=toZ + GetLocationZ(s__MissilePosition_loc)
                if ( s__MissilePosition_ref[this] != this ) then
                    loop
                        exitwhen s__MissilePosition_math(this , s__MissilePosition_ref[this])
                    endloop
                endif
            endfunction
    
            function s__MissilePosition_destroy takes integer this returns nothing
                set s__MissilePosition_recycler[this]=s__MissilePosition_recycler[0]
                set s__MissilePosition_recycler[0]=this
            endfunction
    
            function s__MissilePosition_create takes real x,real y,real z returns integer
                local integer this= s__MissilePosition_recycler[0]
                 if ( 0 == this ) then
                    set s__MissilePosition_alloc=s__MissilePosition_alloc + 1
                    set this=s__MissilePosition_alloc
                else
                    set s__MissilePosition_recycler[0]=s__MissilePosition_recycler[this]
                endif
                set s__MissilePosition_ref[this]=this
                call s__MissilePosition_move(this,x , y , z)
                return this
            endfunction
    
//end of: WRITE_MISSILE_POSITION_CODE()
    
    // keywords are replaced directives for a scope.
    // Missiles structure works like a list with the folling methods:
    // allocateCollection(), allocateNode(), insertEnd(node) and remove()
    //
    // MissileStructure is implemented as a module
    // The code is located at the bottom of Missile, as it would also hurt read-ability if placed here.
//Implemented from module Missile___MissileStructure:
        


        
        function s__Missile__get_list takes integer this returns integer


            return s__Missile_Missile___MissileStructure___list[this]
        endfunction
        
        function s__Missile__get_next takes integer this returns integer


            return s__Missile_Missile___MissileStructure___next[this]
        endfunction
        
        function s__Missile__get_prev takes integer this returns integer


            return s__Missile_Missile___MissileStructure___prev[this]
        endfunction
        
        function s__Missile__get_first takes integer this returns integer


            return s__Missile_Missile___MissileStructure___first[this]
        endfunction
        
        function s__Missile__get_last takes integer this returns integer


            return s__Missile_Missile___MissileStructure___last[this]
        endfunction
        
        function s__Missile_allocateCollection takes nothing returns integer
            local integer this= s__Missile_Missile___MissileStructure___first[(0)]
            
            if ( 0 == this ) then


                
                set this=s__Missile_Missile___MissileStructure__collectionCount + 1
                set s__Missile_Missile___MissileStructure__collectionCount=this
            else
                set s__Missile_Missile___MissileStructure___first[(0)]=s__Missile_Missile___MissileStructure___first[this]
            endif
            


            
            set s__Missile_Missile___MissileStructure___first[this]=0
            
            return this
        endfunction
        
        function s__Missile_allocateNode takes nothing returns integer
            local integer this= s__Missile_Missile___MissileStructure___next[(0)]
            
            if ( 0 == this ) then


                
                set this=s__Missile_Missile___MissileStructure__nodeCount + 1
                set s__Missile_Missile___MissileStructure__nodeCount=this
            else
                set s__Missile_Missile___MissileStructure___next[(0)]=s__Missile_Missile___MissileStructure___next[this]
            endif
            
            return this
        endfunction
        
        function s__Missile_insertEnd takes integer this,integer node returns integer
            


            
            
            set s__Missile_Missile___MissileStructure___list[node]=this
        
            if ( s__Missile_Missile___MissileStructure___first[this] == 0 ) then
                set s__Missile_Missile___MissileStructure___first[this]=node
                set s__Missile_Missile___MissileStructure___last[this]=node
                set s__Missile_Missile___MissileStructure___prev[node]=0
            else
                set s__Missile_Missile___MissileStructure___next[s__Missile_Missile___MissileStructure___last[this]]=node
                set s__Missile_Missile___MissileStructure___prev[node]=s__Missile_Missile___MissileStructure___last[this]
                set s__Missile_Missile___MissileStructure___last[this]=node
            endif
            
            set s__Missile_Missile___MissileStructure___next[node]=0
            
            return node
        endfunction
        
        function s__Missile_remove takes integer this returns nothing
            local integer node= this
            set this=s__Missile_Missile___MissileStructure___list[node]
            


            
            set s__Missile_Missile___MissileStructure___list[node]=0
        
            if ( 0 == s__Missile_Missile___MissileStructure___prev[node] ) then
                set s__Missile_Missile___MissileStructure___first[this]=s__Missile_Missile___MissileStructure___next[node]
            else
                set s__Missile_Missile___MissileStructure___next[s__Missile_Missile___MissileStructure___prev[node]]=s__Missile_Missile___MissileStructure___next[node]
            endif
            if ( 0 == s__Missile_Missile___MissileStructure___next[node] ) then
                set s__Missile_Missile___MissileStructure___last[this]=s__Missile_Missile___MissileStructure___prev[node]
            else
                set s__Missile_Missile___MissileStructure___prev[s__Missile_Missile___MissileStructure___next[node]]=s__Missile_Missile___MissileStructure___prev[node]
            endif
            
            set s__Missile_Missile___MissileStructure___next[node]=s__Missile_Missile___MissileStructure___next[(0)]
            set s__Missile_Missile___MissileStructure___next[(0)]=node
        endfunction
        
        // I included enormous debug safety to Missile, 
        // in order to eradicate wrong user usage.
        // You should do this with every system you write. 
        //
        // Set MORE_SAFETY to false, once major mistakes are
        // purged from your code. It will create a more realistic
        // performance to a non DEBUG_MODE code, because many
        // error checks are then excluded via "static if".
        // 
        // Placed here on purpose, to ensure that less experienced users
        // recieve the full range of debug features. Basically they will
        // never find this constant boolean :)!
        
        // launched prevents double launching! Very logical. DEBUG_MODE only.
        
        // Effect attach point name. Read-only for shared usage in your map.
        // Of course only if you read until here :)!
        
        // Defines a default unit hit box in range of 0 to 1,
        // while 0 is the toe and 1 the head of a unit.
        
        // Please do not use this group from somewhere else,
        // as it may conflict with Missiles code execution.
        // Rather go with bj_lastCreatedGroup.
        
        // Prevents a double free case.
        
        // Useful struct members. Names chosen to be self-explaining.
        
        
        
        // For curved missiles the position of a missile is not
        // equal to the x/y required by Missiles trigonometry.
        // Therefore we need this member two times.
        // x/y/z for your needs and xPrivate/yPrivate for cool mathematics.
        

        // wantDestroy deallocates an instance on the next
        // timer callback. 100% safe to use.
        
        // recycle is set to true, when a missile reached
        // it's destination. Then it may be destroyed.
        
        // distance traveled.
        
        // Members for your needs.
        // No operator overloading, expect in a few cases.
        
        // As the dummy always belongs to the neutral player.
        // You can add a pseudo owner for faster onCollide evaluation.
        // No monitoring or nulling included. Use carefully.

// I really don't know how wc3 works with negative collision values. (bug free???)
// So I decided to monitor collision and eventually collisionZ.


















// Without debug mode we give a shit on monitoring!





// Speed determines the lenght of our vector for Missile movement.
// Non positive values and zero are invalid. So let's monitor again.











        
        // You can attach any data to a missile.
        
        // Dummy is readonly so you can add more than one model.
        function s__Missile__set_model takes integer this,string modelFile returns nothing
            if ( s__Missile_sfx[this] != null ) then
                call DestroyEffect(s__Missile_sfx[this])
            endif
            set s__Missile_path[this]=modelFile
            set s__Missile_sfx[this]=AddSpecialEffectTarget(modelFile, s__Missile_dummy[this], s__Missile_ORIGIN)
        endfunction
        function s__Missile__get_model takes integer this returns string
            return s__Missile_path[this]
        endfunction
       
        // Simple trigonometry, some values will freak out the missile movement.
        function s__Missile__set_curve takes integer this,real value returns nothing
            set s__Missile_open[this]=Tan(value) * s__MissilePosition_distance[s__Missile_origin[this]]
        endfunction
        function s__Missile__get_curve takes integer this returns real
            if ( s__MissilePosition_distance[s__Missile_origin[this]] == 0 ) then
                return 0. // It's a limit of sequence and crashes the thread. Intuitively  chosen 0.
            endif
            return Atan(s__Missile_open[this] / s__MissilePosition_distance[s__Missile_origin[this]])
        endfunction
       
        // Simple trigonometry, some values will freak out the missile movement.
        function s__Missile__set_arc takes integer this,real value returns nothing
            set s__Missile_height[this]=Tan(value) * s__MissilePosition_distance[s__Missile_origin[this]] / 4
        endfunction
        function s__Missile__get_arc takes integer this returns real
            if ( s__MissilePosition_distance[s__Missile_origin[this]] == 0 ) then
                return 0. // It's a limit of sequence and crashes the thread. Intuitively  chosen 0.
            endif
            return Atan(4 * s__Missile_height[this] / s__MissilePosition_distance[s__Missile_origin[this]])
        endfunction
       
        function s__Missile__set_scale takes integer this,real value returns nothing
            call SetUnitScale(s__Missile_dummy[this], value, 1., 1.)
            set s__Missile_missileScale[this]=value
        endfunction
        function s__Missile__get_scale takes integer this returns real
            return s__Missile_missileScale[this]
        endfunction
    
        function s__Missile_bounce takes integer this returns nothing
            call s__MissilePosition_move(s__Missile_origin[this],s__Missile_xPrivate[this] , s__Missile_yPrivate[this] , s__Missile_z[this])
            set s__Missile_distance[this]=0
        endfunction
       
        function s__Missile_deflect takes integer this,real tx,real ty returns nothing
            local real a= 2 * Atan2(ty - s__Missile_yPrivate[this], tx - s__Missile_xPrivate[this]) + bj_PI - s__Missile_angle[this]
            call s__MissilePosition_move(s__Missile_impact[this],s__Missile_xPrivate[this] + ( s__MissilePosition_distance[s__Missile_origin[this]] - s__Missile_distance[this] ) * Cos(a) , s__Missile_yPrivate[this] + ( s__MissilePosition_distance[s__Missile_origin[this]] - s__Missile_distance[this] ) * Sin(a) , s__MissilePosition_z[s__Missile_impact[this]])
            call s__Missile_bounce(this)
        endfunction
        
        function s__Missile_deflectEx takes integer this,real tx,real ty,real tz returns nothing
            call s__MissilePosition_move(s__Missile_impact[this],s__MissilePosition_x[s__Missile_impact[this]] , s__MissilePosition_y[s__Missile_impact[this]] , tz)
            call s__Missile_deflect(this,tx , ty)
        endfunction
    
        function s__Missile_flightTime2Speed takes integer this,real duration returns nothing
            set s__Missile_speed[this]=RMaxBJ(0.00000001, ( s__MissilePosition_distance[s__Missile_origin[this]] - s__Missile_distance[this] ) * Missile_TIMER_TIMEOUT / duration)
        endfunction
    
        // I would expect more from a destroy method :)!
        function s__Missile_destroy takes integer this returns nothing
            set s__Missile_wantDestroy[this]=true
        endfunction
    
        // As user you shouldn't have access to .remove(), so you can use .terminate() instead.
        function s__Missile_terminate takes integer this returns nothing
            set s__Missile_allocated[this]=false
            call DestroyEffect(s__Missile_sfx[this])
            



                call DestroyGroup(s__Missile_unitsHit[this])

           
            if ( GetUnitTypeId(s__Missile_dummy[this]) == Missile_DUMMY_UNIT_ID ) then










                    call RemoveUnit(s__Missile_dummy[this])

            endif
           
            set s__Missile_recycle[this]=false
            set s__Missile_sfx[this]=null
            set s__Missile_unitsHit[this]=null
            set s__Missile_source[this]=null
            set s__Missile_target[this]=null
            set s__Missile_dummy[this]=null
           
            call s__MissilePosition_destroy(s__Missile_impact[this])
            call s__MissilePosition_destroy(s__Missile_origin[this])
           
            call s__Missile_remove(this)
        endfunction
    
        // Freaky static if ensures these libraries really don't exist.

            function s__Missile_newMissileUnit takes real x,real y,real face returns unit
                // Just in case you have UnitIndexer.

                    set s__UnitIndexer_enabled=false

                set bj_lastCreatedUnit=CreateUnit(Missile_NEUTRAL_PASSIVE, Missile_DUMMY_UNIT_ID, x, y, face)
                call SetUnitX(bj_lastCreatedUnit, x)
                call SetUnitY(bj_lastCreatedUnit, y)
                call PauseUnit(bj_lastCreatedUnit, true)

                    set s__UnitIndexer_enabled=true

                return bj_lastCreatedUnit
            endfunction

    
        function s__Missile_create takes real originX,real originY,real originZ,real angleP,real distanceP,real impactZ returns integer
            local integer this= s__Missile_allocateNode()
            set s__Missile_origin[this]=s__MissilePosition_create(originX , originY , originZ)
            set s__Missile_impact[this]=s__MissilePosition_create(originX + distanceP * Cos(angleP) , originY + distanceP * Sin(angleP) , impactZ)
            call s__MissilePosition_link(s__Missile_origin[this] , s__Missile_impact[this])
            
            set s__Missile_collision[this]=0

                set s__Missile_collisionZ[this]=0

            
            set s__Missile_acceleration[this]=0
            set s__Missile_height[this]=0
            set s__Missile_turn[this]=0
            set s__Missile_open[this]=0
            
            set s__Missile_recycle[this]=false
            set s__Missile_wantDestroy[this]=false
            set s__Missile_path[this]=""
            
            set s__Missile_xPrivate[this]=originX
            set s__Missile_yPrivate[this]=originY
            set s__Missile_z[this]=s__MissilePosition_z[s__Missile_origin[this]]
            set s__Missile_angle[this]=angleP
            set s__Missile_distance[this]=0
            










                set s__Missile_dummy[this]=s__Missile_newMissileUnit(originX , originY , angleP * bj_RADTODEG)


            set s__Missile_allocated[this]=true
            



                set s__Missile_unitsHit[this]=CreateGroup()

            
            call MoveLocation(s__MissilePosition_loc, originX, originY)
            call SetUnitFlyHeight(s__Missile_dummy[this], s__MissilePosition_z[s__Missile_origin[this]] - GetLocationZ(s__MissilePosition_loc), 0.)
            
            return this
        endfunction
    
        // Currently a private method. In future updates it will be public again and similiar
        // to create(), but you can pass in any existing unit, instead poping a dummy unit from the stack.
         function s__Missile_createEx takes unit missileDummy,real impactX,real impactY,real impactZ returns integer
            local integer this= s__Missile_allocateNode()
            local real originX= GetUnitX(missileDummy)
            local real originY= GetUnitY(missileDummy)
            local real originZ= GetUnitFlyHeight(missileDummy)
            set s__Missile_origin[this]=s__MissilePosition_create(originX , originY , originZ)
            set s__Missile_impact[this]=s__MissilePosition_create(impactX , impactY , impactZ)
            
            call s__MissilePosition_link(s__Missile_origin[this] , s__Missile_impact[this])



            set s__Missile_collision[this]=0

                set s__Missile_collisionZ[this]=0

            
            set s__Missile_acceleration[this]=0
            set s__Missile_height[this]=0
            set s__Missile_turn[this]=0
            set s__Missile_open[this]=0
            
            set s__Missile_recycle[this]=false
            set s__Missile_wantDestroy[this]=false
            set s__Missile_path[this]=""
            
            set s__Missile_xPrivate[this]=originX
            set s__Missile_yPrivate[this]=originY
            set s__Missile_z[this]=originZ
            set s__Missile_angle[this]=s__MissilePosition_angle[s__Missile_origin[this]]
            set s__Missile_distance[this]=0
            set s__Missile_dummy[this]=missileDummy
            set s__Missile_allocated[this]=true
            



                set s__Missile_unitsHit[this]=CreateGroup()

            
            call MoveLocation(s__MissilePosition_loc, originX, originY)
            call SetUnitFlyHeight(missileDummy, s__MissilePosition_z[s__Missile_origin[this]] - GetLocationZ(s__MissilePosition_loc), 0.)
            
            return this
        endfunction
        
        // This one is new. I think it is useful.
        function s__Missile_createXYZ takes real x,real y,real z,real impactX,real impactY,real impactZ returns integer
            local real angleP= Atan2(impactY - y, impactX - x)
            local real distance= SquareRoot(( x - impactX ) * ( x - impactX ) + ( y - impactY ) * ( y - impactY ))
            return s__Missile_create(x , y , z , angleP , distance , impactZ)
        endfunction
    
        // Periodic loop every 1/32 seconds. Runs once per active missile struct.
        function s__Missile_move takes integer this returns nothing
            local integer loc
            local real a
            local real d
            local real s
            local unit u
            
            local real h
            local real tx
            local real ty
            local real index
            
            loop
                exitwhen ( this == 0 )
                set loc=s__Missile_origin[this]
                set u=s__Missile_target[this]
                set h=s__Missile_height[this]
                
                // Missile target.
                if ( u != null ) then
                    if ( 0 != GetUnitTypeId(u) ) then
                        set tx=GetUnitX(u)
                        set ty=GetUnitY(u)
                        set a=Atan2(ty - s__Missile_yPrivate[this], tx - s__Missile_xPrivate[this])
                        // Does not hit the toe, but hits the chest.
                        // Why so? Because of HIT_BOX and GetUnitBodySize(u)
                        call s__MissilePosition_move(s__Missile_impact[this],tx , ty , GetUnitFlyHeight(u) + GetUnitBodySize(u) * s__Missile_HIT_BOX)
                        set s__Missile_distance[this]=s__MissilePosition_distance[loc] - SquareRoot(( tx - s__Missile_xPrivate[this] ) * ( tx - s__Missile_xPrivate[this] ) + ( ty - s__Missile_yPrivate[this] ) * ( ty - s__Missile_yPrivate[this] ))
                    else
                        set s__Missile_target[this]=null
                    endif
                else
                    set a=s__MissilePosition_angle[loc]
                endif
            
                // Missile turn
                if ( 0 != s__Missile_turn[this] ) and ( Cos(s__Missile_angle[this] - a) < Cos(s__Missile_turn[this]) ) then
                    if ( Sin(a - s__Missile_angle[this]) >= 0 ) then
                        set s__Missile_angle[this]=s__Missile_angle[this] + s__Missile_turn[this]
                    else
                        set s__Missile_angle[this]=s__Missile_angle[this] - s__Missile_turn[this]
                    endif
                else
                    set s__Missile_angle[this]=a
                endif
                
                set d=s__MissilePosition_distance[loc]
                set s=s__Missile_distance[this] + s__Missile_speed[this]
                set s__Missile_distance[this]=s
               
                set u=s__Missile_dummy[this]
               
                set tx=s__Missile_xPrivate[this] + s__Missile_speed[this] * Cos(s__Missile_angle[this])
                set ty=s__Missile_yPrivate[this] + s__Missile_speed[this] * Sin(s__Missile_angle[this])
                set s__Missile_speed[this]=s__Missile_speed[this] + s__Missile_acceleration[this]
                set s__Missile_xPrivate[this]=tx
                set s__Missile_yPrivate[this]=ty
            
                // Missile curve
                if ( s__Missile_open[this] != 0 ) then
                    set a=4 * s__Missile_open[this] * s * ( d - s ) / ( d * d )
                    set tx=tx + a * Cos(s__Missile_angle[this] + 1.57)
                    set ty=ty + a * Sin(s__Missile_angle[this] + 1.57)
                    call SetUnitFacing(u, ( s__Missile_angle[this] + Atan(- ( ( 4 * s__Missile_open[this] ) * ( 2 * s - d ) ) / ( d * d )) ) * bj_RADTODEG)
                else
                    call SetUnitFacing(u, s__Missile_angle[this] * bj_RADTODEG)
                endif
                
                // Missile x/y
                set s__Missile_x[this]=tx
                set s__Missile_y[this]=ty
                

                    if ( tx > s__WorldBounds_maxX ) or ( tx < s__WorldBounds_minX ) or ( ty > s__WorldBounds_maxY ) or ( ty < s__WorldBounds_minY ) then
                        set s__Missile_wantDestroy[this]=true
                    else
                        call SetUnitX(u, tx)
                        call SetUnitY(u, ty)
                    endif





                // Missile z
                call MoveLocation(s__MissilePosition_loc, tx, ty)
                set s__Missile_terrainZ[this]=GetLocationZ(s__MissilePosition_loc)
                if ( h != 0 ) or ( s__MissilePosition_slope[loc] != 0 ) then
                    set s__Missile_z[this]=s__MissilePosition_z[loc] - s__Missile_terrainZ[this] + s__MissilePosition_slope[loc] * s
                    set index=s__MissilePosition_alpha[loc]
                    if ( h != 0 ) then
                        set s__Missile_z[this]=s__Missile_z[this] + ( 4 * h * s * ( d - s ) / ( d * d ) )
                        set index=index - Atan(( ( 4 * h ) * ( 2 * s - d ) ) / ( d * d )) * bj_RADTODEG
                    endif
                    call SetUnitAnimationByIndex(u, R2I(index + 90.5))
                else
                    set s__Missile_z[this]=s__MissilePosition_z[loc] - s__Missile_terrainZ[this]
                endif
                call SetUnitFlyHeight(u, s__Missile_z[this], 0)
               
                if ( s >= d ) then
                    set s__Missile_recycle[this]=true
                endif
               
                set this=(s__Missile_Missile___MissileStructure___next[(this)]) // INLINED!!
            endloop
            set u=null
        endfunction
        
// Optional code stays optional.


        // After several test it turned out, that the square used in EnumDestructablesInRect leaves out
        // destructables which are within an appropriate range of the projectile.
        // Sadly there is no IsDestructableInRange native!!!
        function s__Missile_actionFuncDest takes nothing returns nothing
            local destructable d= GetEnumDestructable()
            local real xd= GetDestructableX(d)
            local real yd= GetDestructableY(d)
            local real dist= ( s__Missile_x[s__Missile_temp] - xd ) * ( s__Missile_x[s__Missile_temp] - xd ) + ( s__Missile_y[s__Missile_temp] - yd ) * ( s__Missile_y[s__Missile_temp] - yd )

                local real collideZ= Missile_GetLocZ(xd , yd) - s__Missile_terrainZ[s__Missile_temp]
                if ( dist <= bj_enumDestructableRadius ) and ( collideZ + (GetDestructableOccluderHeight((d))) >= s__Missile_z[s__Missile_temp] - s__Missile_collisionZ[s__Missile_temp] ) and ( collideZ <= s__Missile_z[s__Missile_temp] + s__Missile_collisionZ[s__Missile_temp] ) then // INLINED!!
                    if ( dist < s__Missile_tempDist ) then
                        set s__Missile_tempDist=dist
                        set bj_destRandomCurrentPick=d
                    endif
                endif








            set d=null
        endfunction



    function s__Missile_nullBefore takes integer this returns nothing
        set s__Missile_dummy[this]=null
    endfunction


// Does not check for 'Aloc' and 'Amrf' as they could be customized.









    // You made it to the end of Missile, but we are not finished.
    // Do you remember about the data structure, the delayed recycler
    // and of course our interface module "MissileStruct"
    //
    // This comes now!
    
    
    // Debug code taken from List (credits to Nestharus)
    
    // Can private as the MissileStruct module is written here.
    
    function Missile___Fire takes nothing returns nothing
        call TriggerEvaluate(Missile___core)
    endfunction
    
    function Missile___MissileCreateExpression takes integer structId,code func returns nothing
        set Missile___expression[structId]=Condition(func)
    endfunction
    
    // Start timer if not already running.
    function Missile___StartPeriodic takes integer structId returns nothing
        if ( Missile___instances[structId] == 0 ) then
            set Missile___condition[structId]=TriggerAddCondition(Missile___core, Missile___expression[structId])
            if ( Missile___active == 0 ) then
                call TimerStart(Missile___clock, Missile_TIMER_TIMEOUT, true, function Missile___Fire)
            endif
            set Missile___active=Missile___active + 1
        endif
        set Missile___instances[structId]=Missile___instances[structId] + 1
    endfunction
    
    // And stops it.
    function Missile___StopPeriodic takes integer structId returns nothing
        set Missile___instances[structId]=Missile___instances[structId] - 1
        if ( Missile___instances[structId] == 0 ) then
            set Missile___active=Missile___active - 1
            if ( Missile___active == 0 ) then
                call PauseTimer(Missile___clock)
            endif
            call TriggerRemoveCondition(Missile___core, Missile___condition[structId])
            set Missile___condition[structId]=null
        endif
    endfunction
    
    // Now the popular MissileStruct.
    // How is it working? Let's see!
    //
    // P in the end of all methods hopefully prevents
    // any conflicting code.
    
    
    
// The end!

//library Missile ends
//library UnitZ:

    function GetUnitZ takes unit u returns real
        return GetTerrainZ(GetUnitX(u) , GetUnitY(u)) + GetUnitFlyHeight(u)
    endfunction
       
    function SetUnitZ takes unit u,real z returns nothing
        call SetUnitFlyHeight(u, z - GetTerrainZ(GetUnitX(u) , GetUnitY(u)), 0)
    endfunction
       

//library UnitZ ends
//library Coconut:
    
    
    
    function Coconut___IsInBound takes real x,real y returns boolean
        return x < s__WorldBounds_maxX and x > s__WorldBounds_minX and y < s__WorldBounds_maxY and y > s__WorldBounds_minY
    endfunction
    
        
        
        
        
        
        
        function s__Coconut_remove takes integer this returns nothing
            
            call ReleaseTimer(s__Coconut_tick[this])
            call KillUnit(s__Coconut_missile[this])
            call DestroyEffect(s__Coconut_sfx[this])
            
            call s__Coconut_deallocate(this)
            set s__Coconut_missile[this]=null
            set s__Coconut_sfx[this]=null
            
            
            
        endfunction
        
        function s__Coconut_setLocation takes integer this,real x,real y,boolean checkPathing returns nothing
            
            if checkPathing then
                call SetUnitPosition(s__Coconut_missile[this], x, y)
                set s__Coconut_x[this]=GetUnitX(s__Coconut_missile[this])
                set s__Coconut_y[this]=GetUnitY(s__Coconut_missile[this])
            else
                call SetUnitX(s__Coconut_missile[this], x)
                call SetUnitY(s__Coconut_missile[this], y)
                set s__Coconut_x[this]=x
                set s__Coconut_y[this]=y
            endif
            
        endfunction
        
        function s__Coconut_getSlope takes real x1,real y1,real x2,real y2 returns real
            return 1.571 * ( ( GetTerrainZ(x1 , y1) - GetTerrainZ(x2 , y2) ) / SLOPE_ACCURACY )
        endfunction
    
        function s__Coconut_circularDifference takes real a,real b returns real
        
            local real diff= RAbsBJ(a - b)
            
            if diff * 2 <= TAU then
                return diff
            else
                return TAU - diff
            endif
            
        endfunction
        
        function s__Coconut_normalize takes real a returns real
            loop
                if a < 0 then
                    set a=a + TAU
                elseif a > TAU then
                    set a=a - TAU
                else
                    exitwhen true
                endif
            endloop
            
            return a
        endfunction
        
        function s__Coconut_onPeriodic takes nothing returns nothing
            
            local real slope
            local real slope2
            local unit u
            
            local real px
            local real py
            
            local real d1
            local real d2
            local real d3
            
            local real sx
            local real sy
            local timer t= GetExpiredTimer()
            local integer this= (LoadInteger(TimerUtils___ht, 0, GetHandleId((t)))) // INLINED!!
            local integer tempInt
            local boolean isRemove= false
            
            local boolean detect
            local unit fog
            local real a1
            local real a2
            
            local real xt= s__Coconut_x[this]
            local real yt= s__Coconut_y[this]
            local real x= 0
            local real y= 0
            local real z
            local integer data
            local integer pathing
            
            set s__Coconut_duration[this]=s__Coconut_duration[this] - 0.03125
            if s__Coconut_duration[this] > 0 then
                if not s__Coconut_isFlying[this] then
                
                    call sc__Coconut_getLowestGr(this)
                    
                    set slope=s__Coconut_getSlope(xt , yt , s__Coconut___Ground_x , s__Coconut___Ground_y)
                    
                    if slope != 0 then
                        call sc__Coconut_slip(this,FULL_GRAVITY * slope , 20 , Atan2(s__Coconut___Ground_y - yt, s__Coconut___Ground_x - xt) , 2 * bj_DEGTORAD)
                    endif
                    
                    set pathing=GetTerrainPathingColor(xt , yt)
                    if pathing == PATHING_COLOR_BLUE then
                        set s__Coconut_splash[this]=not s__Coconut_splash[this]
                        if s__Coconut_splash[this] then
                            set s__Coconut_speed[this]=s__Coconut_speed[this] * 0.95
                            if s__Coconut_speed[this] > 5 then
                                set u=CreateUnit(PASSIVE, 'h006', s__Coconut_x[this], s__Coconut_y[this], s__Coconut_angle[this] * bj_RADTODEG)
                                call SetUnitScale(u, ( 0.5 * s__Coconut_speed[this] + 25 ) / 55, 1, 1)
                                call UnitApplyTimedLife(u, 'BTLF', 3.0)
                                call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\Splash.mdx", u, "origin"))
                                set u=null
                            endif
                        endif
                    endif
                    
                endif
                    
                if s__Coconut_speed[this] < 0 then
                    set s__Coconut_speed[this]=0
                endif
                    
                if Coconut___IsInBound(xt , yt) then
                    
                    set px=xt
                    set py=yt
                    
                    set sx=xt + SLOPE_ACCURACY * Cos(s__Coconut_angle[this])
                    set sy=yt + SLOPE_ACCURACY * Sin(s__Coconut_angle[this])
                    
                    set slope=s__Coconut_getSlope(sx , sy , xt , yt)
                    
                    set xt=xt + s__Coconut_speed[this] * Cos(s__Coconut_angle[this])
                    set yt=yt + s__Coconut_speed[this] * Sin(s__Coconut_angle[this])
                    
                    if Coconut___IsInBound(xt , yt) then
                        call SetUnitX(s__Coconut_missile[this], xt)
                        call SetUnitY(s__Coconut_missile[this], yt)
                    else
                        set isRemove=true
                    endif
                    call SetUnitFacing(s__Coconut_missile[this], s__Coconut_angle[this] * bj_RADTODEG)
                    
                    if s__Coconut_isFlying[this] then
                    
                        set s__Coconut_z[this]=s__Coconut_z[this] + s__Coconut_zVel[this]
                        set s__Coconut_zVel[this]=s__Coconut_zVel[this] - ( FULL_GRAVITY + SLIDER_MASS )
                        set z=GetTerrainZ(xt , yt)
                        
                        if s__Coconut_z[this] <= z + 24 then
                        
                            set s__Coconut_z[this]=z + 24
                            set d1=Atan(RAbsBJ(s__Coconut_zVel[this]) / s__Coconut_speed[this])
                            set d2=Atan(( z - GetTerrainZ(px , py) ) / s__Coconut_speed[this])
                            set d3=bj_PI - d1 - d2
                            
                            set s__Coconut_speed[this]=s__Coconut_speed[this] * 1 //((d3/HP-1)*0)
                            
                            if RAbsBJ(s__Coconut_zVel[this]) < 17.5 then
                                set s__Coconut_isFlying[this]=false
                            else
                                set s__Coconut_zVel[this]=- s__Coconut_zVel[this] * 0.35
                            endif
                        endif
                        call SetUnitZ(s__Coconut_missile[this] , s__Coconut_z[this])
                    else
                        call SetUnitTimeScale(s__Coconut_missile[this], s__Coconut_speed[this] / 40)
                        set sx=xt - SLOPE_ACCURACY * Cos(s__Coconut_angle[this])
                        set sy=yt - SLOPE_ACCURACY * Sin(s__Coconut_angle[this])
                        set slope2=s__Coconut_getSlope(xt , yt , sx , sy)
                        
                        if slope > slope2 and slope - slope2 > bj_DEGTORAD * 5 then
                        
                            set s__Coconut_zVel[this]=s__Coconut_speed[this] * Sin(slope)
                            
                            if s__Coconut_zVel[this] > ( FULL_GRAVITY + SLIDER_MASS + ( GetTerrainZ(xt , yt) - GetTerrainZ(sx , sy) ) ) then
                                set s__Coconut_isFlying[this]=true
                                set s__Coconut_z[this]=GetUnitZ(s__Coconut_missile[this]) + 24
                            endif
                        else
                            set s__Coconut_z[this]=GetTerrainZ(xt , yt) + 24
                            call SetUnitZ(s__Coconut_missile[this] , s__Coconut_z[this])
                        endif
                    endif
                endif
                
                
                set pathing=GetTerrainPathingColor(xt , yt)
                
                if not s__Coconut_isFlying[this] and ( pathing == PATHING_COLOR_YELLOW or pathing == PATHING_COLOR_CYAN ) then
                    call s__Coconut_remove(this)
                else
                    if pathing != PATHING_COLOR_MAGENTA and ( pathing != PATHING_COLOR_GREEN or s__Coconut_isFlying[this] ) then
                        set s__Coconut_x[this]=xt
                        set s__Coconut_y[this]=yt
                    elseif s__Coconut_speed[this] > 25 then
                        set isRemove=true
                    else
                        set s__Coconut_angle[this]=- 2 * Atan2(yt - s__Coconut_y[this], xt - s__Coconut_x[this]) + bj_PI - s__Coconut_angle[this]
                        set s__Coconut_speed[this]=s__Coconut_speed[this] * 0.4
                    endif
                endif
                
            else
                set isRemove=true
            endif
            
            if isRemove then
                call s__Coconut_remove(this)
            endif
            set t=null
        
        endfunction
        
        function s__Coconut_getLowestGr takes integer this returns nothing
            
            local real x
            local real y
            local real z
            
            local real x2
            local real y2
            local real z2
            
            local real angle= 0
            local real o= GetTerrainZ(s__Coconut_x[this] , s__Coconut_y[this])
            local real lowest= 99999999
            local real acc= 10 * bj_DEGTORAD
            
            set x=s__Coconut_x[this] + SLOPE_ACCURACY * Cos(acc)
            set y=s__Coconut_y[this] + SLOPE_ACCURACY * Sin(acc)
            set z=GetTerrainZ(x , y)
            
            set x2=s__Coconut_x[this] + SLOPE_ACCURACY * Cos(- acc)
            set y2=s__Coconut_y[this] + SLOPE_ACCURACY * Sin(- acc)
            set z2=GetTerrainZ(x2 , y2)
            
            if z2 < z then
                set acc=- acc
            endif
            
            loop
                exitwhen RAbsBJ(angle) >= TAU
                
                set x=s__Coconut_x[this] + SLOPE_ACCURACY * Cos(angle)
                set y=s__Coconut_y[this] + SLOPE_ACCURACY * Sin(angle)
                
                if Coconut___IsInBound(x , y) then
                
                    set z=GetTerrainZ(x , y)
                    
                    exitwhen lowest < z
                    
                    if z < lowest then
                    
                        set lowest=z
                        set s__Coconut___Ground_x=x
                        set s__Coconut___Ground_y=y
                        
                    endif
                    
                endif
                
                set angle=angle + acc
            endloop
            
            if o < lowest then
                set s__Coconut___Ground_x=s__Coconut_x[this]
                set s__Coconut___Ground_y=s__Coconut_y[this]
            endif
            
        endfunction
        
        function s__Coconut_turn takes integer this,real targetAngle,real turnRate returns nothing
            
            if Cos(s__Coconut_angle[this] - targetAngle) < Cos(turnRate) then
                if Sin(targetAngle - s__Coconut_angle[this]) >= 0 then
                    set s__Coconut_angle[this]=s__Coconut_normalize(s__Coconut_angle[this] + turnRate)
                else
                    set s__Coconut_angle[this]=s__Coconut_normalize(s__Coconut_angle[this] - turnRate)
                endif
            else
                set s__Coconut_angle[this]=s__Coconut_normalize(targetAngle)
            endif
            
        endfunction
        
        function s__Coconut_slip takes integer this,real speed,real maxspeed,real angle,real rate returns nothing
            
            local real diff
            local real turnPow
            local real spdPow
            
            set angle=s__Coconut_normalize(angle)
            set diff=s__Coconut_circularDifference(angle , s__Coconut_angle[this])
            
            set turnPow=RAbsBJ(s__Coconut_circularDifference(diff , HP))
            set turnPow=1 - turnPow / HP
            call s__Coconut_turn(this,angle , rate * turnPow)
        
            set spdPow=1 - diff * ( 2 / bj_PI )
            if spdPow < 0 or s__Coconut_speed[this] < maxspeed then
            
                set s__Coconut_speed[this]=s__Coconut_speed[this] + speed * spdPow
                
                if spdPow >= 0 and s__Coconut_speed[this] > maxspeed then
                    set s__Coconut_speed[this]=maxspeed
                endif
                
                if s__Coconut_speed[this] < 0 then
                    set s__Coconut_angle[this]=angle
                    set s__Coconut_speed[this]=s__Coconut_speed[this] + speed
                endif
                
            endif
            
        endfunction
        
        function s__Coconut_accelerate takes integer this,real speed,real maxspeed,real angle,real rate returns nothing
            
            local real diff
            local real turnPow
            local real spdPow
            
            set angle=s__Coconut_normalize(angle)
            if s__Coconut_speed[this] <= 0 then
                set s__Coconut_angle[this]=angle
                if s__Coconut_speed[this] < maxspeed then
                    set s__Coconut_speed[this]=speed
                endif
            else
                set diff=s__Coconut_circularDifference(angle , s__Coconut_angle[this])
                set turnPow=RAbsBJ(s__Coconut_circularDifference(diff , HP))
                set turnPow=1 - turnPow / HP
                call s__Coconut_turn(this,angle , rate * turnPow)
                
                set spdPow=1 - diff * ( 2 / bj_PI )
                if spdPow < 0 or s__Coconut_speed[this] < maxspeed then
                    set s__Coconut_speed[this]=s__Coconut_speed[this] + speed * spdPow
                    if s__Coconut_speed[this] > maxspeed and spdPow >= 0 then
                        set s__Coconut_speed[this]=maxspeed
                    endif
                    if s__Coconut_speed[this] < 0 then
                        set s__Coconut_angle[this]=angle
                        set s__Coconut_speed[this]=- s__Coconut_speed[this]
                    endif
                endif
            endif
            
        endfunction
        
        function s__Coconut_create takes real x,real y returns integer
            
            local integer this= s__Coconut__allocate()
            local integer dif1
            local integer dif2
            local integer i
            local boolean b
            
            set CocoCount=CocoCount + 1
            set Cocos[CocoCount]=this
            set s__Coconut_source[this]=4
            set s__Coconut_index[this]=CocoCount
            
            set i=GetRandomInt(0, 3)
            
            set s__Coconut_angle[this]=SpawnA[i] + GetRandomReal(- 45, 45)
            set s__Coconut_x[this]=SpawnX[i]
            set s__Coconut_y[this]=SpawnY[i]
            set s__Coconut_z[this]=GetTerrainZ(s__Coconut_x[this] , s__Coconut_y[this]) + 64
            call SetUnitZ(s__Coconut_missile[this] , s__Coconut_z[this])
            set s__Coconut_missile[this]=CreateUnit(PASSIVE, 'h000', s__Coconut_x[this], s__Coconut_y[this], s__Coconut_angle[this])
            set s__Coconut_sfx[this]=AddSpecialEffectTarget("war3mapImported\\Coco4.mdx", s__Coconut_missile[this], "origin")
            
            set s__Coconut_duration[this]=15
            set s__Coconut_zVel[this]=GetRandomReal(45, 75)
            set s__Coconut_isFlying[this]=true
            set s__Coconut_speed[this]=GetRandomReal(10, 20)
            set s__Coconut_angle[this]=s__Coconut_angle[this] * bj_DEGTORAD
            
            set s__Coconut_tick[this]=NewTimerEx(this)
            call TimerStart(s__Coconut_tick[this], 0.03125, true, function s__Coconut_onPeriodic)
            
            return this
        endfunction
        
        function s__Coconut_onInit takes nothing returns nothing
            set SpawnX[0]=- 544
            set SpawnY[0]=- 544
            set SpawnA[0]=45
            set SpawnX[1]=544
            set SpawnY[1]=- 544
            set SpawnA[1]=135
            set SpawnX[2]=544
            set SpawnY[2]=544
            set SpawnA[2]=225
            set SpawnX[3]=- 544
            set SpawnY[3]=544
            set SpawnA[3]=315
        endfunction
        
    

//library Coconut ends
//===========================================================================
// 
// |CFFD9BD89Coconut Party|R
// 
//   Warcraft III map script
//   Generated by the Warcraft III World Editor
//   Date: Sat Oct 03 04:25:49 2015
//   Map Author: Quilnez
// 
//===========================================================================

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


function InitGlobals takes nothing returns nothing
endfunction

//***************************************************************************
//*
//*  Regions
//*
//***************************************************************************

function CreateRegions takes nothing returns nothing
    local weathereffect we

    set gg_rct_Rect_000=Rect(- 32.0, - 1056.0, 32.0, - 992.0)
    set gg_rct_Rect_000_Copy=Rect(- 1056.0, - 32.0, - 992.0, 32.0)
    set gg_rct_Rect_000_Copy_2=Rect(- 32.0, 992.0, 32.0, 1056.0)
    set gg_rct_Rect_000_Copy_3=Rect(992.0, - 32.0, 1056.0, 32.0)
    set gg_rct_Rect_004=Rect(- 608.0, - 608.0, - 480.0, - 480.0)
    set gg_rct_Rect_004_Copy=Rect(- 608.0, 480.0, - 480.0, 608.0)
    set gg_rct_Rect_004_Copy_2=Rect(480.0, 480.0, 608.0, 608.0)
    set gg_rct_Rect_004_Copy_3=Rect(480.0, - 608.0, 608.0, - 480.0)
    set gg_rct_Rect_008=Rect(- 320.0, - 896.0, - 288.0, - 672.0)
endfunction

//***************************************************************************
//*
//*  Cameras
//*
//***************************************************************************

function CreateCameras takes nothing returns nothing

    set gg_cam_Camera_001=CreateCameraSetup()
    call CameraSetupSetField(gg_cam_Camera_001, CAMERA_FIELD_ZOFFSET, 0.0, 0.0)
    call CameraSetupSetField(gg_cam_Camera_001, CAMERA_FIELD_ROTATION, 88.7, 0.0)
    call CameraSetupSetField(gg_cam_Camera_001, CAMERA_FIELD_ANGLE_OF_ATTACK, 317.5, 0.0)
    call CameraSetupSetField(gg_cam_Camera_001, CAMERA_FIELD_TARGET_DISTANCE, 2415.8, 0.0)
    call CameraSetupSetField(gg_cam_Camera_001, CAMERA_FIELD_ROLL, 0.0, 0.0)
    call CameraSetupSetField(gg_cam_Camera_001, CAMERA_FIELD_FIELD_OF_VIEW, 70.0, 0.0)
    call CameraSetupSetField(gg_cam_Camera_001, CAMERA_FIELD_FARZ, 8857.8, 0.0)
    call CameraSetupSetDestPosition(gg_cam_Camera_001, 0.0, 0.0, 0.0)

endfunction

//***************************************************************************
//*
//*  Custom Script Code
//*
//***************************************************************************
//TESH.scrollpos=0
//TESH.alwaysfold=0

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

//===========================================================================
// Trigger: AI
//===========================================================================
//TESH.scrollpos=65
//TESH.alwaysfold=0
// scope AI begins
    
    
        
//Implemented from module MissileStruct:
        
// Why not run some debug checks first.


























        




        
        // Stupid name ensures not to be called accidently.
        function s__AI_MissileStruct__missileTerminateP takes integer node returns nothing










            
            call s__Missile_terminate(node)
            call Missile___StopPeriodic(si__AI)
        endfunction
    
        // Returns boolean to be compile-able with Cohadars JassHelper.
        function s__AI_MissileStruct__missileIterateP takes nothing returns boolean
            local integer this= (s__Missile_Missile___MissileStructure___first[(Missile___missileStack[si__AI])]) // INLINED!!
            local integer node
            local real collideZ
            local unit u
            
            // Move the whole stack.
            call s__Missile_move(this)
            loop
                exitwhen this == 0
                set node=(s__Missile_Missile___MissileStructure___next[(this)]) // INLINED!!
               
                if ( s__Missile_wantDestroy[this] ) then





                        call s__AI_MissileStruct__missileTerminateP(this)

                else
                






































                        



















                
                    if ( s__Missile_recycle[this] ) and ( s__Missile_allocated[this] ) then































                                call s__AI_MissileStruct__missileTerminateP(this)


                    endif
                











                
                    // Runs last











                endif
                set this=node
            endloop
           
            set u=null
            return false
        endfunction
    
        function s__AI_launch takes integer missile returns nothing


        
            call s__Missile_insertEnd(Missile___missileStack[si__AI],missile)
            call Missile___StartPeriodic(si__AI)
        endfunction
    
        function s__AI_MissileStruct__onInit takes nothing returns nothing
            set Missile___missileStack[si__AI]=s__Missile_allocateCollection()
            set Missile___expression[(si__AI )]=Condition(( function s__AI_MissileStruct__missileIterateP)) // INLINED!!



        endfunction
    
        
        function s__AI_normal takes nothing returns nothing
            
            local timer t= GetExpiredTimer()
            local integer pn= (LoadInteger(TimerUtils___ht, 0, GetHandleId((t)))) // INLINED!!
            local integer i= 1
            local integer urgen
            local integer dex
            local real r
            local real d
            local real x
            local real y
            local real z
            local real x2
            local real y2
            local real a
            local integer m
            
            loop
                exitwhen i > CocoCount
                if i == AITarget[pn] then
                    set TargetUrgency[i]=1
                else
                    set TargetUrgency[i]=0
                endif
                if pn == 0 then
                    if s__Coconut_y[Cocos[i]] < 128 and s__Coconut_y[Cocos[i]] > CurrentY[pn] and s__Coconut_x[Cocos[i]] > - 448 and s__Coconut_x[Cocos[i]] < 448 then
                        set TargetUrgency[i]=TargetUrgency[i] + R2I(( 1 - RAbsBJ(CurrentX[pn] - s__Coconut_x[Cocos[i]]) / 672 ) * 5)
                        set r=circularDifference(normalize(s__Coconut_angle[Cocos[i]]) , bj_PI + HP)
                        if r < HP then
                            set TargetUrgency[i]=TargetUrgency[i] + R2I(HP - r)
                        elseif s__Coconut_speed[Cocos[i]] < 15 then
                            set TargetUrgency[i]=0
                        endif
                    else
                        set TargetUrgency[i]=0
                    endif
                elseif pn == 1 then
                    if s__Coconut_x[Cocos[i]] < 128 and s__Coconut_x[Cocos[i]] > CurrentX[pn] and s__Coconut_y[Cocos[i]] > - 448 and s__Coconut_y[Cocos[i]] < 448 then
                        set TargetUrgency[i]=TargetUrgency[i] + R2I(( 1 - RAbsBJ(CurrentX[pn] - s__Coconut_x[Cocos[i]]) / 672 ) * 5)
                        set r=circularDifference(normalize(s__Coconut_angle[Cocos[i]]) , bj_PI)
                        if r < HP then
                            set TargetUrgency[i]=TargetUrgency[i] + R2I(HP - r)
                        elseif s__Coconut_speed[Cocos[i]] < 15 then
                            set TargetUrgency[i]=0
                        endif
                    else
                        set TargetUrgency[i]=0
                    endif
                elseif pn == 2 then
                    if s__Coconut_y[Cocos[i]] > 128 and s__Coconut_y[Cocos[i]] < CurrentY[pn] and s__Coconut_x[Cocos[i]] > - 448 and s__Coconut_x[Cocos[i]] < 448 then
                        set TargetUrgency[i]=TargetUrgency[i] + R2I(( 1 - RAbsBJ(CurrentX[pn] - s__Coconut_x[Cocos[i]]) / 672 ) * 5)
                        set r=circularDifference(normalize(s__Coconut_angle[Cocos[i]]) , HP)
                        if r < HP then
                            set TargetUrgency[i]=TargetUrgency[i] + R2I(HP - r)
                        elseif s__Coconut_speed[Cocos[i]] < 15 then
                            set TargetUrgency[i]=0
                        endif
                    else
                        set TargetUrgency[i]=0
                    endif
                elseif pn == 3 then
                    if s__Coconut_x[Cocos[i]] > 128 and s__Coconut_x[Cocos[i]] < CurrentX[pn] and s__Coconut_y[Cocos[i]] > - 448 and s__Coconut_y[Cocos[i]] < 448 then
                        set TargetUrgency[i]=TargetUrgency[i] + R2I(( 1 - RAbsBJ(CurrentX[pn] - s__Coconut_x[Cocos[i]]) / 672 ) * 5)
                        set r=circularDifference(normalize(s__Coconut_angle[Cocos[i]]) , 0)
                        if r < HP then
                            set TargetUrgency[i]=TargetUrgency[i] + R2I(HP - r)
                        elseif s__Coconut_speed[Cocos[i]] < 15 then
                            set TargetUrgency[i]=0
                        endif
                    else
                        set TargetUrgency[i]=0
                    endif
                endif
                set i=i + 1
            endloop
            
            set i=1
            set urgen=0
            set dex=0
            loop
                exitwhen i > CocoCount
                if TargetUrgency[i] > urgen then
                    set urgen=TargetUrgency[i]
                    set dex=i
                endif
                set i=i + 1
            endloop
            
            if dex == 0 then
                set AITarget[pn]=0
                set TargetX[pn]=StartX[pn]
                set TargetY[pn]=StartY[pn]
            else
                set AITarget[pn]=dex
                if pn == 0 then
                    set TargetX[pn]=s__Coconut_x[Cocos[dex]]
                    if TargetX[pn] < - 288 then
                        set TargetX[pn]=- 288
                    elseif TargetX[pn] > 288 then
                        set TargetX[pn]=288
                    endif
                elseif pn == 1 then
                    set TargetY[pn]=s__Coconut_y[Cocos[dex]]
                    if TargetY[pn] < - 288 then
                        set TargetY[pn]=- 288
                    elseif TargetY[pn] > 288 then
                        set TargetY[pn]=288
                    endif
                elseif pn == 2 then
                    set TargetX[pn]=s__Coconut_x[Cocos[dex]]
                    if TargetX[pn] < - 288 then
                        set TargetX[pn]=- 288
                    elseif TargetX[pn] > 288 then
                        set TargetX[pn]=288
                    endif
                elseif pn == 3 then
                    set TargetY[pn]=s__Coconut_y[Cocos[dex]]
                    if TargetY[pn] < - 288 then
                        set TargetY[pn]=- 288
                    elseif TargetY[pn] > 288 then
                        set TargetY[pn]=288
                    endif
                endif
                
                set x=s__Coconut_x[Cocos[dex]]
                set y=s__Coconut_y[Cocos[dex]]
                set x2=CurrentX[pn]
                set y2=CurrentY[pn]
                set d=SquareRoot(( x2 - x ) * ( x2 - x ) + ( y2 - y ) * ( y2 - y ))
                if d < 192 then
                    set x2=CurrentX[pn] + 64 * Cos(HP - HP * pn + bj_PI)
                    set y2=CurrentY[pn] + 64 * Sin(HP - HP * pn + bj_PI)
                    set z=GetTerrainZ(CurrentX[pn] , CurrentY[pn]) + 15
                    set m=s__Missile_create(CurrentX[pn] , CurrentY[pn] , z , HP - HP * pn , 64 , z)
                    call s__Missile__set_model(m,"war3mapImported\\Pump" + I2S(pn) + ".mdx")
                    set s__Missile_speed[m]=30
                    call s__AI_launch(m)
                    set i=1
                    loop
                        exitwhen i > CocoCount
                        set x=s__Coconut_x[Cocos[i]]
                        set y=s__Coconut_y[Cocos[i]]
                        set d=SquareRoot(( x2 - x ) * ( x2 - x ) + ( y2 - y ) * ( y2 - y ))
                        if d < 256 and d > 64 then
                            set a=Atan2(y - y2, x - x2)
                            if circularDifference(normalize(HP - HP * pn) , normalize(a)) < HP / 2 then
                                set d=SquareRoot(( CurrentX[pn] - x ) * ( CurrentX[pn] - x ) + ( CurrentY[pn] - y ) * ( CurrentY[pn] - y ))
                                if circularDifference(normalize(s__Coconut_angle[Cocos[i]]) , normalize(HP - HP * pn)) > HP then
                                    set s__Coconut_speed[Cocos[i]]=30 * ( 1 - ( d - 64 ) / 224 )
                                else
                                    set s__Coconut_speed[Cocos[i]]=s__Coconut_speed[Cocos[i]] + 30 * ( 1 - d / 224 )
                                endif
                                if s__Coconut_speed[Cocos[i]] > 30 then
                                    set s__Coconut_speed[Cocos[i]]=30
                                endif
                                set s__Coconut_angle[Cocos[i]]=a
                                set s__Coconut_duration[Cocos[i]]=15
                                if s__Coconut_source[Cocos[i]] != pn then
                                    set s__Coconut_source[Cocos[i]]=pn
                                    call DestroyEffect(s__Coconut_sfx[Cocos[i]])
                                    set s__Coconut_sfx[Cocos[i]]=AddSpecialEffectTarget("war3mapImported\\Coco" + I2S(pn) + ".mdx", s__Coconut_missile[Cocos[i]], "origin")
                                endif
                            endif
                        endif
                        set i=i + 1
                    endloop
                endif
            endif
            
        endfunction
        
        function s__AI_initAI takes nothing returns nothing
            
            local integer i= 0
            
            loop
                exitwhen i > 3
                if IsAI[i] then
                    set AITimer[i]=NewTimerEx(i)
                    call TimerStart(AITimer[i], 0.25, true, function s__AI_normal)
                endif
                set i=i + 1
            endloop
            call DestroyTimer(GetExpiredTimer())
            
        endfunction
        
        function s__AI_onInit takes nothing returns nothing
            call TimerStart(CreateTimer(), 0.0, false, function s__AI_initAI)
        endfunction
        
    
// scope AI ends
// Trigger: Unit
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// scope Unit begins
    
    
// scope Unit ends
// Trigger: Coconut
//===========================================================================
//TESH.scrollpos=132
//TESH.alwaysfold=0
// Trigger: Control
//===========================================================================
//TESH.scrollpos=279
//TESH.alwaysfold=0
// scope Control begins
    
    
    
        
        function s__Controller_periodic takes nothing returns nothing
        
            local integer i= 0
            local real speed= 24
            
            loop
                exitwhen i > 3
                call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 290, 0)
                call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 3500, 0)
                if GetLocalPlayer() == Player(i) then
                    call SetCameraField(CAMERA_FIELD_ROTATION, 90 - 90 * i, 0)
                endif
                if CurrentX[i] > TargetX[i] then
                    set CurrentX[i]=CurrentX[i] - speed
                    call SetUnitFacing(Unit[i], 180)
                    if CurrentX[i] < TargetX[i] then
                        set CurrentX[i]=TargetX[i]
                    endif
                elseif CurrentX[i] < TargetX[i] then
                    set CurrentX[i]=CurrentX[i] + speed
                    call SetUnitFacing(Unit[i], 0)
                    if CurrentX[i] > TargetX[i] then
                        set CurrentX[i]=TargetX[i]
                    endif
                endif
                if CurrentY[i] > TargetY[i] then
                    set CurrentY[i]=CurrentY[i] - speed
                    call SetUnitFacing(Unit[i], 270)
                    if CurrentY[i] < TargetY[i] then
                        set CurrentY[i]=TargetY[i]
                    endif
                elseif CurrentY[i] < TargetY[i] then
                    set CurrentY[i]=CurrentY[i] + speed
                    call SetUnitFacing(Unit[i], 90)
                    if CurrentY[i] > TargetY[i] then
                        set CurrentY[i]=TargetY[i]
                    endif
                endif
                call SetUnitX(Unit[i], CurrentX[i])
                call SetUnitY(Unit[i], CurrentY[i])
                if CurrentX[i] == TargetX[i] then
                    if CurrentY[i] == TargetY[i] then
                        call SetUnitAnimation(Unit[i], "stand")
                        call SetUnitFacing(Unit[i], 90 - 90 * i)
                    endif
                endif
                set i=i + 1
            endloop
            
        endfunction
        
        function s__Controller_onHover0 takes nothing returns boolean
            
            local integer i= 1
            local player p= (s__Track_tracker) // INLINED!!
            local integer t= (s__Track_instance) // INLINED!!
            local integer pn= GetPlayerId(p)
            
            if pn == 0 then
                loop
                    exitwhen i > 40
                    if t == s___BarData_t[s__BarData_t[Bars[0]]+i] then
                        if i < 12 then
                            set i=12
                        elseif i > 29 then
                            set i=29
                        endif
                        set TargetX[0]=s___BarData_x[s__BarData_x[Bars[0]]+i]
                        call SetUnitAnimationByIndex(Unit[0], 10)
                    endif
                    set i=i + 1
                endloop
            endif
            
            return false
        endfunction
        
        function s__Controller_onHover1 takes nothing returns boolean
            
            local integer i= 1
            local player p= (s__Track_tracker) // INLINED!!
            local integer t= (s__Track_instance) // INLINED!!
            local integer pn= GetPlayerId(p)
            
            if pn == 1 then
                loop
                    exitwhen i > 40
                    if t == s___BarData_t[s__BarData_t[Bars[1]]+i] then
                        if i < 12 then
                            set i=12
                        elseif i > 29 then
                            set i=29
                        endif
                        set TargetY[1]=s___BarData_y[s__BarData_y[Bars[1]]+i]
                        call SetUnitAnimationByIndex(Unit[1], 10)
                    endif
                    set i=i + 1
                endloop
            endif
            
            return false
        endfunction
        
        function s__Controller_onHover2 takes nothing returns boolean
            
            local integer i= 1
            local player p= (s__Track_tracker) // INLINED!!
            local integer t= (s__Track_instance) // INLINED!!
            local integer pn= GetPlayerId(p)
            
            if pn == 2 then
                loop
                    exitwhen i > 40
                    if t == s___BarData_t[s__BarData_t[Bars[2]]+i] then
                        if i < 12 then
                            set i=12
                        elseif i > 29 then
                            set i=29
                        endif
                        set TargetX[2]=s___BarData_x[s__BarData_x[Bars[2]]+i]
                        call SetUnitAnimationByIndex(Unit[2], 10)
                    endif
                    set i=i + 1
                endloop
            endif
            
            return false
        endfunction
        
        function s__Controller_onHover3 takes nothing returns boolean
            
            local integer i= 1
            local player p= (s__Track_tracker) // INLINED!!
            local integer t= (s__Track_instance) // INLINED!!
            local integer pn= GetPlayerId(p)
            
            if pn == 3 then
                loop
                    exitwhen i > 40
                    if t == s___BarData_t[s__BarData_t[Bars[3]]+i] then
                        if i < 12 then
                            set i=12
                        elseif i > 29 then
                            set i=29
                        endif
                        set TargetY[3]=s___BarData_y[s__BarData_y[Bars[3]]+i]
                        call SetUnitAnimationByIndex(Unit[3], 10)
                    endif
                    set i=i + 1
                endloop
            endif
            
            return false
        endfunction
        
//Implemented from module MissileStruct:
        
// Why not run some debug checks first.


























        




        
        // Stupid name ensures not to be called accidently.
        function s__Controller_MissileStruct__missileTerminateP takes integer node returns nothing










            
            call s__Missile_terminate(node)
            call Missile___StopPeriodic(si__Controller)
        endfunction
    
        // Returns boolean to be compile-able with Cohadars JassHelper.
        function s__Controller_MissileStruct__missileIterateP takes nothing returns boolean
            local integer this= (s__Missile_Missile___MissileStructure___first[(Missile___missileStack[si__Controller])]) // INLINED!!
            local integer node
            local real collideZ
            local unit u
            
            // Move the whole stack.
            call s__Missile_move(this)
            loop
                exitwhen this == 0
                set node=(s__Missile_Missile___MissileStructure___next[(this)]) // INLINED!!
               
                if ( s__Missile_wantDestroy[this] ) then





                        call s__Controller_MissileStruct__missileTerminateP(this)

                else
                






































                        



















                
                    if ( s__Missile_recycle[this] ) and ( s__Missile_allocated[this] ) then































                                call s__Controller_MissileStruct__missileTerminateP(this)


                    endif
                











                
                    // Runs last











                endif
                set this=node
            endloop
           
            set u=null
            return false
        endfunction
    
        function s__Controller_launch takes integer missile returns nothing


        
            call s__Missile_insertEnd(Missile___missileStack[si__Controller],missile)
            call Missile___StartPeriodic(si__Controller)
        endfunction
    
        function s__Controller_MissileStruct__onInit takes nothing returns nothing
            set Missile___missileStack[si__Controller]=s__Missile_allocateCollection()
            set Missile___expression[(si__Controller )]=Condition(( function s__Controller_MissileStruct__missileIterateP)) // INLINED!!



        endfunction
    
        
        function s__Controller_onClick takes nothing returns boolean
            
            local integer i= 1
            local player p= (s__Track_tracker) // INLINED!!
            local integer pn= GetPlayerId(p)
            local real x
            local real y
            local real z
            local real x2
            local real y2
            local real a
            local real d
            local integer m
            
            set x2=CurrentX[pn] + 64 * Cos(HP - HP * pn + bj_PI)
            set y2=CurrentY[pn] + 64 * Sin(HP - HP * pn + bj_PI)
            set z=GetTerrainZ(CurrentX[pn] , CurrentY[pn]) + 15
            set m=s__Missile_create(CurrentX[pn] , CurrentY[pn] , z , HP - HP * pn , 64 , z)
            call s__Missile__set_model(m,"war3mapImported\\Pump" + I2S(pn) + ".mdx")
            set s__Missile_speed[m]=30
            call s__Controller_launch(m)
            loop
                exitwhen i > CocoCount
                set x=s__Coconut_x[Cocos[i]]
                set y=s__Coconut_y[Cocos[i]]
                set d=SquareRoot(( x2 - x ) * ( x2 - x ) + ( y2 - y ) * ( y2 - y ))
                if d < 256 and d > 64 then
                    set a=Atan2(y - y2, x - x2)
                    if circularDifference(normalize(HP - HP * pn) , normalize(a)) < HP / 2 then
                        set d=SquareRoot(( CurrentX[pn] - x ) * ( CurrentX[pn] - x ) + ( CurrentY[pn] - y ) * ( CurrentY[pn] - y ))
                        if circularDifference(normalize(s__Coconut_angle[Cocos[i]]) , normalize(HP - HP * pn)) > HP then
                            set s__Coconut_speed[Cocos[i]]=30 * ( 1 - ( d - 64 ) / 224 )
                        else
                            set s__Coconut_speed[Cocos[i]]=s__Coconut_speed[Cocos[i]] + 30 * ( 1 - d / 224 )
                        endif
                        if s__Coconut_speed[Cocos[i]] > 30 then
                            set s__Coconut_speed[Cocos[i]]=30
                        endif
                        set s__Coconut_angle[Cocos[i]]=a
                        set s__Coconut_duration[Cocos[i]]=15
                        if s__Coconut_source[Cocos[i]] != pn then
                            set s__Coconut_source[Cocos[i]]=pn
                            call DestroyEffect(s__Coconut_sfx[Cocos[i]])
                            set s__Coconut_sfx[Cocos[i]]=AddSpecialEffectTarget("war3mapImported\\Coco" + I2S(pn) + ".mdx", s__Coconut_missile[Cocos[i]], "origin")
                        endif
                    endif
                endif
                set i=i + 1
            endloop
            
            return false
        endfunction
        
        function s__Controller_onInit takes nothing returns nothing
            
            local integer i= 1
            local player p
            
            set Bars[0]=s__BarData__allocate()
            loop
                exitwhen i > 40
                set s___BarData_x[s__BarData_x[Bars[0]]+i]=- 656 + 32 * i
                set s___BarData_y[s__BarData_y[Bars[0]]+i]=- 768
                set s___BarData_t[s__BarData_t[Bars[0]]+i]=(s__Track_createTrack((("war3mapImported\\Invis2.mdx" ) ) , (( (( s___BarData_x[s__BarData_x[Bars[0]]+i] )*1.0) )*1.0) , (( (( s___BarData_y[s__BarData_y[Bars[0]]+i] )*1.0) )*1.0) , (( (( 300 )*1.0) )*1.0) , (( (( 0)*1.0))*1.0) , null)) // INLINED!!
                call s__Track_registerHover((s___BarData_t[s__BarData_t[Bars[0]]+i] ),( function s__Controller_onHover0)) // INLINED!!
                call s__Track_registerClick((s___BarData_t[s__BarData_t[Bars[0]]+i] ),( function s__Controller_onClick)) // INLINED!!
                set i=i + 1
            endloop
            
            set i=1
            set Bars[1]=s__BarData__allocate()
            loop
                exitwhen i > 40
                set s___BarData_x[s__BarData_x[Bars[1]]+i]=- 768
                set s___BarData_y[s__BarData_y[Bars[1]]+i]=- 656 + 32 * i
                set s___BarData_t[s__BarData_t[Bars[1]]+i]=(s__Track_createTrack((("war3mapImported\\Invis2.mdx" ) ) , (( (( s___BarData_x[s__BarData_x[Bars[1]]+i] )*1.0) )*1.0) , (( (( s___BarData_y[s__BarData_y[Bars[1]]+i] )*1.0) )*1.0) , (( (( 300 )*1.0) )*1.0) , (( (( HP)*1.0))*1.0) , null)) // INLINED!!
                call s__Track_registerHover((s___BarData_t[s__BarData_t[Bars[1]]+i] ),( function s__Controller_onHover1)) // INLINED!!
                call s__Track_registerClick((s___BarData_t[s__BarData_t[Bars[1]]+i] ),( function s__Controller_onClick)) // INLINED!!
                set i=i + 1
            endloop
            
            set i=1
            set Bars[2]=s__BarData__allocate()
            loop
                exitwhen i > 40
                set s___BarData_x[s__BarData_x[Bars[2]]+i]=- 656 + 32 * i
                set s___BarData_y[s__BarData_y[Bars[2]]+i]=768
                set s___BarData_t[s__BarData_t[Bars[2]]+i]=(s__Track_createTrack((("war3mapImported\\Invis2.mdx" ) ) , (( (( s___BarData_x[s__BarData_x[Bars[2]]+i] )*1.0) )*1.0) , (( (( s___BarData_y[s__BarData_y[Bars[2]]+i] )*1.0) )*1.0) , (( (( 300 )*1.0) )*1.0) , (( (( 0)*1.0))*1.0) , null)) // INLINED!!
                call s__Track_registerHover((s___BarData_t[s__BarData_t[Bars[2]]+i] ),( function s__Controller_onHover2)) // INLINED!!
                call s__Track_registerClick((s___BarData_t[s__BarData_t[Bars[2]]+i] ),( function s__Controller_onClick)) // INLINED!!
                set i=i + 1
            endloop
            
            set i=1
            set Bars[3]=s__BarData__allocate()
            loop
                exitwhen i > 40
                set s___BarData_x[s__BarData_x[Bars[3]]+i]=768
                set s___BarData_y[s__BarData_y[Bars[3]]+i]=- 656 + 32 * i
                set s___BarData_t[s__BarData_t[Bars[3]]+i]=(s__Track_createTrack((("war3mapImported\\Invis2.mdx" ) ) , (( (( s___BarData_x[s__BarData_x[Bars[3]]+i] )*1.0) )*1.0) , (( (( s___BarData_y[s__BarData_y[Bars[3]]+i] )*1.0) )*1.0) , (( (( 300 )*1.0) )*1.0) , (( (( HP)*1.0))*1.0) , null)) // INLINED!!
                call s__Track_registerHover((s___BarData_t[s__BarData_t[Bars[3]]+i] ),( function s__Controller_onHover3)) // INLINED!!
                call s__Track_registerClick((s___BarData_t[s__BarData_t[Bars[3]]+i] ),( function s__Controller_onClick)) // INLINED!!
                set i=i + 1
            endloop
            
            set StartX[0]=- 16
            set StartY[0]=- 768
            set StartX[1]=- 768
            set StartY[1]=- 16
            set StartX[2]=- 16
            set StartY[2]=768
            set StartX[3]=768
            set StartY[3]=- 16
            
            set i=0
            loop
                exitwhen i > 3
                set p=Player(i)
                set Control[i]=CreateUnit(p, 'h006', 0, 0, 0)
                set CurrentX[i]=StartX[i]
                set CurrentY[i]=StartY[i]
                set TargetX[i]=StartX[i]
                set TargetY[i]=StartY[i]
                set Unit[i]=CreateUnit(p, 'h002' + i, StartX[i], StartY[i], 90 - 90 * i)
                if GetLocalPlayer() == p then
                    call SetCameraTargetController(Control[i], 0, 0, false)
                    call SelectUnit(Control[i], true)
                endif
                set IsAI[i]=GetPlayerController(p) != MAP_CONTROL_USER
                if GetPlayerSlotState(p) != PLAYER_SLOT_STATE_PLAYING then
                    set IsAI[i]=true
                endif
                set i=i + 1
            endloop
            
            call TimerStart((NewTimerEx(0)), 0.03125, true, function s__Controller_periodic) // INLINED!!
            
        endfunction
        
    
// scope Control ends
// Trigger: Music
//===========================================================================
function Trig_Music_Actions takes nothing returns nothing
    call PlayMusic("war3mapImported\\music.mp3")
endfunction

//===========================================================================
function InitTrig_Music takes nothing returns nothing
    set gg_trg_Music=CreateTrigger()
    call TriggerRegisterTimerEventSingle(gg_trg_Music, 0.00)
    call TriggerAddAction(gg_trg_Music, function Trig_Music_Actions)
endfunction

//===========================================================================
// Trigger: GUI
//===========================================================================
function Trig_GUI_Actions takes nothing returns nothing
    call PlayMusic("war3mapImported\\blank.mp3")
    call SetAmbientDaySound("war3mapImported\\blank.mp3")
    call SetTimeOfDay(12)
    call SetTimeOfDayScalePercentBJ(0)
    call EnableDragSelect(false, false)
    call EnablePreSelect(true, false)
    call FogEnableOff()
    call FogMaskEnableOff()
endfunction

//===========================================================================
function InitTrig_GUI takes nothing returns nothing
    set gg_trg_GUI=CreateTrigger()
    call TriggerAddAction(gg_trg_GUI, function Trig_GUI_Actions)
endfunction

//===========================================================================
// Trigger: test
//===========================================================================
function Trig_test_Actions takes nothing returns nothing
    call s__Coconut_create(0 , 0)
endfunction

//===========================================================================
function InitTrig_test takes nothing returns nothing
    set gg_trg_test=CreateTrigger()
    call TriggerRegisterTimerEventPeriodic(gg_trg_test, 2)
    call TriggerAddAction(gg_trg_test, function Trig_test_Actions)
endfunction

//===========================================================================
// Trigger: Missile
//===========================================================================
//TESH.scrollpos=185
//TESH.alwaysfold=0
// Trigger: AngleDiff
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: ExSound
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: Track
//===========================================================================
//TESH.scrollpos=21
//TESH.alwaysfold=0
// Trigger: Table
//===========================================================================
//TESH.scrollpos=156
//TESH.alwaysfold=0
// Trigger: AutoFly
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: Unit Indexer
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: Event
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: Alloc
//===========================================================================
//TESH.scrollpos=27
//TESH.alwaysfold=0

//===========================================================================
// Trigger: Error Message
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
//===========================================================================
// Trigger: WorldBounds
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: PathingType
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: TimerUtils
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: UnitZ
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Trigger: GetTerrainZ
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
function InitCustomTriggers takes nothing returns nothing
    //Function not found: call InitTrig_AI()
    //Function not found: call InitTrig_Unit()
    //Function not found: call InitTrig_Coconut()
    //Function not found: call InitTrig_Control()
    call InitTrig_Music()
    call InitTrig_GUI()
    call InitTrig_test()
    //Function not found: call InitTrig_Missile()
    //Function not found: call InitTrig_AngleDiff()
    //Function not found: call InitTrig_ExSound()
    //Function not found: call InitTrig_Track()
    //Function not found: call InitTrig_Table()
    //Function not found: call InitTrig_AutoFly()
    //Function not found: call InitTrig_Unit_Indexer()
    //Function not found: call InitTrig_Event()
    //Function not found: call InitTrig_Alloc()
    //Function not found: call InitTrig_Error_Message()
    //Function not found: call InitTrig_WorldBounds()
    //Function not found: call InitTrig_PathingType()
    //Function not found: call InitTrig_TimerUtils()
    //Function not found: call InitTrig_UnitZ()
    //Function not found: call InitTrig_GetTerrainZ()
endfunction

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

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

function InitCustomPlayerSlots takes nothing returns nothing

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

    // Player 1
    call SetPlayerStartLocation(Player(1), 1)
    call ForcePlayerStartLocation(Player(1), 1)
    call SetPlayerColor(Player(1), ConvertPlayerColor(1))
    call SetPlayerRacePreference(Player(1), RACE_PREF_HUMAN)
    call SetPlayerRaceSelectable(Player(1), false)
    call SetPlayerController(Player(1), MAP_CONTROL_USER)

    // Player 2
    call SetPlayerStartLocation(Player(2), 2)
    call ForcePlayerStartLocation(Player(2), 2)
    call SetPlayerColor(Player(2), ConvertPlayerColor(2))
    call SetPlayerRacePreference(Player(2), RACE_PREF_HUMAN)
    call SetPlayerRaceSelectable(Player(2), false)
    call SetPlayerController(Player(2), MAP_CONTROL_USER)

    // Player 3
    call SetPlayerStartLocation(Player(3), 3)
    call ForcePlayerStartLocation(Player(3), 3)
    call SetPlayerColor(Player(3), ConvertPlayerColor(3))
    call SetPlayerRacePreference(Player(3), RACE_PREF_HUMAN)
    call SetPlayerRaceSelectable(Player(3), false)
    call SetPlayerController(Player(3), MAP_CONTROL_USER)

endfunction

function InitCustomTeams takes nothing returns nothing
    // Force: TRIGSTR_075
    call SetPlayerTeam(Player(0), 0)

    // Force: TRIGSTR_076
    call SetPlayerTeam(Player(1), 1)

    // Force: TRIGSTR_077
    call SetPlayerTeam(Player(2), 2)

    // Force: TRIGSTR_078
    call SetPlayerTeam(Player(3), 3)

endfunction

function InitAllyPriorities takes nothing returns nothing

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

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

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

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

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

//===========================================================================
function main takes nothing returns nothing
    call SetCameraBounds(- 5376.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), - 3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM), 5376.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), - 5376.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), 5376.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), - 3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM))
    call SetDayNightModels("Environment\\DNC\\DNCLordaeron\\DNCLordaeronTerrain\\DNCLordaeronTerrain.mdl", "Environment\\DNC\\DNCLordaeron\\DNCLordaeronUnit\\DNCLordaeronUnit.mdl")
    call SetTerrainFogEx(0, 0.0, 100000.0, 0.000, 1.000, 1.000, 1.000)
    call NewSoundEnvironment("Default")
    call SetAmbientDaySound("SunkenRuinsDay")
    call SetAmbientNightSound("SunkenRuinsNight")
    call SetMapMusic("Music", true, 0)
    call CreateRegions()
    call CreateCameras()
    call InitBlizzard()

call ExecuteFunc("jasshelper__initstructs74849404")
call ExecuteFunc("PathingType___onInit")
call ExecuteFunc("TimerUtils___init")

    call InitGlobals()
    call InitCustomTriggers()
    call ConditionalTriggerExecute(gg_trg_GUI) // INLINED!!

endfunction

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

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

    call DefineStartLocation(0, 0.0, 0.0)
    call DefineStartLocation(1, 0.0, 0.0)
    call DefineStartLocation(2, 0.0, 0.0)
    call DefineStartLocation(3, 0.0, 0.0)

    // Player setup
    call InitCustomPlayerSlots()
    call InitCustomTeams()
    call InitAllyPriorities()
endfunction




//Struct method generated initializers/callers:

//Functions for BigArrays:
function sa__Coconut_getLowestGr takes nothing returns boolean
local integer this=f__arg_this
            local real x
            local real y
            local real z
            local real x2
            local real y2
            local real z2
            local real angle= 0
            local real o= GetTerrainZ(s__Coconut_x[this] , s__Coconut_y[this])
            local real lowest= 99999999
            local real acc= 10 * bj_DEGTORAD
            set x=s__Coconut_x[this] + SLOPE_ACCURACY * Cos(acc)
            set y=s__Coconut_y[this] + SLOPE_ACCURACY * Sin(acc)
            set z=GetTerrainZ(x , y)
            set x2=s__Coconut_x[this] + SLOPE_ACCURACY * Cos(- acc)
            set y2=s__Coconut_y[this] + SLOPE_ACCURACY * Sin(- acc)
            set z2=GetTerrainZ(x2 , y2)
            if z2 < z then
                set acc=- acc
            endif
            loop
                exitwhen RAbsBJ(angle) >= TAU
                set x=s__Coconut_x[this] + SLOPE_ACCURACY * Cos(angle)
                set y=s__Coconut_y[this] + SLOPE_ACCURACY * Sin(angle)
                if Coconut___IsInBound(x , y) then
                    set z=GetTerrainZ(x , y)
                    exitwhen lowest < z
                    if z < lowest then
                        set lowest=z
                        set s__Coconut___Ground_x=x
                        set s__Coconut___Ground_y=y
                    endif
                endif
                set angle=angle + acc
            endloop
            if o < lowest then
                set s__Coconut___Ground_x=s__Coconut_x[this]
                set s__Coconut___Ground_y=s__Coconut_y[this]
            endif
   return true
endfunction
function sa__Coconut_slip takes nothing returns boolean
local integer this=f__arg_this
local real speed=f__arg_real1
local real maxspeed=f__arg_real2
local real angle=f__arg_real3
local real rate=f__arg_real4
            local real diff
            local real turnPow
            local real spdPow
            set angle=s__Coconut_normalize(angle)
            set diff=s__Coconut_circularDifference(angle , s__Coconut_angle[this])
            set turnPow=RAbsBJ(s__Coconut_circularDifference(diff , HP))
            set turnPow=1 - turnPow / HP
            call s__Coconut_turn(this,angle , rate * turnPow)
            set spdPow=1 - diff * ( 2 / bj_PI )
            if spdPow < 0 or s__Coconut_speed[this] < maxspeed then
                set s__Coconut_speed[this]=s__Coconut_speed[this] + speed * spdPow
                if spdPow >= 0 and s__Coconut_speed[this] > maxspeed then
                    set s__Coconut_speed[this]=maxspeed
                endif
                if s__Coconut_speed[this] < 0 then
                    set s__Coconut_angle[this]=angle
                    set s__Coconut_speed[this]=s__Coconut_speed[this] + speed
                endif
            endif
   return true
endfunction
function sa___prototype9_TimerUtils___init takes nothing returns boolean

     local integer i=0
     local integer o=- 1
     local boolean oops= false
        if ( TimerUtils___didinit ) then
    return true
        else
            set TimerUtils___didinit=true
        endif
            set TimerUtils___ht=InitHashtable()
            loop
                exitwhen ( i == TimerUtils___QUANTITY )
                set s__TimerUtils___tT[i]= CreateTimer()
                call SaveInteger(TimerUtils___ht, 0, GetHandleId((s__TimerUtils___tT[i] )), ( TimerUtils___HELD)) // INLINED!!
                set i=i + 1
            endloop
            set TimerUtils___tN=TimerUtils___QUANTITY
    return true
endfunction

function jasshelper__initstructs74849404 takes nothing returns nothing
    set st__Coconut_getLowestGr=CreateTrigger()
    call TriggerAddCondition(st__Coconut_getLowestGr,Condition( function sa__Coconut_getLowestGr))
    set st__Coconut_slip=CreateTrigger()
    call TriggerAddCondition(st__Coconut_slip,Condition( function sa__Coconut_slip))
    set st___prototype9[1]=CreateTrigger()
    call TriggerAddAction(st___prototype9[1],function sa___prototype9_TimerUtils___init)
    call TriggerAddCondition(st___prototype9[1],Condition(function sa___prototype9_TimerUtils___init))

















































call ExecuteFunc("s__WorldBounds_WorldBounds___WorldBoundInit__onInit")




call ExecuteFunc("s__Track_Track___Init__onInit")



call ExecuteFunc("s__UnitIndexer_UnitIndexer___UnitIndexerInit__onInit")

call ExecuteFunc("s__AutoFly___Inits_AutoFly___Init__onInit")






call ExecuteFunc("s__AI_MissileStruct__onInit")





call ExecuteFunc("s__Controller_MissileStruct__onInit")

    call ExecuteFunc("s__Coconut_onInit")
    call ExecuteFunc("s__AI_onInit")
    call ExecuteFunc("s__Controller_onInit")
endfunction

Map protection is a lie!
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
Seems pretty impresive
I think the algorithm is something like: you periodically detect all nearby coconuts and order the AI to move there (not 'Amov', but via SetUnitX,Y) but taking the speed factor in the priority.

My suggestion is to slightly enlarge the trackable area because sometimes, the mouse wander outside of it. Oh and make it possible to select arenas too.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Seems pretty impresive
I think the algorithm is something like: you periodically detect all nearby coconuts and order the AI to move there (not 'Amov', but via SetUnitX,Y) but taking the speed factor in the priority.

My suggestion is to slightly enlarge the trackable area because sometimes, the mouse wander outside of it. Oh and make it possible to select arenas too.

Close enough. :) You can see the code above tho at DSG's post. But you know it's the old version, I only had worked on it for 1 hour or so.

I agree with your suggestions. Will do it some times later. Thanks
 
Status
Not open for further replies.
Top