1. Are you planning to upload your awesome map to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. The reforging of the races is complete. Come see the 14th Techtree Contest Results.
    Dismiss Notice
  5. It's time to choose your horse in the race - the 32nd Modeling Contest Poll is up!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Trigger Viewer

TaigaSurvival1210.w3x
Variables
Initialization
debugmode
fadein
fadeinmore
make hashtable
maketrees
makesurvivor
call maketrees
call inits
populate
create playergroup
modify alliances
quests
addunittakesdamage
difficulty
difficulty
picked difficulty
yeti
ko
entercave
tips
upgrade penguin
gold
meat 1
meat 2
survivor clothes
giveclothesonupgrade
spells
press esc
start spells
snare
pincer
fastpump spell
end spell
pump spells
environment
yetispawn
addwolf
addbear
heatloss
fadein fadeout
start blizzard chance
chance of blizzard
blizzard comes
blizzard ends
unitdies
treedies
crippletedrant
AI
checkformeat
hashtable practice
proximity agitation
alerted pump
test proximity
treatwood
treatwood
item stacking
stackitems
dropitem
swapitem
shoot bow
arrowhit
decreasearrows
Generic Triggers
money
enablevision
detectleaver
radio rescue
callradiorescue
helicopterarrives
victory
chat to command
unally ally zoom
skiing
skipump
upgrades skis
skiturn
skigo
Untitled Trigger 002
Title: Taiga Survival Description: Warcraft III Custom Map
Copyright (C) 2009 Daniel Griffing

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
function ReturnTrue takes nothing returns boolean
    return true
endfunction

function upgrade2unitbling takes nothing returns nothing
    local unit u = GetEnumUnit()
    local player p = GetOwningPlayer(u)
    if GetPlayerTechCount(p,'R00B',true) > 0 then     // wooden armor
        call UnitAddAbility(u,'AId4')                 // scale shoulder pads
    endif
    if GetPlayerTechCount(p,'R00C',true) > 0 then     // bone armor
        call UnitRemoveAbility(u,'AId4')
        call UnitAddAbility(u,'AId8')                 // metal shoulder pads
    endif
    if GetPlayerTechCount(p,'R004',true) > 0 then // snow goggles
        call UnitAddAbility(u,'AId2')                 // goblin goggles
    endif
    if GetPlayerTechCount(p,'R006',true) > 1 then // big axe
        if GetUnitTypeId(u) == 'h001' then
            call UnitRemoveAbility(u,'AId1')          // remove small axe
            call UnitAddAbility(u,'AId0')             // give big axe
        endif
    elseif GetPlayerTechCount(p,'R006',true) > 0 then // small axe axe
        if GetUnitTypeId(u) == 'h001' then
            call UnitAddAbility(u,'AId1')             // give small axe
        endif  
    endif
    if GetPlayerTechCount(p,'R003',true) > 0 then // fur hat
        call UnitAddAbility(u,'AId5')                 // give fur hat
    endif
    //if GetUnitTypeId(u) == 'h004' then
        call AddUnitAnimationProperties(u,"Lumber",true)        
    //endif
endfunction

function say takes string message, unit u, integer r, integer g, integer b returns nothing
    call CreateTextTagUnitBJ( message, u, 0, 10, r, g, b, 0 )
    call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 64, 90 )
    call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
    call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 0.00 )
    call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 1.00 )
endfunction

function agitate takes unit u, integer agitation_modifier returns nothing
    local integer present_agitation =  LoadInteger(udg_hash,GetHandleId(u),StringHash("agitation"))
    local integer new_agitation = present_agitation + agitation_modifier
    //if new_agitation > 100 then
    //    set new_agitation = 100
    if new_agitation < 0 then
        set new_agitation = 0
    endif
    call SaveInteger(udg_hash,GetHandleId(u),StringHash("agitation"),new_agitation)
    call GroupAddUnit(udg_agitated, u)    
endfunction

function unit2group takes integer animaltype returns group
    if animaltype == 'n000' then
        return udg_herbgroup
    elseif animaltype == 'n001' then
        return udg_carngroup
    elseif animaltype == 'n002' then
        return udg_carngroup
    elseif animaltype == 'n003' then
        return udg_herbgroup
    elseif animaltype == 'n004' then
        return udg_herbgroup
    elseif animaltype == 'n005' then
        return udg_carngroup
    endif
    return null
endfunction

function spawnunit takes integer utype, player p, location l, integer parent_fight, integer parent_flight returns nothing
    local integer child_fight = parent_fight
    local integer child_flight = parent_flight
    local integer base_fight
    local integer base_flight
    local unit u = CreateUnitAtLoc(p, utype, l, GetRandomDirectionDeg())
    if utype == 'n000' then // elk
        set base_fight = 10
        set base_flight = 20
    elseif utype == 'n001' then // wolf
        set base_fight = 1
        set base_flight = 400
    elseif utype == 'n002' then // raccoon
        set base_fight = 1
        set base_flight = 6
    elseif utype == 'n003' then // rabbit
        set base_fight = 1
        set base_flight = 1
    elseif utype == 'n004' then // moose
        set base_fight = 20
        set base_flight = 70
    elseif utype == 'n005' then // bear
        set base_fight = 1
        set base_flight = 400
    else
        set base_fight = 1
        set base_flight = 9999
    endif        
    call SaveInteger(udg_hash,GetHandleId(u),StringHash("fight"),base_fight)
    call SaveInteger(udg_hash,GetHandleId(u),StringHash("agitation"),0)
    call SaveInteger(udg_hash,GetHandleId(u),StringHash("flight"),base_flight)
    call SaveInteger(udg_hash,GetHandleId(u),StringHash("extrafight"),parent_fight)
    call SaveInteger(udg_hash,GetHandleId(u),StringHash("extraflight"),parent_flight)
    call SaveInteger(udg_hash,GetHandleId(u),StringHash("pumpid"),GetRandomInt(0,99))
    call RemoveGuardPosition(u)
    call GroupAddUnit(unit2group(utype),u)    
endfunction
Name Type Is Array Initial Value
agitated group No
allunits group No
blizzard timer No
blizzardhappens timer No
blizzarding boolean No
bolas group No
boomerang group No
burning group No
burningtree group No
carngroup group No
chained group No
cleanthisloc location No
COLLISIONDAMAGE real No 30.00
CORNERINGFRICTION real No 0.50
crippleted unit No
crippletedrants string Yes
departure timer No
destructablecount integer No
dialogue dialog Yes
dummygroup group No
easy button Yes
escapepoint location No
GRAVITY real No 0.20
hard button Yes
hash hashtable No
helicopter unit No
helicopterarrived boolean No
herbgroup group No
ix integer No
NIGHTTIMEHEATLOSS real No 1.00
normal button Yes
oldmanwinter unit No
playable rect No RectNull
players force No
PREDATORWANDER real No 180.00
pumpid integer No
rescue timer No
rescuecalled boolean No
shakers group No
shot group No
skiiers group No
skispray group No
snowpilers group No
snowshovelers group No
survivors group No
survivorupgradebuilding unit Yes
temp_distance real No
temp_x real No
temp_y real No
tempbool boolean No
tempcollider unit No
tempint integer No
tempplayer player No
tempunit unit No
TORCHLIFE integer No 30
treecount integer No
TURNINGANGLE real No 2.50
WANDERDECREASE real No 0.30
WINDRESISTANCE real No 0.00
debugmode
  Events
    Map initialization
  Conditions
  Actions
    Game - Display to (All players) the text: |cffffcc00Debug Mode|r
    Trigger - Turn off fadein <gen>
    Trigger - Turn off fadeinmore <gen>
    Trigger - Turn off maketrees <gen>
    Trigger - Turn off call_maketrees <gen>
    Trigger - Turn off call_inits <gen>
    Trigger - Run money <gen> (ignoring conditions)
    Trigger - Run enablevision <gen> (ignoring conditions)
fadein
  Events
    Time - Elapsed game time is 0.01 seconds
  Conditions
  Actions
    Cinematic - Apply a filter over 6.00 seconds using Normal blending on texture White Mask, starting with color (0.00%, 0.00%, 0.00%) and 0.00% transparency and ending with color (50.00%, 50.00%, 50.00%) and 10.00% transparency
    Game - Display to (All players) for 15.00 seconds the text: |cffC0C0c0You wake in the snow. The elements have already scattered the debris of an airplane that you were, until very recently, a passenger of. A handful of survivors and casualties rest on the snow around you. Slowly everyone rises.|r
    Environment - Set fog to style Linear, z-start 1000, z-end 8000, density 10.00 and color (100%, 100%, 100%)
    Game - Set the time of day to 6.00
fadeinmore
  Events
    Time - Elapsed game time is 6.00 seconds
  Conditions
  Actions
    Cinematic - Apply a filter over 6.00 seconds using Normal blending on texture White Mask, starting with color (50.00%, 50.00%, 50.00%) and 10.00% transparency and ending with color (100.00%, 100.00%, 100.00%) and 100.00% transparency
make hashtable
  Events
    Map initialization
  Conditions
  Actions
    Hashtable - Create a hashtable
    Set VariableSet hash = (Last created hashtable)
function anybodyhome takes nothing returns nothing
    set udg_destructablecount = udg_destructablecount + 1
endfunction

function chance_to_plant takes location l, real parentheight, real facing, integer age, integer basechance returns integer
    // determine tree's chance of survival
    local integer chance = basechance
    local integer terrain = GetTerrainType(GetLocationX(l),GetLocationY(l))
    local real childheight = GetLocationZ(l)
    local integer face = R2I(facing)
    // downhill children are more likely to plant
    if childheight > parentheight then
        set chance = chance - 10
    elseif childheight < parentheight then
        set chance = chance + 10
    endif
    // upwind children are less likely to plant
    if face > 45 then
        if face < 135 then
            set chance = chance - 10
        endif
    endif
    // downwind children are more likely to plant
    if facing > 225 then
        if facing < 315 then
            set chance = chance + 10
        endif
    endif
    // children cannot plant near other children
    call EnumDestructablesInCircleBJ(50,l,function anybodyhome)
    if udg_destructablecount > 0 then
        set udg_destructablecount = 0
        //call DisplayTextToForce(GetPlayersAll(),"didnt fit")
        return 0
    endif
    // children not in snow cannot plant
    if terrain != 'Nsnw' then
        return 0
    endif
    // children off screen cannot plant
    if not RectContainsCoords(GetPlayableMapRect(),GetLocationX(l),GetLocationY(l)) then
        //call DisplayTextToForce(GetPlayersAll(),"bad zoning")
        return 0  
    endif
    // set chance between 0 and 100
    if chance > 100 then
        set chance = 100
    elseif chance < 0 then
        set chance = 0
    endif
    return chance  
endfunction

function plant_tree takes location l, real height, real facing, integer age, integer basechance returns integer
    // recursive function, get tree's chance to plant and then try making more tree babies
    // in random directions if the tree does indeed plant itself
    local integer ix = 0
    local real child_facing
    local location child_l
    local integer child_distance
    local destructable tree
    if GetRandomInt(1,100) > chance_to_plant(l, height, facing, age, basechance) then
        return 0
    endif
    set tree = CreateDestructableLoc( 'WTst', l, GetRandomDirectionDeg(), 1, GetRandomInt(0,10) )
    call TriggerRegisterDeathEvent( gg_trg_treedies, tree)
    //call CreateUnitAtLoc(Player(6),'h000',l,0)
    loop
        exitwhen ix == 3
        set ix = ix + 1
        set child_facing = GetRandomDirectionDeg()
        set child_distance = GetRandomInt(300,400)
        //set child_distance = GetRandomInt(200,600)
        set child_l = PolarProjectionBJ(l,child_distance,child_facing)
        call plant_tree(child_l, GetLocationZ(l), child_facing, age+1, basechance+GetRandomInt(-2,2))
    endloop
    call RemoveLocation(child_l)
    set child_l = null
    set udg_treecount = udg_treecount + 1
    //call DisplayTextToForce(GetPlayersAll(),I2S(udg_treecount))
    return 1
endfunction

function Trig_maketrees_Actions takes nothing returns nothing
    // initialize with map, keep making new seed trees until quota is reached
    local location l
    loop
        exitwhen udg_treecount > 2000
        //set udg_treecount = udg_treecount + 1
        set l = GetRandomLocInRect(GetPlayableMapRect())
        call plant_tree(l,0,0,0,GetRandomInt(10,40))
        //call DisplayTextToForce(GetPlayersAll(),"looping again")
        //call DisplayTextToForce(GetPlayersAll(),I2S(udg_treecount))
        //call RemoveLocation(l)
    endloop
    call RemoveLocation(l)
    set l = null
    //call DisplayTextToForce(GetPlayersAll(),"finished")
    call DisplayTextToForce(GetPlayersAll(),I2S(udg_treecount))
endfunction

//===========================================================================
function InitTrig_maketrees takes nothing returns nothing
    set gg_trg_maketrees = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_maketrees, 1.00 )
    call TriggerAddAction( gg_trg_maketrees, function Trig_maketrees_Actions )
endfunction
function Trig_makesurvivor_Actions takes nothing returns nothing
    local real x = GetRandomReal(GetRectMinX(gg_rct_redspawn),GetRectMaxX(gg_rct_redspawn))
    local real y = GetRandomReal(GetRectMinY(gg_rct_redspawn),GetRectMaxY(gg_rct_redspawn))
    local unit u = CreateUnit(udg_tempplayer,'h001',x,y,0)
    call SetUnitState(u,UNIT_STATE_MANA,100)
    call GroupAddUnit(udg_survivors,u)      
endfunction

//===========================================================================
function InitTrig_makesurvivor takes nothing returns nothing
    set gg_trg_makesurvivor = CreateTrigger(  )
    call TriggerAddAction( gg_trg_makesurvivor, function Trig_makesurvivor_Actions )
endfunction
call maketrees
  Events
    Time - Elapsed game time is 0.50 seconds
    Time - Elapsed game time is 1.00 seconds
    Time - Elapsed game time is 1.50 seconds
    Time - Elapsed game time is 2.00 seconds
    Time - Elapsed game time is 2.50 seconds
    Time - Elapsed game time is 3.00 seconds
    Time - Elapsed game time is 3.50 seconds
    Time - Elapsed game time is 4.00 seconds
    Time - Elapsed game time is 4.50 seconds
    Time - Elapsed game time is 5.00 seconds
    Time - Elapsed game time is 5.50 seconds
    Time - Elapsed game time is 6.00 seconds
    Time - Elapsed game time is 6.50 seconds
  Conditions
  Actions
    Trigger - Run maketrees <gen> (ignoring conditions)
call inits
  Events
    Time - Elapsed game time is 4.00 seconds
  Conditions
  Actions
    Set VariableSet crippletedrants[0] = I'd stand up but my balls are frozen to the ground.
    Set VariableSet crippletedrants[1] = Someone get me some rum!
    Set VariableSet crippletedrants[2] = Make me somethin' nice, honey!
    Set VariableSet crippletedrants[3] = I just made a little snowman.
    Set VariableSet crippletedrants[4] = ... and so *I* said, "That ain't a bagpipe, baby, but keep playing!"
    Set VariableSet crippletedrants[5] = Rectum? Darn near KILLED 'em!
    Set VariableSet crippletedrants[6] = Damn this is a lot of snow.
    Set VariableSet crippletedrants[7] = I don't know why y'all think this is a good idea.
    Set VariableSet crippletedrants[8] = ... and so little Jimmy said, "because it was SALTY!"
    Set VariableSet crippletedrants[9] = Knock Knock!|nWho's there?|nThe military. Your son just died in Iraq.
    Trigger - Run populate <gen> (checking conditions)
    Trigger - Run create_playergroup <gen> (ignoring conditions)
    Trigger - Run modify_alliances <gen> (ignoring conditions)
    Trigger - Run quests <gen> (ignoring conditions)
    Trigger - Run callradiorescue <gen> (ignoring conditions)
function removetreesforanimals takes nothing returns nothing
    call RemoveDestructable(GetEnumDestructable())
endfunction

function removetreesforwreck takes nothing returns nothing
    call KillDestructable(GetEnumDestructable())
endfunction

function createsurvivors takes nothing returns nothing
    local integer ix = 0
    local integer survivorix = 0
    local player p
    local location l = GetRectCenter(gg_rct_redspawn)
    local unit u
    local unit upgrade
    loop
        exitwhen ix == 7
        set p = Player(ix)
        if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
            set upgrade = CreateUnit(Player(ix),'n00F',0,0,0)
            loop
                exitwhen survivorix == 1
                set u = CreateUnitAtLoc(Player(ix),'h001', l, 0)
                //set udg_survivorupgradebuilding[ix] = upgrade
                call SetUnitState(u,UNIT_STATE_MANA,100)
                call GroupAddUnit(udg_survivors,u)
                //call GroupAddUnit(udg_skiiers,u)
                //call AddUnitAnimationProperties(u,"Channel",true)
                set survivorix = survivorix + 1
            endloop
            set survivorix = 0
        endif
        set ix = ix + 1
    endloop
    call RemoveLocation(l)
    set l = null
endfunction

function animal2loc takes integer animal returns location
    if animal == 'n005' then //bear
        return GetRandomLocInRect(gg_rct_bearzone)
    elseif animal == 'n001' then
        return GetRandomLocInRect(gg_rct_wolfzone)
    else
        return GetRandomLocInRect(gg_rct_thismap)
    endif
endfunction

function createanimal takes integer animaltype, integer size, integer herd, integer p returns nothing
    local integer animalcount = 0
    local integer ix = 0
    local location l
    loop
        exitwhen animalcount == size
        set l = animal2loc(animaltype)
        call EnumDestructablesInCircleBJ(100,l,function removetreesforanimals)
        loop
            exitwhen ix == herd
            set ix = ix + 1
            call spawnunit(animaltype, Player(p), l, 0, 0)
        endloop
        set animalcount = animalcount + 1
        set ix = 0
        call RemoveLocation(udg_cleanthisloc)
    endloop  
    call RemoveLocation(l)
    set l = null
endfunction

function createrangerstation takes nothing returns nothing
    local location l = GetRandomLocInRect(gg_rct_bearzone)
    call EnumDestructablesInCircleBJ(500,l,function removetreesforanimals)
    call CreateUnitAtLoc(Player(8),'n009',l,0)
    call RemoveLocation(l)
endfunction

function createwreckage takes nothing returns nothing
    local location l = GetRandomLocInRect(gg_rct_redspawn)
    local location wreckl
    local location ted_l
    local unit wreckage
    local unit ted
    local integer ix = 0
    set ted_l = PolarProjectionBJ(l,300,135)
    loop
        exitwhen ix == 9
        if GetPlayerSlotState(Player(ix)) == PLAYER_SLOT_STATE_EMPTY then
            set wreckl = PolarProjectionBJ(l,GetRandomReal(200,600),GetRandomDirectionDeg())
            call CreateUnitAtLoc(Player(9),'h009',wreckl,GetRandomDirectionDeg())
        endif
        set ix = ix + 1
    endloop
    set ix = 0
    loop
        exitwhen ix == 5
        set wreckl = PolarProjectionBJ(l,GetRandomReal(0,100),GetRandomDirectionDeg())
        call CreateUnitAtLoc(Player(8),'h00A',wreckl,GetRandomDirectionDeg())
        //call UnitApplyTimedLife(GetLastCreatedUnit(),'BTLF',10)
        call CreateUnitAtLoc(Player(8),'h00B',wreckl,GetRandomDirectionDeg())
        //call UnitApplyTimedLife(GetLastCreatedUnit(),'BTLF',10)
        set ix = ix + 1
    endloop
    call EnumDestructablesInCircleBJ(500,l,function removetreesforwreck)
    call SetTerrainType(GetLocationX(l),GetLocationY(l),'Ndrd',0,4,0)
    set wreckage = CreateUnitAtLoc(Player(8),'h008',l,90)
    set udg_crippleted = CreateUnitAtLoc(Player(8),'h00Y',ted_l,315)
    call SetUnitLookAt(udg_crippleted,"bone_chest",wreckage,0,0,0)
    //call UnitApplyTimedLife(GetLastCreatedUnit(),'BTLF',10)
    call RemoveLocation(l)
    call RemoveLocation(wreckl)
    call RemoveLocation(ted_l)
    set ted_l = null
    set l = null
    set wreckl = null
endfunction

function Trig_populate_Actions takes nothing returns nothing
    local integer elk = 4 // herds
    local integer rabbit = 20 // pairs
    local integer moose = 3 // individuals
    local integer raccoon = 5 // individuals
    local integer wolf = 1 // packs
    local integer bear = 2 // individuals
    call createanimal('n000',elk,1,10)
    call createanimal('n003',rabbit,2,10)
    call createanimal('n004',moose,1,10)
    call createanimal('n002',raccoon,1,11)
    call createanimal('n001',wolf,2,11)
    //call createanimal('n005',bear,1,11)
    //call createrangerstation()
    //call createsurvivors()
    call createwreckage()
endfunction

//===========================================================================
function InitTrig_populate takes nothing returns nothing
    set gg_trg_populate = CreateTrigger(  )
    call TriggerAddAction( gg_trg_populate, function Trig_populate_Actions )
endfunction

 
create playergroup
  Events
  Conditions
  Actions
    Player Group - Add Player 1 (Red) to players
    Player Group - Add Player 2 (Blue) to players
    Player Group - Add Player 3 (Teal) to players
    Player Group - Add Player 4 (Purple) to players
    Player Group - Add Player 5 (Yellow) to players
    Player Group - Add Player 6 (Orange) to players
    Player Group - Add Player 7 (Green) to players
modify alliances
  Events
  Conditions
  Actions
    Player Group - Pick every player in players and do (Make Player 11 (Dark Green) treat (Picked player) as an Neutral)
    Player Group - Pick every player in players and do (Make (Picked player) treat Player 9 (Gray) as an Ally with shared vision and full shared units)
    Player Group - Pick every player in (All players) and do (Make (Picked player) treat Player 10 (Light Blue) as an Enemy)
    Player - Make Player 8 (Pink) treat Player 11 (Dark Green) as an Ally with shared vision
    Player - Make Player 8 (Pink) treat Player 12 (Brown) as an Ally with shared vision
    Player Group - Pick every player in players and do (Make (Picked player) treat Player 10 (Light Blue) as an Ally with shared vision and full shared units)
    Player Group - Pick every player in players and do (Make Player 9 (Gray) treat (Picked player) as an Ally)
    Player Group - Pick every player in (All players) and do (Turn Gives bounty On for (Picked player))
quests
  Events
  Conditions
  Actions
    Quest - Create a Required quest titled Get to the Chopper with the description Get to the chopper when it arrives., using icon path ReplaceableTextures\CommandButtons\BTNROBOGOBLIN.blp
    Quest - Create a Optional quest titled Version with the description Version 2009 December 12Newer versions can be found at http://www.hiveworkshop.com/forums/maps-564/taiga-survival-146839/, using icon path ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp
    Quest - Create a Optional quest titled Tips with the description - Stay near a fire to stay warm until you can afford nice clothes.- Get torches from the wreckage. You can't start a fire without one.- Use a torch on a pile of sticks to start a fire. You can torch other things, too.- Buildings gradually decay. Repair them if you want them to last., using icon path ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp
    Quest - Create a Optional quest titled Animal Behavior with the description As an animal gets agitated, it becomes aggressive. Agitate it more and it will run away. Different species have different thresholds of aggression and alarm. That is, you're more likely to scare off a rabbit than a bear.Predators increasingly seek out survivors as the game progresses., using icon path ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp
    Quest - Create a Optional quest titled Zoom with the description Type "-zoom 1" for a close view.Type "-zoom 2" for a farther view.Etc., using icon path ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp
    Quest - Create a Optional quest titled Unally with the description Type "-unally 1" to unally player 1 (red)Type "-ally 1" to ally player 1 (red)Numbers to colors:1 red2 blue3 teal4 purple5 yellow6 orange7 green8 pink, using icon path ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp
    Quest - Create a Optional quest titled Skiing with the description Right click to aim, use "z" to move, and use "x" to slow down.A fast skier can kill a rabbit on impact., using icon path ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp
    Quest - Create a Optional quest titled Mapmakers with the description This map is unprotected and free to be edited by anyone under the terms of the GPLv3. Basically, you can do whatever you want as long as you keep it unprotected, keep my name on it, and release it under the GLP, too. The models, however, aren't GPL and you need to work that out with each modeler. Check credits for their info., using icon path ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp
    Quest - Create a Optional quest titled Credits with the description Lord_T: Ogre Axe, Short AxeVillager: Villagerman With AnimationsHappyTauren: Medkitperfjert: Iron War Axesunchips: EbonBow, WolfHat, Scaled Mail PaulderonsFingolfin: Goblin GogglesRightfield: HamGottfrei: Lethal BowRaidonGod: Chef's HatTalonTheMage: Konstruct Rifleikillforeyou: Platemail Paulderons, using icon path ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp
addunittakesdamage
  Events
    Unit - A unit enters (Entire map)
  Conditions
    Or - Any (Conditions) are true
      Conditions
        (Race of (Triggering unit)) Equal to Human
  Actions
    Trigger - Add to proximity_agitation <gen> the event ((Entering unit) Takes damage)
    Trigger - Add to snare <gen> the event ((Entering unit) Takes damage)
    Trigger - Add to ko <gen> the event ((Entering unit) Takes damage)
    Trigger - Add to arrowhit <gen> the event ((Entering unit) Takes damage)
difficulty
  Events
    Time - Elapsed game time is 4.00 seconds
  Conditions
  Actions
    For each (Integer A) from 1 to 7, do (Actions)
      Loop - Actions
        Dialog - Create a dialog button for dialogue[(Integer A)] labelled Easy
        Set VariableSet easy[(Integer A)] = (Last created dialog Button)
        Dialog - Create a dialog button for dialogue[(Integer A)] labelled Medium
        Set VariableSet normal[(Integer A)] = (Last created dialog Button)
        Dialog - Create a dialog button for dialogue[(Integer A)] labelled Hard
        Set VariableSet hard[(Integer A)] = (Last created dialog Button)
        Dialog - Show dialogue[(Integer A)] for (Player((Integer A)))
picked difficulty
  Events
    Dialog - A dialog button is clicked for dialogue[1]
    Dialog - A dialog button is clicked for dialogue[2]
    Dialog - A dialog button is clicked for dialogue[3]
    Dialog - A dialog button is clicked for dialogue[4]
    Dialog - A dialog button is clicked for dialogue[5]
    Dialog - A dialog button is clicked for dialogue[6]
    Dialog - A dialog button is clicked for dialogue[7]
  Conditions
  Actions
    For each (Integer A) from 1 to 7, do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (Clicked dialog button) Equal to easy[(Integer A)]
          Then - Actions
            Game - Display to (All players) the text: ((Name of (Triggering player)) + picks easy.)
            Player - Set the current research level of R00D (techcode) to 2 for (Triggering player)
            Dialog - Clear dialogue[(Integer A)]
            Set VariableSet tempplayer = (Triggering player)
            Trigger - Run makesurvivor <gen> (ignoring conditions)
          Else - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (Clicked dialog button) Equal to normal[(Integer A)]
          Then - Actions
            Game - Display to (All players) the text: ((Name of (Triggering player)) + picks normal.)
            Player - Set the current research level of R00D (techcode) to 1 for (Triggering player)
            Dialog - Clear dialogue[(Integer A)]
            Set VariableSet tempplayer = (Triggering player)
            Trigger - Run makesurvivor <gen> (ignoring conditions)
          Else - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            (Clicked dialog button) Equal to hard[(Integer A)]
          Then - Actions
            Game - Display to (All players) the text: ((Name of (Triggering player)) + picks hard.)
            Dialog - Clear dialogue[(Integer A)]
            Set VariableSet tempplayer = (Triggering player)
            Trigger - Run makesurvivor <gen> (ignoring conditions)
          Else - Actions
function knockedthefuckout takes unit u, real angle returns nothing
    local location l = GetUnitLoc(u)
    local real life = GetUnitState(u,UNIT_STATE_MAX_LIFE)
    local real velocity = Pow(RAbsBJ(2000-life),.3)
    call GroupAddUnit(udg_skiiers,u)
    call UnitAddAbility(u,'Amrf')
    call UnitRemoveAbility(u,'Amrf')
    call SaveReal(udg_hash,GetHandleId(u),StringHash("inertia_force"),velocity)
    call SaveBoolean(udg_hash,GetHandleId(u),StringHash("flying"),true)
    call SaveBoolean(udg_hash,GetHandleId(u),StringHash("involuntary"),true)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("height"),GetLocationZ(l))
    call SaveReal(udg_hash,GetHandleId(u),StringHash("vertical_velocity"),velocity/1.5)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("angular_velocity"),1)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("inertia_theta"),angle)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("total_spin"),0)            
    call SaveReal(udg_hash,GetHandleId(u),StringHash("total_velocity"),0)            
    call SetUnitPathing(u,false)
    call RemoveLocation(l)
    set l = null
endfunction

function Trig_ko_Actions takes nothing returns nothing
    local real angle
    if GetUnitTypeId(GetEventDamageSource()) == 'n00E' then
        if IsUnitType(GetTriggerUnit(),UNIT_TYPE_STRUCTURE) then
        else
            set angle = Atan2(GetUnitY(GetTriggerUnit())-GetUnitY(GetEventDamageSource()),GetUnitX(GetTriggerUnit())-GetUnitX(GetEventDamageSource()))
            call knockedthefuckout(GetTriggerUnit(),angle)            
        endif
    endif
endfunction

//===========================================================================
function InitTrig_ko takes nothing returns nothing
    set gg_trg_ko = CreateTrigger(  )
    call TriggerAddAction( gg_trg_ko, function Trig_ko_Actions )
endfunction
entercave
  Events
    Unit - A unit enters yeti <gen>
  Conditions
  Actions
    Game - Display to (Player group((Owner of (Triggering unit)))) the text: It smells like wet yeti in here.
upgrade penguin
  Events
    Time - Elapsed game time is 20.00 seconds
  Conditions
  Actions
    Quest - Display to (All players) the Hint message: |cffffcc00Hint:|r Remember to hotkey your Upgrade Penguin for easy access to upgrades.
gold
  Events
    Time - Elapsed game time is 60.00 seconds
  Conditions
  Actions
    Quest - Display to (All players) the Hint message: |cffffcc00Hint:|r Kill animals to receive gold.
meat 1
  Events
    Time - Elapsed game time is 100.00 seconds
  Conditions
  Actions
    Quest - Display to (All players) the Hint message: |cffffcc00Hint:|r Eat meat to regain hitpoints.
meat 2
  Events
    Time - Elapsed game time is 140.00 seconds
  Conditions
  Actions
    Quest - Display to (All players) the Hint message: |cffffcc00Hint:|r Cook meat by USING it on a fire, not dropping.
function Trig_giveclothesonupgrade_Actions takes nothing returns nothing
    call ForGroup(udg_survivors, function upgrade2unitbling)  
endfunction

//===========================================================================
function InitTrig_giveclothesonupgrade takes nothing returns nothing
    set gg_trg_giveclothesonupgrade = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_giveclothesonupgrade, EVENT_PLAYER_UNIT_RESEARCH_FINISH )
    call TriggerAddAction( gg_trg_giveclothesonupgrade, function Trig_giveclothesonupgrade_Actions )
endfunction
function Trig_press_esc_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_press_esc takes nothing returns nothing
    set gg_trg_press_esc = CreateTrigger(  )
    call TriggerRegisterPlayerKeyEventBJ( gg_trg_press_esc, Player(0), bj_KEYEVENTTYPE_DEPRESS, bj_KEYEVENTKEY_LEFT )
    call TriggerAddAction( gg_trg_press_esc, function Trig_press_esc_Actions )
endfunction

 
function burn_destructable takes nothing returns nothing
    local real x = GetDestructableX(GetEnumDestructable())
    local real y = GetDestructableY(GetEnumDestructable())
    local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),'h000',x,y,0)
    local effect fx
    if GetDestructableLife(GetEnumDestructable()) <= 0 then
        call RemoveDestructable(GetEnumDestructable())
        call RemoveUnit(u)
    elseif LoadBoolean(udg_hash,GetHandleId(u),StringHash("onfire")) != true then
        call SetUnitVertexColor(u,0,0,0,0)    
        call GroupAddUnit(udg_burningtree,u)
        call SaveInteger(udg_hash,GetHandleId(u),StringHash("burningtreeage"),6)
        call DestroyEffect(LoadEffectHandle(udg_hash,GetHandleId(u),StringHash("burningtreefx")))
        set fx = AddSpecialEffectTarget("Doodads\\Cinematic\\FirePillarMedium\\FirePillarMedium.mdl",u,"overhead")
        call SaveEffectHandle(udg_hash,GetHandleId(u),StringHash("burningtreefx"),fx)
        call SaveDestructableHandle(udg_hash,GetHandleId(u),StringHash("burningtree"),GetEnumDestructable())
        call SaveBoolean(udg_hash,GetHandleId(GetEnumDestructable()),StringHash("onfire"),true)
    endif
endfunction

function burn_unit takes nothing returns nothing
    local real x = GetUnitX(GetEnumUnit())
    local real y = GetUnitY(GetEnumUnit())
    local player p = GetOwningPlayer(udg_tempunit)
    local player target_p = GetOwningPlayer(GetEnumUnit())
    local effect fx
    local real life = GetUnitState(GetEnumUnit(),UNIT_STATE_LIFE)
    if GetUnitTypeId(GetEnumUnit()) == 'h00C' then
        call PlaySoundOnUnitBJ(gg_snd_burn,100,GetEnumUnit())
        call RemoveUnit(GetEnumUnit())
        call CreateUnit(target_p,'h002',x,y,90)
        call DestroyEffect(fx)
    elseif GetUnitTypeId(GetEnumUnit()) == 'h00L' then
        call DestroyEffect(fx)
    elseif p == target_p then
        call DestroyEffect(fx)
    else
        call SetUnitState(GetEnumUnit(),UNIT_STATE_LIFE,life-20)
        //call UnitDamageTarget(udg_tempunit,GetEnumUnit(),20,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_FIRE,null)
        call agitate(GetEnumUnit(),40)
        call GroupAddUnit(udg_burning,GetEnumUnit())
        call SaveInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burningage"),2)
        call DestroyEffect(LoadEffectHandle(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burning")))
        set fx = AddSpecialEffectTarget("Doodads\\Cinematic\\FirePillarMedium\\FirePillarMedium.mdl",GetEnumUnit(),"head")
        call SaveEffectHandle(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burning"),fx)
    endif
endfunction

function burn takes unit u, location l, unit target returns nothing
    local group g
    if u == target then
        call UnitAddAbility(u,'Ault')
        call SaveInteger(udg_hash,GetHandleId(u),StringHash("visiontime"),udg_TORCHLIFE)
        call DisplayTextToPlayer(GetOwningPlayer(u),0,0,"|cff00ff00You light your torch.|r")
    else
        set g = GetUnitsInRangeOfLocAll(200,l)
        set udg_tempunit = u
        call EnumDestructablesInCircleBJ(200,l, function burn_destructable)
        call ForGroup(g, function burn_unit)
    endif
    call DestroyGroup(g)
    set g = null
endfunction

function pilesnow takes unit u, location l returns nothing
    call GroupAddUnit(udg_snowpilers,u)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("pile_x"),GetLocationX(l))
    call SaveReal(udg_hash,GetHandleId(u),StringHash("pile_y"),GetLocationY(l))
endfunction

function shovelsnow takes unit u, location l returns nothing
    call GroupAddUnit(udg_snowshovelers,u)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("shovel_x"),GetLocationX(l))
    call SaveReal(udg_hash,GetHandleId(u),StringHash("shovel_y"),GetLocationY(l))
endfunction

function throwbolas takes unit u, location l returns nothing
    call GroupAddUnit(udg_bolas,u)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("target_x"),GetLocationX(l))
    call SaveReal(udg_hash,GetHandleId(u),StringHash("target_y"),GetLocationY(l))
endfunction

function firstaid takes unit caster, unit target returns nothing
    local unit u
    local unit ice
    if GetUnitTypeId(target) == 'h00L' then
        set ice = LoadUnitHandle(udg_hash,GetHandleId(target),StringHash("ice"))
        set u = CreateUnit(GetOwningPlayer(target),'h001',GetUnitX(target),GetUnitY(target), 0)
        call SelectUnitForPlayerSingle(u,GetOwningPlayer(target))
        call SetUnitState(u,UNIT_STATE_MANA,30)
        call SetUnitState(u,UNIT_STATE_LIFE,50)        
        call GroupAddUnit(udg_survivors,u)
        call FlushChildHashtable(udg_hash,GetHandleId(target))
        call FlushChildHashtable(udg_hash,GetHandleId(ice))
        call CreateUnit(Player(9),'h00M',GetUnitX(target),GetUnitY(target),0)
        call RemoveUnit(ice)
        call RemoveUnit(target)
        if GetPlayerTechResearched(GetOwningPlayer(target),'R009',false) then
            call GroupAddUnit(udg_skiiers,u)
            call UnitAddAbility(u,'Amrf')
            call UnitRemoveAbility(u,'Amrf')
            call SaveBoolean(udg_hash,GetHandleId(u),StringHash("isskiing"),true)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("vertical_velocity"),0)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("horizontal_acceleration"),0)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("inertia_theta"),bj_DEGTORAD*GetUnitFacing(u))
            call SaveReal(udg_hash,GetHandleId(u),StringHash("height"),0)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("inertia_force"),0)
            call StartSound(bj_questItemAcquiredSound)
        endif
    endif
endfunction

function throwboomerang takes unit u, location l returns nothing
    local location unit_l = GetUnitLoc(u)
    local real angle = AngleBetweenPoints(unit_l,l)*bj_DEGTORAD
    local unit new_u = CreateUnitAtLoc(GetOwningPlayer(u),'h00P',unit_l,GetUnitFacing(u))
    local real distance = DistanceBetweenPoints(l,unit_l)
    call SetUnitFlyHeight(new_u,GetLocationZ(unit_l)+100,0)
    call SetUnitScale(new_u,1,1,1)
    call SaveReal(udg_hash,GetHandleId(new_u),StringHash("horizontal_velocity"),Pow(distance,.4))
    call SaveReal(udg_hash,GetHandleId(new_u),StringHash("vertical_velocity"),Pow(distance,.2))
    call SaveReal(udg_hash,GetHandleId(new_u),StringHash("height"),GetLocationZ(unit_l)+100)
    call SaveReal(udg_hash,GetHandleId(new_u),StringHash("horizontal_angle"),angle)
    call SaveReal(udg_hash,GetHandleId(new_u),StringHash("age"),0)
    call SaveReal(udg_hash,GetHandleId(new_u),StringHash("rotation"),0)
    call GroupAddUnit(udg_boomerang,new_u)
    call RemoveLocation(unit_l)
endfunction

function cookallmeat takes unit u returns nothing
    // @param u: unit cooking the meat
    local integer ix = 0
    local integer capacity
    local item slotitem
    local item cookeditem
    loop
        exitwhen ix == UnitInventorySize(u)
        set slotitem = UnitItemInSlot(u,ix)
        if GetItemTypeId(slotitem) == 'I005' then // permanent version of raw meat
            set cookeditem = CreateItem('I008',GetUnitX(u),GetUnitY(u)) // powerup version of cooked meat    
            call SetItemCharges(cookeditem,GetItemCharges(slotitem))
            call RemoveItem(slotitem)
            call UnitAddItem(u,cookeditem)
        endif
        set ix = ix + 1  
    endloop
endfunction

function meat takes unit caster, unit target, integer id returns nothing
    // @param caster: unit using meat
    // @param target: unit receiving effect of meat
    // @param id: ability id of meat being used. The four types of meat each have different IDs
    local integer meat_charm // how likely the meat is to charm a unit
    local integer unit_charm // how likely the unit is to get charmed
    local integer charm_total = LoadInteger(udg_hash,GetHandleId(target),StringHash("charm_total"))
    local real meat_heal
    local string msg
    local integer fx
    if id == 'A00N' then // raw meat
        set meat_charm = 3
        set meat_heal = 30
        set msg = "The raw meat tastes disgusting."
        set fx = 'h00T'
    elseif id == 'A00O' then // cooked meat
        set meat_charm = 5
        set meat_heal = 50
        set msg = "|cff00ff00This cooked meat is delicious.|r"
        set fx = 'h00T'
    elseif id == 'A00P' then // burned meat
        set meat_charm = 2
        set meat_heal = 20
        set msg = "The burnt meat leaves a bitter taste in your mouth."
        set fx = 'h00T'
    elseif id == 'A010' then // poisoned meat
        set meat_charm = 0
        set meat_heal = -100
        set msg = "|cffff4040This meat is poisoned! You feel sick.|r"
        set fx = 'h01G'
    endif
    if target == caster then
        call SetUnitState(target,UNIT_STATE_LIFE, GetUnitState(target,UNIT_STATE_LIFE)+meat_heal)
        call CreateUnit(GetOwningPlayer(target),fx,GetUnitX(target),GetUnitY(target),0)
        call DisplayTextToPlayer(GetOwningPlayer(caster),0,0,msg)
    elseif IsUnitInGroup(caster,udg_survivors) then
        if IsUnitInGroup(target, udg_carngroup) then // try to charm animal
            if GetUnitTypeId(target) == 'n002' then // raccoon
                set unit_charm = 8
            elseif GetUnitTypeId(target) == 'n001' then // wolf
                set unit_charm = 24
            elseif GetUnitTypeId(target) == 'n005' then // bear
                set unit_charm = 48
            endif
            if (GetRandomInt(0,unit_charm) < meat_charm + charm_total) then // if you can't convince it this time, try again later wil work maybe
                call SetUnitOwner(target,GetOwningPlayer(caster),true)
                call DisplayTextToPlayer(GetOwningPlayer(caster),0,0,"|cff00ff00You befriend the "+GetUnitName(target)+"!|r")
                call CreateUnit(GetOwningPlayer(caster),'h00V',GetUnitX(target),GetUnitY(target),0)
            else
                call SaveInteger(udg_hash,GetHandleId(target),StringHash("charm_total"),unit_charm + charm_total)
                call DisplayTextToPlayer(GetOwningPlayer(caster),0,0,"|cffffff00You intrigue the "+GetUnitName(target)+".|r")
                call SaveReal(udg_hash,GetHandleId(target),StringHash("agitation"),0)
            endif
        elseif (GetUnitTypeId(target) == 'h002') or (GetUnitTypeId(target) == 'h00R') or (GetUnitTypeId(target) == 'h008') then // try to burn meat
            if id == 'A00N' then
                call cookallmeat(caster)
                call DisplayTextToPlayer(GetOwningPlayer(caster),0,0,"|cff00ff00The meat cooks!|r")    
            elseif (id == 'A00O') or (id == 'A010') then // cooked and poisoned meat both burn
                call CreateItem('I00A',GetUnitX(caster),GetUnitY(caster))
                call DisplayTextToPlayer(GetOwningPlayer(caster),0,0,"|cffff0000The meat burns.|r")
            elseif (id == 'A00P') then
                call CreateItem('I00A',GetUnitX(caster),GetUnitY(caster))
                call DisplayTextToPlayer(GetOwningPlayer(caster),0,0,"|cffff0000The meat burns, again.|r")
            endif
            call CreateUnit(GetOwningPlayer(caster),'h00U',GetUnitX(caster),GetUnitY(caster),0) // burn effect
            call PlaySoundOnUnitBJ(gg_snd_burn,100,caster)
        else
            if id == 'A00N' then
                call CreateItem('I006',GetUnitX(target),GetUnitY(target))    
            elseif id == 'A00O' then
                call CreateItem('I008',GetUnitX(target),GetUnitY(target))
            elseif id == 'A00P' then
                call CreateItem('I00A',GetUnitX(target),GetUnitY(target))
            elseif id == 'A010' then
                call CreateItem('I00N',GetUnitX(target),GetUnitY(target))
            endif
            call DisplayTextToPlayer(GetOwningPlayer(caster),0,0,"|cffffff00Meat does nothing to a "+GetUnitName(target)+".|r")
            call CreateUnit(GetOwningPlayer(caster),'h00W',GetUnitX(caster),GetUnitY(caster),0) // blood effect
        endif
    else
        if id == 'A00N' then
            call CreateItem('I006',GetUnitX(target),GetUnitY(target))    
        elseif id == 'A00O' then
            call CreateItem('I008',GetUnitX(target),GetUnitY(target))
        elseif id == 'A00P' then
            call CreateItem('I00A',GetUnitX(target),GetUnitY(target))
        elseif id == 'A010' then
            call CreateItem('I00N',GetUnitX(target),GetUnitY(target))
        endif
        call DisplayTextToPlayer(GetOwningPlayer(caster),0,0,"|cffffff00"+GetUnitName(caster)+" can't use the meat on "+GetUnitName(target)+".|r")
    endif
endfunction

function removearrow takes unit u returns boolean
    local integer itemkey = 'I002' // arrows
    local integer remainingcharges = 1 // only takes one arrow
    local integer thisitemscharges
    local integer ix = 0
    local item inventoryitem
    loop
        exitwhen ix == UnitInventorySize(u)
        exitwhen remainingcharges == 0
        set inventoryitem = UnitItemInSlot(u,ix)
        if GetItemTypeId(inventoryitem) == itemkey then
            set thisitemscharges = GetItemCharges(inventoryitem)
            if thisitemscharges > remainingcharges then
                call SetItemCharges(inventoryitem,thisitemscharges-remainingcharges)
                set remainingcharges = 0
            else
                call RemoveItem(inventoryitem)
                set remainingcharges = remainingcharges - thisitemscharges
            endif
        endif
        set ix = ix + 1
    endloop
    if remainingcharges > 0 then
        call DisplayTextToPlayer(GetOwningPlayer(u),0,0,"Out of Arrows")
        call IssueImmediateOrder(u,"stop")
        return false
    endif
    return true
endfunction

function raiselower takes unit u returns nothing
    call CreateUnit(Player(0),'h01A',GetUnitX(u),GetUnitY(u),0)
    call PlaySoundOnUnitBJ(gg_snd_grumble,100,u)
endfunction
   
function headshot takes unit shooter, unit target returns nothing
    local real angle = Atan2(GetUnitY(target)-GetUnitY(shooter),GetUnitX(target)-GetUnitX(shooter))
    if removearrow(shooter) == true then
        call SaveReal(udg_hash,GetHandleId(target),StringHash("shot_angle"),angle)
        call SaveReal(udg_hash,GetHandleId(target),StringHash("shot_amount"),10)
        call CreateUnit(GetOwningPlayer(shooter),'h00W',GetUnitX(target),GetUnitY(target),0) // blood effect    
        call GroupAddUnit(udg_shot,target)
        call say("headshot!",target,100,0,0)
        call UnitDamageTarget(shooter,target,50,false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_NORMAL,null)
        call PlaySoundOnUnitBJ(gg_snd_arrow,100,target)
    endif
endfunction

function upgradesurvivor takes unit u returns nothing
    local integer ix = GetPlayerId(GetOwningPlayer(u))
    call SelectUnitForPlayerSingle(udg_survivorupgradebuilding[ix],GetOwningPlayer(u))
endfunction

function Trig_start_spells_Actions takes nothing returns nothing
    local location l
    local location u_l = GetUnitLoc(GetTriggerUnit())
    local unit u
    if GetSpellAbilityId() == 'A007' then
        set l = GetSpellTargetLoc()
        set u = GetSpellTargetUnit()
        call burn(GetTriggerUnit(),l,u)
    elseif GetSpellAbilityId() == 'A00C' then
        set l = GetSpellTargetLoc()
        call pilesnow(GetTriggerUnit(),l)
    elseif GetSpellAbilityId() == 'A00E' then
        set l = GetSpellTargetLoc()
        call shovelsnow(GetTriggerUnit(),l)
    elseif GetSpellAbilityId() == 'A00G' then
        set l = GetSpellTargetLoc()
        set u = CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()),'h00J',u_l,0)
        call throwbolas(u,l)
    elseif GetSpellAbilityId() == 'A00J' then
        set u = GetSpellTargetUnit()
        call firstaid(GetTriggerUnit(),u)
    elseif GetSpellAbilityId() == 'A00K' then
        set l = GetSpellTargetLoc()
        call throwboomerang(GetTriggerUnit(),l)
    elseif (GetSpellAbilityId() == 'A00N') or(GetSpellAbilityId() == 'A00O') or(GetSpellAbilityId() == 'A00P') or(GetSpellAbilityId() == 'A010') then
        set u = GetSpellTargetUnit()
        call meat(GetTriggerUnit(),u,GetSpellAbilityId())
    elseif GetSpellAbilityId() == 'A00R' then
        call headshot(GetTriggerUnit(),GetSpellTargetUnit())
    elseif GetSpellAbilityId() == 'A00Y' then
        call raiselower(GetTriggerUnit())
    elseif GetSpellAbilityId() == 'A00Z' then
        call upgradesurvivor(GetTriggerUnit())
     
    endif
    call RemoveLocation(l)
    call RemoveLocation(u_l)
    set l = null
    set u_l = null
       
endfunction

//===========================================================================
function InitTrig_start_spells takes nothing returns nothing
    set gg_trg_start_spells = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_start_spells, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_start_spells, function Trig_start_spells_Actions )
endfunction
function add_chain takes unit master, boolean end, real length, real strength, real x, real y, integer chaintype returns unit
    local unit slave = CreateUnit(Player(0),chaintype,x,y,0)
    call SaveUnitHandle(udg_hash,GetHandleId(master),StringHash("slave"),slave)
    call SaveUnitHandle(udg_hash,GetHandleId(slave),StringHash("master"),master)
    call SaveReal(udg_hash,GetHandleId(slave),StringHash("tipx"),x)      
    call SaveReal(udg_hash,GetHandleId(slave),StringHash("tipy"),y)
    call SaveReal(udg_hash,GetHandleId(slave),StringHash("basex"),x)
    call SaveReal(udg_hash,GetHandleId(slave),StringHash("basey"),y)
    call SaveReal(udg_hash,GetHandleId(slave),StringHash("length"),length)
    call SaveReal(udg_hash,GetHandleId(slave),StringHash("strength"),strength)
    call SaveBoolean(udg_hash,GetHandleId(slave),StringHash("end"),end)
    call SaveBoolean(udg_hash,GetHandleId(slave),StringHash("start"),false)
    //call BJDebugMsg(I2S(GetHandleId(slave))+" is chained to "+I2S(GetHandleId(master)))
    return slave            
endfunction

function chainunit takes unit u, integer links, real length, real strength, real anchorx, real anchory, integer chaintype returns nothing
    local unit next_u
    call GroupAddUnit(udg_chained,u)
    //call BJDebugMsg("main unit is "+I2S(GetHandleId(u)))
    call SaveBoolean(udg_hash,GetHandleId(u),StringHash("start"),true)
    call SaveBoolean(udg_hash,GetHandleId(u),StringHash("end"),false)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("basex"),anchorx)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("basey"),anchory)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("anchorx"),anchorx)
    call SaveReal(udg_hash,GetHandleId(u),StringHash("anchory"),anchory)
    loop
        exitwhen links == 0
        set next_u = add_chain(u,false,length,strength,anchorx,anchory,chaintype)
        set u = next_u
        set links = links - 1
    endloop
    call add_chain(next_u,true,length,strength,anchorx,anchory,chaintype)

    //call BJDebugMsg("added everyone")  
endfunction

function Trig_snare_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit snare = GetEventDamageSource()
    local real strength
    local integer links
    local integer chaintype
    if IsUnitInGroup(u,udg_chained) == false then
        if GetUnitTypeId(snare) == 'h010' then   // basic
            set strength = 1000
            set links = 3
            set chaintype = 'h00Z'
        elseif GetUnitTypeId(snare) == 'h012' then   // strong
            set strength = 10000
            set links = 3
            set chaintype = 'h015'
        elseif GetUnitTypeId(snare) == 'h013' then   // wide
            set strength = 1000
            set links = 6    
            set chaintype = 'h00Z'
        elseif GetUnitTypeId(snare) == 'h014' then   // wide
            set strength = 10000
            set links = 6
            set chaintype = 'h015'
        else
            set strength = 0
            set links = 0
        endif
        if strength != 0 then
            call chainunit(u,links,32,strength,GetUnitX(snare),GetUnitY(snare),chaintype) // unit, links, length, strength, x & y of anchor
            call CreateUnit(Player(11),'h011',GetUnitX(snare),GetUnitY(snare),0)
            call PingMinimapForPlayer(GetOwningPlayer(snare),GetUnitX(snare),GetUnitY(snare),1)
            call PlaySoundOnUnitBJ(gg_snd_trap,100,u)
            call RemoveUnit(snare)
        endif
    endif
   
endfunction


//===========================================================================
function InitTrig_snare takes nothing returns nothing
    set gg_trg_snare = CreateTrigger(  )
    call TriggerAddAction( gg_trg_snare, function Trig_snare_Actions )
endfunction
 
pincer
  Events
  Conditions
  Actions
function enumusebolas takes nothing returns nothing
    local integer uid = GetUnitTypeId(GetEnumUnit())
    local integer sid
    local unit u
    if (uid == 'n000')or(uid == 'n003')or(uid == 'n002')or(uid == 'n001') then
        set sid = 'A00I'
    else
        set sid = 'A00H'
    endif
    set u = CreateUnit(GetOwningPlayer(GetEnumUnit()),'h00I',GetUnitX(GetEnumUnit()),GetUnitY(GetEnumUnit()),0)
    call UnitApplyTimedLife(u,'BTLF',2)
    call UnitAddAbility(u,sid)
    call IssueTargetOrder(u,"ensnare",GetEnumUnit())
endfunction

function usebolas takes real x, real y returns nothing
    local group g
    local location l = Location(x,y)
    set g = GetUnitsInRangeOfLocAll(200,l)
    call ForGroup(g, function enumusebolas)
    call DestroyGroup(g)
    call RemoveLocation(l)
    set g = null
    set l = null  
endfunction

function movebolas takes nothing returns nothing
    local real target_x = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("target_x"))
    local real target_y = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("target_y"))
    local real x = GetUnitX(GetEnumUnit())
    local real y = GetUnitY(GetEnumUnit())
    local real angle = Atan2(target_y - y, target_x - x)
    local real distance = SquareRoot(Pow(target_x-x,2)+Pow(target_y-y,2))
    local real d_x = Cos(angle)*11
    local real d_y = Sin(angle)*11
    if distance < 12 then
        call usebolas(target_x,target_y)
        call GroupRemoveUnit(udg_bolas,GetEnumUnit())
        call FlushChildHashtable(udg_hash,GetHandleId(GetEnumUnit()))
        call RemoveUnit(GetEnumUnit())        
    else
        call SetUnitPosition(GetEnumUnit(),x+d_x,y+d_y)
    endif
endfunction

function removeboomerang takes unit u returns nothing
    call CreateItem('I00I',GetUnitX(u),GetUnitY(u))
    call FlushChildHashtable(udg_hash,GetHandleId(u))
    call RemoveUnit(u)
endfunction

function AngleDifference takes real a1, real a2 returns real
 local real x
    set a1=ModuloReal(a1,360)
    set a2=ModuloReal(a2,360)
    if a1>a2 then
        set x=a1
        set a1=a2
        set a2=x
    endif
    set x=a2-360
    if a2-a1 > a1-x then
        set a2=x
    endif
 return RAbsBJ(a1-a2)
endfunction

function enumcheckcollisions takes nothing returns nothing
    local real age
    local unit u
    if IsUnitDeadBJ(GetEnumUnit()) then
    elseif (GetUnitTypeId(GetEnumUnit()) == 'h001') or (GetUnitTypeId(GetEnumUnit()) == 'h004') then
        set age = LoadReal(udg_hash,GetHandleId(udg_tempunit),StringHash("age"))
        if  age > 40 then
            call UnitAddItemById(GetEnumUnit(),'I00I')
            call FlushChildHashtable(udg_hash,GetHandleId(udg_tempunit))
            call RemoveUnit(udg_tempunit)
        endif
    elseif GetUnitTypeId(GetEnumUnit()) == 'h00P' then
    else
        call DisplayTextToForce(GetPlayersAll(),GetUnitName(GetEnumUnit()))
        set u = CreateUnit(Player(8),'h00I',GetUnitX(GetEnumUnit()),GetUnitY(GetEnumUnit()),0)  
        call UnitApplyTimedLife(u,'BTLF',2)
        call UnitAddAbility(u,'A00L')
        call IssueTargetOrder(u,"thunderbolt",GetEnumUnit())
        call FlushChildHashtable(udg_hash,GetHandleId(udg_tempunit))
        call RemoveUnit(udg_tempunit)
    endif
       
endfunction

function checkcollisions takes unit u returns nothing
    local location l = GetUnitLoc(u)
    local group g = GetUnitsInRangeOfLocAll(90,l)
    set udg_tempunit = u
    call ForGroup(g,function enumcheckcollisions)
    call DestroyGroup(g)
    call RemoveLocation(l)
endfunction

function moveboomerang takes nothing returns nothing
    local real x = GetUnitX(GetEnumUnit())
    local real y = GetUnitY(GetEnumUnit())
    local real d_x
    local real d_y
    local real horizontal_velocity = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("horizontal_velocity"))
    local real horizontal_angle = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("horizontal_angle"))
    local real vertical_velocity = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("vertical_velocity"))
    local real height = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("height"))
    local real rotation = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("rotation"))
    local real turnangle = -bj_DEGTORAD*5/horizontal_velocity
    local real angular_velocity = 2
    local real new_rotation
    local location l
    set vertical_velocity = vertical_velocity - udg_GRAVITY
    set height = vertical_velocity + height
    set horizontal_velocity = horizontal_velocity - Pow(horizontal_velocity,2)*udg_WINDRESISTANCE*.001
    set horizontal_angle = horizontal_angle - turnangle
    set d_x = Cos(horizontal_angle)*horizontal_velocity
    set d_y = Sin(horizontal_angle)*horizontal_velocity
    call SetUnitPosition(GetEnumUnit(),x+d_x,y+d_y)
    set l = GetUnitLoc(GetEnumUnit())
    call SetUnitFlyHeight(GetEnumUnit(),height - GetLocationZ(l),0)
    set new_rotation = ModuloReal(rotation + angular_velocity,360)
    call SetUnitFacing(GetEnumUnit(),new_rotation)
    call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("horizontal_velocity"),horizontal_velocity)
    call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("horizontal_angle"),horizontal_angle)
    call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("vertical_velocity"),vertical_velocity)
    call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("height"),height)
    call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("rotation"),new_rotation)
    call checkcollisions(GetEnumUnit())
    if height < GetLocationZ(l) then
        call removeboomerang(GetEnumUnit())
    endif
    call RemoveLocation(l)
    //if ModuloReal(age,3) == 0 then
    //    call createblur(GetEnumUnit())
    //endif
endfunction

function moveshot takes nothing returns nothing
    // move units that have been headshot by an arrow
    local real x = GetUnitX(GetEnumUnit())
    local real y = GetUnitY(GetEnumUnit())
    local real angle = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("shot_angle"))
    local real velocity = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("shot_amount"))
    local real d_x = Cos(angle) * velocity
    local real d_y = Sin(angle) * velocity
    call SetUnitPosition(GetEnumUnit(),x+d_x,y+d_y)
    set velocity = velocity - 1
    if velocity <= 0 then
        call GroupRemoveUnit(udg_shot,GetEnumUnit())
    else
        call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("shot_amount"),velocity)
    endif
endfunction

function removechain takes unit chain returns nothing
    local unit slave = LoadUnitHandle(udg_hash,GetHandleId(chain),StringHash("slave"))
    local boolean end = LoadBoolean(udg_hash,GetHandleId(chain),StringHash("end"))
    call FlushChildHashtable(udg_hash,GetHandleId(chain))
    call RemoveUnit(chain)
    set chain = null
    if end != true then
        call removechain(slave)
    endif
endfunction

function backpull takes unit chain returns nothing
    local unit master = LoadUnitHandle(udg_hash,GetHandleId(chain),StringHash("master"))
    local unit slave = LoadUnitHandle(udg_hash,GetHandleId(chain),StringHash("slave"))
    local real masterx = LoadReal(udg_hash,GetHandleId(master),StringHash("basex"))
    local real mastery = LoadReal(udg_hash,GetHandleId(master),StringHash("basey"))
    local real tipx = LoadReal(udg_hash,GetHandleId(chain),StringHash("tipx"))      
    local real tipy = LoadReal(udg_hash,GetHandleId(chain),StringHash("tipy"))
    local real basex = LoadReal(udg_hash,GetHandleId(chain),StringHash("basex"))
    local real basey = LoadReal(udg_hash,GetHandleId(chain),StringHash("basey"))
    local real length = LoadReal(udg_hash,GetHandleId(chain),StringHash("length"))
    local boolean start = LoadBoolean(udg_hash,GetHandleId(chain),StringHash("start"))
    local real dist
    local real angle
    local real strength
    if start != true then
        set angle = Atan2(-basey+tipy,-basex+tipx)
        set tipx = basex + length*Cos(angle)
        set tipy = basey + length*Sin(angle)
        set masterx = tipx
        set mastery = tipy
        call SaveReal(udg_hash,GetHandleId(chain),StringHash("tipx"),tipx)
        call SaveReal(udg_hash,GetHandleId(chain),StringHash("tipy"),tipy)
        call SaveReal(udg_hash,GetHandleId(master),StringHash("basex"),masterx)
        call SaveReal(udg_hash,GetHandleId(master),StringHash("basey"),mastery)
        call SetUnitFacing(chain,bj_RADTODEG*angle)
        call backpull(master)
    else
        set dist = SquareRoot(Pow(GetUnitX(chain)-basex,2)+Pow(GetUnitY(chain)-basey,2))
        if dist > 30 then // tug on the rope
            set strength = LoadReal(udg_hash,GetHandleId(slave),StringHash("strength"))
            set strength = strength - GetUnitState(chain,UNIT_STATE_MAX_LIFE)
            if strength < 0 then
                call removechain(slave)
                call GroupRemoveUnit(udg_chained,chain)
                call say("free!",chain,100,100,100)
            else
                call SetUnitPosition(chain,basex,basey)
                call SaveReal(udg_hash,GetHandleId(slave),StringHash("strength"),strength)
            endif    
        endif
    endif    
endfunction

function pull takes unit chain returns nothing
    local unit master = LoadUnitHandle(udg_hash,GetHandleId(chain),StringHash("master"))
    local unit slave = LoadUnitHandle(udg_hash,GetHandleId(chain),StringHash("slave"))
    local real masterx = LoadReal(udg_hash,GetHandleId(master),StringHash("basex"))
    local real mastery = LoadReal(udg_hash,GetHandleId(master),StringHash("basey"))
    local real tipx = LoadReal(udg_hash,GetHandleId(chain),StringHash("tipx"))      
    local real tipy = LoadReal(udg_hash,GetHandleId(chain),StringHash("tipy"))
    local real basex = LoadReal(udg_hash,GetHandleId(chain),StringHash("basex"))
    local real basey = LoadReal(udg_hash,GetHandleId(chain),StringHash("basey"))
    local real length = LoadReal(udg_hash,GetHandleId(chain),StringHash("length"))
    local boolean end = LoadBoolean(udg_hash,GetHandleId(chain),StringHash("end"))
    local real angle
    set tipx = masterx
    set tipy = mastery
    call SaveReal(udg_hash,GetHandleId(chain),StringHash("tipx"),tipx)
    call SaveReal(udg_hash,GetHandleId(chain),StringHash("tipy"),tipy)
    if end == false then
        set angle = Atan2(-tipy+basey,-tipx+basex)
        set basex = tipx + length*Cos(angle)
        set basey = tipy + length*Sin(angle)
        call SaveReal(udg_hash,GetHandleId(chain),StringHash("basex"),basex)
        call SaveReal(udg_hash,GetHandleId(chain),StringHash("basey"),basey)
        call pull(slave)
    else
        call backpull(chain)
    endif    
endfunction

function movechain takes unit chain returns nothing
    local unit slave
    local real tipx = LoadReal(udg_hash,GetHandleId(chain),StringHash("tipx"))      
    local real tipy = LoadReal(udg_hash,GetHandleId(chain),StringHash("tipy"))
    local real basex = LoadReal(udg_hash,GetHandleId(chain),StringHash("basex"))
    local real basey = LoadReal(udg_hash,GetHandleId(chain),StringHash("basey"))
    local boolean end = LoadBoolean(udg_hash,GetHandleId(chain),StringHash("end"))
    call SetUnitPosition(chain,(tipx+basex)/2,(tipy+basey)/2)
    if end == false then
        set slave = LoadUnitHandle(udg_hash,GetHandleId(chain),StringHash("slave"))
        call movechain(slave)
    endif
endfunction    

function startmovechain takes nothing returns nothing
    // slave is the first link
    local unit slave = LoadUnitHandle(udg_hash,GetHandleId(GetEnumUnit()),StringHash("slave"))
    call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("basex"),GetUnitX(GetEnumUnit()))
    call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("basey"),GetUnitY(GetEnumUnit()))
    call pull(slave)
    call movechain(slave)
endfunction

function Trig_fastpump_spell_Actions takes nothing returns nothing
    call ForGroup(udg_bolas, function movebolas)
    call ForGroup(udg_boomerang, function moveboomerang)
    call ForGroup(udg_shot, function moveshot)
    call ForGroup(udg_chained, function startmovechain)
endfunction

//===========================================================================
function InitTrig_fastpump_spell takes nothing returns nothing
    set gg_trg_fastpump_spell = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_fastpump_spell, 0.02 )
    call TriggerAddAction( gg_trg_fastpump_spell, function Trig_fastpump_spell_Actions )
endfunction
function Trig_end_spell_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    if GetSpellAbilityId() == 'A00C' then
        call GroupRemoveUnit(udg_snowpilers,u)
    elseif GetSpellAbilityId() == 'A00E' then
        call GroupRemoveUnit(udg_snowshovelers,u)
    elseif GetSpellAbilityId() == 'A003' then // morph
        call ForGroup(udg_survivors,function upgrade2unitbling)
    elseif GetSpellAbilityId() == 'A00J' then // first aid
        call ForGroup(udg_survivors,function upgrade2unitbling)
    elseif GetSpellAbilityId() == 'A007' then
        call UnitResetCooldown(u)
    endif
endfunction

//===========================================================================
function InitTrig_end_spell takes nothing returns nothing
    set gg_trg_end_spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_end_spell, EVENT_PLAYER_UNIT_SPELL_ENDCAST )
    call TriggerAddAction( gg_trg_end_spell, function Trig_end_spell_Actions )
endfunction
function burntree_pump takes nothing returns nothing
    local integer age = LoadInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burningtreeage"))
    local destructable destruct
    local real x
    local real y
    local integer ix = 0
    set age = age - 1
    set destruct = LoadDestructableHandle(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burningtree"))
    set x = GetDestructableX(destruct)
    set y = GetDestructableY(destruct)
    call SaveInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burningtreeage"),age)
    if age == 5 then
        call SetTerrainType(x,y,'Ndrd',GetRandomInt(0,2),1,0)
    elseif age == 4 then
        call RemoveDestructable(destruct)
        set destruct = CreateDestructable('NTtw',x,y,0,1,GetRandomInt(0,9))
        call SaveDestructableHandle(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burningtree"),destruct)
        call SaveBoolean(udg_hash,GetHandleId(destruct),StringHash("onfire"),true)
    elseif age == 3 then
        call KillDestructable(destruct)
    elseif age == 2 then
        call DestroyEffect(LoadEffectHandle(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burningtreefx")))
    elseif age < 1 then
        call GroupRemoveUnit(udg_burning,GetEnumUnit())
        call RemoveDestructable(destruct)
        call RemoveUnit(GetEnumUnit())
    endif
endfunction

function burn_pump takes nothing returns nothing
    local integer age = LoadInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burningage"))
    set age = age - 1
    if age < 1 then
        call GroupRemoveUnit(udg_burning,GetEnumUnit())
        call DestroyEffect(LoadEffectHandle(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burning")))
    else
        call SaveInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("burningage"),age)
    endif
endfunction

function skispray_pump takes nothing returns nothing
    local unit u = GetEnumUnit()
    local real force_vector = LoadReal(udg_hash,GetHandleId(u),StringHash("force_vector"))
    if force_vector < .1 then
        call SetTerrainType(GetUnitX(u),GetUnitY(u),'Nsnw',7,1,0)
        call GroupRemoveUnit(udg_skispray,u)
        call FlushChildHashtable(udg_hash,GetHandleId(u))  
    endif
    call SaveReal(udg_hash,GetHandleId(u),StringHash("force_vector"),force_vector - .1)  
endfunction

function shake_pump takes nothing returns nothing
    local real shaking = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("shaking"))
    set shaking = shaking - 1
    //call DisplayTextToForce(GetPlayersAll(),R2S(shaking))
    call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("shaking"),shaking)
    if shaking < 0 then
        call CameraClearNoiseForPlayer(GetOwningPlayer(GetEnumUnit()))
        call GroupRemoveUnit(udg_shakers,GetEnumUnit())
    endif
endfunction

function snowpile_pump takes nothing returns nothing
    local real x = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("pile_x"))
    local real y = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("pile_y"))
    local location l = Location(x,y)
    //if GetLocationZ(l) < 275 then
        call TerrainDeformationCraterBJ(0,true,l,200,-50)
    //else      
    //    call GroupRemoveUnit(udg_snowpilers,GetEnumUnit())
    //endif
endfunction

function snowshovel_pump takes nothing returns nothing
    local real x = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("shovel_x"))
    local real y = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("shovel_y"))
    local location l = Location(x,y)
    //if GetLocationZ(l) > -275 then
        call TerrainDeformationCraterBJ(0,true,l,200,50)
    //else      
    //    call GroupRemoveUnit(udg_snowshovelers,GetEnumUnit())
    //endif
endfunction

function ultravision_pump takes nothing returns nothing
    local integer time = LoadInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("visiontime"))
    if time != null then
        if time < 2 then
            call DisplayTextToPlayer(GetOwningPlayer(GetEnumUnit()),0,0,"|cffff0000Your torch fades.|r")
            call UnitRemoveAbility(GetEnumUnit(),'Ault')
            call SaveInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("visiontime"),null)
        else
            set time = time - 1
            call SaveInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("visiontime"),time)
            //call BJDebugMsg("torch dwindles")
        endif
    endif
endfunction

function terrain_pump takes nothing returns nothing
    local real x = GetUnitX(GetEnumUnit())
    local real y = GetUnitY(GetEnumUnit())
    local integer id = GetUnitTypeId(GetEnumUnit())
    if (id == 'n005') or (id == 'h001') or (id == 'h004') then
        if IsUnitInGroup(GetEnumUnit(),udg_skiiers) == false then
            if (GetTerrainType(x,y) == 'Ndrt') then
                call SetTerrainType(x,y,'Ndrd',GetRandomInt(0,17),1,0)
            endif
            if (GetTerrainType(x,y) == 'Ngrs') then
                call SetTerrainType(x,y,'Ndrt',GetRandomInt(0,17),1,0)
            endif
            if (GetTerrainType(x,y) == 'Nsnw') or (GetTerrainType(x,y) == 'Isnw') then
                call SetTerrainType(x,y,'Ngrs',GetRandomInt(0,17),1,0)
            endif
        endif
    endif      
endfunction

function Trig_pump_spells_Actions takes nothing returns nothing
    call ForGroup(udg_burning, function burn_pump)
    call ForGroup(udg_burningtree, function burntree_pump)
    call ForGroup(udg_skispray, function skispray_pump)
    call ForGroup(udg_shakers, function shake_pump)
    call ForGroup(udg_snowpilers, function snowpile_pump)
    call ForGroup(udg_snowshovelers, function snowshovel_pump)
    call ForGroup(udg_survivors, function ultravision_pump)
    call ForGroup(udg_survivors, function terrain_pump)
    call ForGroup(udg_carngroup, function terrain_pump)
endfunction

//===========================================================================
function InitTrig_pump_spells takes nothing returns nothing
    set gg_trg_pump_spells = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_pump_spells, 1.01 )
    call TriggerAddAction( gg_trg_pump_spells, function Trig_pump_spells_Actions )
endfunction
yetispawn
  Events
    Time - Elapsed game time is 1020.00 seconds
  Conditions
  Actions
    Unit - Create 1.Yeti for Player 12 (Brown) at (Center of yetispawn <gen>) facing Default building facing degrees
    Unit Group - Add (Last created unit) to carngroup
    Game - Display to (All players) the text: A fearsome howl echoes across the winter waste.
    Sound - Play Taunt <gen>
function Trig_addwolf_Actions takes nothing returns nothing
    local location l = GetRandomLocInRect(gg_rct_wolfzone)
    call spawnunit('n001',Player(11),l,0,0)
    call DisplayTextToForce(GetPlayersAll(),"A wolf howls at the moon.")
    call RemoveLocation(l)
    set l = null
endfunction

//===========================================================================
function InitTrig_addwolf takes nothing returns nothing
    set gg_trg_addwolf = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_addwolf, 300.00 )
    call TriggerAddAction( gg_trg_addwolf, function Trig_addwolf_Actions )
endfunction
function Trig_addbear_Actions takes nothing returns nothing
    local location l = GetRandomLocInRect(gg_rct_bearzone)
    call spawnunit('n005',Player(11),l,0,0)
    call DisplayTextToForce(GetPlayersAll(),"You hear the roar of a distant bear.")
    call RemoveLocation(l)
    set l = null
endfunction

//===========================================================================
function InitTrig_addbear takes nothing returns nothing
    set gg_trg_addbear = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_addbear, 555.00 )
    call TriggerAddAction( gg_trg_addbear, function Trig_addbear_Actions )
endfunction
function loseheat takes nothing returns nothing
    local real mana = GetUnitState(GetEnumUnit(),UNIT_STATE_MANA)
    if IsUnitLoaded(GetEnumUnit()) == true then
        call SetUnitState(GetEnumUnit(),UNIT_STATE_MANA,mana + 2)
    elseif GetTimeOfDay() < 6 then
        call SetUnitState(GetEnumUnit(),UNIT_STATE_MANA,mana - udg_NIGHTTIMEHEATLOSS)
    elseif GetTimeOfDay() > 18 then
        call SetUnitState(GetEnumUnit(),UNIT_STATE_MANA,mana - udg_NIGHTTIMEHEATLOSS)
    endif
    if (mana <= 0) and not IsUnitDeadBJ(GetEnumUnit()) then
        call say("Frozen",GetEnumUnit(),0,0,100)
        call KillUnit(GetEnumUnit())
    elseif (mana <= 10) then
        call say("Freezing",GetEnumUnit(),50,50,100)
    elseif (mana <= 30) then
        call say("Cold",GetEnumUnit(),100,100,100)      
    endif
endfunction

function Trig_heatloss_Actions takes nothing returns nothing
    call ForGroup(udg_survivors,function loseheat)
endfunction

//===========================================================================
function InitTrig_heatloss takes nothing returns nothing
    set gg_trg_heatloss = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_heatloss, 0.99 )
    call TriggerAddAction( gg_trg_heatloss, function Trig_heatloss_Actions )
endfunction
fadein fadeout
  Events
    Time - Every 60.00 seconds of game time
  Conditions
    (Random integer number between 1 and 10) Equal to 6
  Actions
    Cinematic - Apply a filter over 6.00 seconds using Normal blending on texture White Mask, starting with color (50.00%, 50.00%, 50.00%) and 100% transparency and ending with color (50.00%, 50.00%, 50.00%) and 50.00% transparency
    Wait 6.00 seconds
    Cinematic - Apply a filter over 6.00 seconds using Normal blending on texture White Mask, starting with color (50.00%, 50.00%, 50.00%) and 50.00% transparency and ending with color (100.00%, 100.00%, 100.00%) and 100.00% transparency
start blizzard chance
  Events
    Time - Elapsed game time is 600.00 seconds
  Conditions
  Actions
    Trigger - Turn on chance_of_blizzard <gen>
    Environment - Create at (Playable map area) the weather effect Northrend Blizzard
chance of blizzard
  Events
    Time - Every 60.00 seconds of game time
  Conditions
    blizzarding Equal to False
    (Random integer number between 1 and 10) Equal to 6
  Actions
    Cinematic - Apply a filter over 100.00 seconds using Normal blending on texture White Mask, starting with color (50.00%, 50.00%, 50.00%) and 100% transparency and ending with color (50.00%, 50.00%, 50.00%) and 0.00% transparency
    Countdown Timer - Start blizzard as a One-shot timer that will expire in 75.00 seconds
    Countdown Timer - Create a timer window for (Last started timer) with title Incoming Blizzard
    Environment - Turn (Last created weather effect) On
    Game - Display to (All players) the text: |cffff0000WARNING|r A blizzard approaches! Seek shelter or freeze!
    Set VariableSet blizzarding = True
blizzard comes
  Events
    Time - blizzard expires
  Conditions
  Actions
    Countdown Timer - Destroy (Last created timer window)
    Countdown Timer - Start blizzardhappens as a One-shot timer that will expire in 15.00 seconds
    Countdown Timer - Create a timer window for (Last started timer) with title Blizzard Ends
    Unit - Create 1.old man winter for Player 12 (Brown) at (Center of (Playable map area)) facing 270.00 degrees
    Environment - Change terrain type at (Center of (Playable map area)) to Northrend - Snow using variation -1 in an area of size 999999 and shape Circle
    Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            ((Unit-type of (Picked unit)) Equal to Bonfire) or ((Unit-type of (Picked unit)) Equal to Fire)
          Then - Actions
            Unit - Replace (Picked unit) with a Stick Pile using The old unit's relative life and mana
          Else - Actions
    Item - Pick every item in (Playable map area) and do (If ((Item-type of (Picked item)) Equal to Torch) then do (Remove (Picked item)) else do (Do nothing))
    Set VariableSet oldmanwinter = (Last created unit)
blizzard ends
  Events
    Time - blizzardhappens expires
  Conditions
  Actions
    Cinematic - Apply a filter over 5.00 seconds using Normal blending on texture White Mask, starting with color (50.00%, 50.00%, 50.00%) and 20.00% transparency and ending with color (100.00%, 100.00%, 100.00%) and 100.00% transparency
    Countdown Timer - Destroy (Last created timer window)
    Environment - Turn (Last created weather effect) Off
    Set VariableSet blizzarding = False
    Unit - Remove oldmanwinter from the game
function unitissurvivor takes unit u returns boolean
    if GetUnitTypeId(u) == 'h001' then
        return true
    elseif GetUnitTypeId(u) == 'h004' then
        return true
    endif
    return false
endfunction

function unitisanimal takes unit u returns boolean
    if GetUnitTypeId(u) == 'n000' then
        return true
    elseif GetUnitTypeId(u) == 'n001' then
        return true
    elseif GetUnitTypeId(u) == 'n002' then
        return true
    elseif GetUnitTypeId(u) == 'n003' then
        return true
    elseif GetUnitTypeId(u) == 'n004' then
        return true
    elseif GetUnitTypeId(u) == 'n005' then
        return true
    endif
    return false
endfunction
   
function makecorpse takes unit u returns nothing
    local integer charges = R2I(GetUnitState(u,UNIT_STATE_MAX_LIFE))
    local item food
    set food = CreateItem('I00L',GetUnitX(u),GetUnitY(u))
    call SetItemCharges(food,charges)
endfunction

function freezesurvivor takes unit u returns nothing
    local unit ice = CreateUnit(GetOwningPlayer(u),'h00K',GetUnitX(u),GetUnitY(u),0)
    local unit body = CreateUnit(GetOwningPlayer(u),'h00L',GetUnitX(u),GetUnitY(u),270)
    local unit skierwaypoint = LoadUnitHandle(udg_hash,GetHandleId(u),StringHash("waypoint"))
    call FlushChildHashtable(udg_hash,GetHandleId(skierwaypoint))
    call RemoveUnit(skierwaypoint)
    call SetUnitState(body,UNIT_STATE_MANA,GetUnitState(u,UNIT_STATE_MANA))
    call SaveUnitHandle(udg_hash,GetHandleId(body),StringHash("ice"),ice)
    call FlushChildHashtable(udg_hash,GetHandleId(u))
    call SelectUnitForPlayerSingle(body,GetOwningPlayer(u))    
endfunction

function removedeadchain takes unit chain returns nothing
    // note: another instance of this is in trigger "fast pump spell" as "removechain"
    local unit slave = LoadUnitHandle(udg_hash,GetHandleId(chain),StringHash("slave"))
    local boolean end = LoadBoolean(udg_hash,GetHandleId(chain),StringHash("end"))
    call FlushChildHashtable(udg_hash,GetHandleId(chain))
    call RemoveUnit(chain)
    if end != true then
        call removedeadchain(slave)
    endif
endfunction

function Trig_unitdies_Actions takes nothing returns nothing
    local item debris
    local integer pvalue
    local player owner
    local unit created
    local unit u = GetTriggerUnit()
    if IsUnitInGroup(GetTriggerUnit(),udg_chained) == true then
        call GroupRemoveUnit(udg_chained,GetTriggerUnit())
        call removedeadchain(GetTriggerUnit())
    endif
    if unitissurvivor(GetTriggerUnit()) == true then
        call freezesurvivor(GetTriggerUnit())
    elseif IsUnitType(GetTriggerUnit(),UNIT_TYPE_STRUCTURE) then
        //set pvalue = GetUnitPointValue(GetTriggerUnit())
        //if pvalue > 0 then
        //    set debris = CreateItem('I00K',GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()))
        //    call SetItemCharges(debris,pvalue)
        //endif
        // explode buildings
        if (GetUnitTypeId(GetTriggerUnit()) == 'h016') or(GetUnitTypeId(GetTriggerUnit()) == 'h017') then
            call CreateUnit(Player(0),'h018',GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()),0)
        endif
        if (GetUnitTypeId(GetTriggerUnit()) == 'h019') or(GetUnitTypeId(GetTriggerUnit()) == 'h00Q') then
            call CreateUnit(Player(0),'h01E',GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()),0)
        endif
       
    else
       
        if unitisanimal(GetTriggerUnit()) == true then
            call makecorpse(GetTriggerUnit())
            if (GetUnitTypeId(GetTriggerUnit()) == 'n005')or(GetUnitTypeId(GetTriggerUnit()) == 'n002')or(GetUnitTypeId(GetTriggerUnit()) == 'n001') then
                set owner = Player(11)
            else
                set owner = Player(10)
            endif
            call createanimal(GetUnitTypeId(GetTriggerUnit()),1,1,GetPlayerId(owner))

            //call GroupRemoveUnit(unit2group(GetUnitTypeId(GetTriggerUnit())),GetTriggerUnit())
            call GroupRemoveUnit(udg_herbgroup,GetTriggerUnit())
            call GroupRemoveUnit(udg_carngroup,GetTriggerUnit())
            call GroupRemoveUnit(udg_agitated,GetTriggerUnit())
            call GroupRemoveUnit(udg_shot,GetTriggerUnit())
            call GroupRemoveUnit(udg_burning,GetTriggerUnit())
        endif
        if GetUnitTypeId(GetTriggerUnit()) == 'n00E' then // yeti
            call makecorpse(GetTriggerUnit())
            set created = CreateUnit(Player(11),'n00E',GetRectCenterX(gg_rct_yetispawn),GetRectCenterY(gg_rct_yetispawn),0)
            call GroupAddUnit(udg_carngroup,created)
        endif
        if GetUnitTypeId(GetTriggerUnit()) == 'h009' then // dead survivor
            call makecorpse(GetTriggerUnit())
        endif    
        call FlushChildHashtable(udg_hash,GetHandleId(GetTriggerUnit()))
        //call RemoveUnit(GetTriggerUnit())
        //set u = null
    endif  
endfunction

//===========================================================================
function InitTrig_unitdies takes nothing returns nothing
    set gg_trg_unitdies = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_unitdies, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddAction( gg_trg_unitdies, function Trig_unitdies_Actions )
endfunction
function Trig_treedies_Actions takes nothing returns nothing
    local real x = GetDestructableX(GetTriggerDestructable())
    local real y = GetDestructableY(GetTriggerDestructable())
    if GetRandomInt(0,3) == 0 then
        call CreateItem('I00O',x,y)
        call CreateUnit(Player(0),'h011',x,y,0)
    endif
    //call DisplayTextToForce(GetPlayersAll(),"dead")
endfunction

//===========================================================================
function InitTrig_treedies takes nothing returns nothing
    set gg_trg_treedies = CreateTrigger(  )
    call TriggerAddAction( gg_trg_treedies, function Trig_treedies_Actions )
endfunction
crippletedrant
  Events
    Time - Every 30.00 seconds of game time
  Conditions
    (Random integer number between 1 and 2) Equal to 1
  Actions
    Custom script: set udg_ix = GetRandomInt(0,9)
    Floating Text - Create floating text that reads crippletedrants[ix] above crippleted with Z offset 0.00, using font size 10.00, color (100%, 100%, 0.00%), and 0% transparency
    Floating Text - Change (Last created floating text): Disable permanence
    Floating Text - Change the lifespan of (Last created floating text) to 10.00 seconds
function isitmeat takes integer itemid returns boolean
    if itemid == 'I006' then
        return true
    elseif itemid == 'I008' then
        return true
    elseif itemid == 'I00A' then
        return true
    elseif itemid == 'I00L' then
        return true
    elseif itemid == 'I00N' then
        return true  
    endif
    return false
endfunction

function nabmeat takes nothing returns nothing
    if udg_tempbool == false then // no food found yet
        if isitmeat(GetItemTypeId(GetEnumItem())) == true then
            if GetItemUserData(GetEnumItem()) != 2 then // meat isnt spoken for
                //if GetEnumItem() != null then
                    call SetItemUserData(GetEnumItem(),1) // claim the meat
                    call SaveItemHandle(udg_hash,GetHandleId(udg_tempunit),StringHash("claimedmeat"),GetEnumItem())
                    call IssueTargetItemOrder(udg_tempunit,"smart",GetEnumItem()) //go for the meat
                    set udg_tempbool = true // dont look for more meat
                    //call say(I2S(GetHandleId(GetEnumItem())),udg_tempunit,100,100,100)
                //endif
            endif
        endif
    endif
endfunction

function attackweakest takes nothing returns nothing
    if udg_tempbool == false then
        if (IsUnitInGroup(GetFilterUnit(),udg_herbgroup)) or (IsUnitInGroup(GetFilterUnit(),udg_survivors)) then
            call IssuePointOrder(udg_tempunit,"attack",GetUnitX(GetFilterUnit()),GetUnitY(GetFilterUnit()))
            set udg_tempbool = true
            //call say("|n|nattack",GetEnumUnit(),100,100,100)
        endif
    endif    
endfunction  

function nextmove takes unit u returns nothing
    local integer flight_threshold = LoadInteger(udg_hash,GetHandleId(u),StringHash("flight"))
    local integer agitation = LoadInteger(udg_hash,GetHandleId(u),StringHash("agitation"))
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local rect r = Rect(x-2000,y-2000,x+2000,y+2000)
    local item i = UnitItemInSlot(u,0)
    //local group g
    local item claimedmeat
    local location l
    if flight_threshold < agitation then // keep running
        //call say("run",GetEnumUnit(),100,100,100)
        set claimedmeat = LoadItemHandle(udg_hash,GetHandleId(u),StringHash("claimedmeat"))
        call SetItemUserData(claimedmeat,0) // if running, release claim on any meat you had
        if claimedmeat != null then
            //call say("|nreleasedmeat",GetEnumUnit(),100,100,100)
        endif
    else
        if i != null then
            //call say("eat",GetEnumUnit(),100,100,100)
            call UnitUseItemTarget(u,i,u)
        endif
        set udg_tempunit = u
        call EnumItemsInRect(r,Filter(function ReturnTrue),function nabmeat)// look for food
        if udg_tempbool == false then // no food found
            //call say("didnt find food",GetEnumUnit(),100,100,100)
            if (OrderId2String(GetUnitCurrentOrder(u)) != "smart") and (OrderId2String(GetUnitCurrentOrder(u)) != "attack") then
               
                call GroupEnumUnitsInRect(udg_dummygroup,r,Filter(function attackweakest))
                //set g = GetUnitsInRectMatching(r,null)// look for something to attack
                //call ForGroup(g, function attackweakest)
                //call DestroyGroup(g)
                //set g = null
                if udg_tempbool == false then // STILL havent found anything to do
                    //call say("|nfuck it",GetEnumUnit(),100,100,100)
                    set l = GetRandomLocInRect(GetPlayableMapRect())
                    call IssuePointOrderLoc(u,"attack",l)
                endif      
            endif
        endif
       
    endif
    set udg_tempbool = false
    call RemoveRect(r)
    set r = null
    call RemoveLocation(l)
    set l = null
    //set g = null
endfunction

function forpredators takes nothing returns nothing
    local integer pumpid = LoadInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("pumpid"))
    if pumpid != udg_pumpid then
        return
    else
        call nextmove(GetEnumUnit())
    endif
endfunction

function Trig_checkformeat_Actions takes nothing returns nothing
    call ForGroup(udg_carngroup,function forpredators)
endfunction

//===========================================================================
function InitTrig_checkformeat takes nothing returns nothing
    set gg_trg_checkformeat = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_checkformeat, .02 )
    call TriggerAddAction( gg_trg_checkformeat, function Trig_checkformeat_Actions )
endfunction
hashtable practice
  Events
    Unit - A unit owned by Player 1 (Red).Is issued an order targeting a point
  Conditions
  Actions
    Hashtable - Save Handle Of(Last started timer) as (Key asdf.) of (Key (Ordered unit).) in (Last created hashtable).
    Hashtable - Save 0 as 0 of (Key (Last created unit).) in (Last created hashtable).
    Unit - Kill (Load 0 of (Key (Owner of (Triggering unit)).) in (Last created hashtable).)
    Unit - Kill (Damage source)
    Unit - Order No unit to Human Mountain King - Storm Bolt.No unit
function GetMid takes real a1, real a2 returns real
 local real x
    set a1=ModuloReal(a1,360)
    set a2=ModuloReal(a2,360)
    if a1>a2 then
        set x=a1
        set a1=a2
        set a2=x
    endif
    set x=a2-360
    if a2-a1 > a1-x then
        set a2=x
    endif
 return (a1+a2)/2
endfunction

function scatter takes nothing returns nothing
    local unit u = GetFilterUnit()
    local unit damager = udg_tempunit
    local integer agitation = udg_tempint
    local real angle = LoadReal(udg_hash,GetHandleId(u),StringHash("escapeangle"))
    local real newangle = Atan2(GetUnitY(u)-GetUnitY(damager),GetUnitX(u)-GetUnitX(damager))
    local real mid = GetMid(angle*bj_RADTODEG,newangle*bj_RADTODEG)*bj_DEGTORAD
    if GetOwningPlayer(u) == GetOwningPlayer(damager) then
    else
        call agitate(u,agitation)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("escapeangle"),mid)
    endif
    set u = null
    set damager = null
endfunction

function agitate_neighbors takes unit u, unit damager, integer agitation returns nothing
    local integer rect_size = 500
    local rect r = Rect(GetUnitX(u)-rect_size,GetUnitY(u)-rect_size,GetUnitX(u)+rect_size,GetUnitY(u)+rect_size)
    set udg_tempunit = damager
    set udg_tempint = agitation
    call GroupEnumUnitsInRect(udg_dummygroup,r,Filter(function scatter))
    call RemoveRect(r)    
    set r = null
    set u = null
endfunction

function Trig_proximity_agitation_Actions takes nothing returns nothing
    local integer agitation = 0
    if GetUnitTypeId(GetEventDamageSource()) == 'n000' then // elk
        set agitation = agitation + 2
    elseif GetUnitTypeId(GetEventDamageSource()) == 'n005' then // bear
        set agitation = agitation + 20
    elseif GetUnitTypeId(GetEventDamageSource()) == 'n001' then // wolf
        set agitation = agitation + 10
    elseif GetUnitTypeId(GetEventDamageSource()) == 'n004' then // moose
        set agitation = agitation + 5
    elseif GetUnitTypeId(GetEventDamageSource()) == 'n003' then // rabbit
        set agitation = agitation + 0
    elseif GetUnitTypeId(GetEventDamageSource()) == 'n002' then // raccoon
        set agitation = agitation + 1
    elseif GetUnitTypeId(GetEventDamageSource()) == 'h001' then // axe survivor
        set agitation = agitation + 5
    elseif GetUnitTypeId(GetEventDamageSource()) == 'h004' then // bow survivor
        set agitation = agitation + 5
    elseif GetUnitTypeId(GetEventDamageSource()) == 'h002' then // fire
        set agitation = agitation + 5
    elseif GetUnitTypeId(GetEventDamageSource()) == 'h00R' then // bonfire
        set agitation = agitation + 10
    endif
    if IsUnitInGroup(GetTriggerUnit(),udg_survivors) then
    elseif GetOwningPlayer(GetEventDamageSource()) == GetOwningPlayer(GetTriggerUnit()) then
    else    
        set agitation = agitation + R2I(GetEventDamage())
        call agitate(GetEventDamageSource(),R2I(-GetEventDamage())) // hitting things relieves agitation
        call agitate_neighbors(GetTriggerUnit(),GetEventDamageSource(),agitation)
    endif
endfunction

//===========================================================================
function InitTrig_proximity_agitation takes nothing returns nothing
    set gg_trg_proximity_agitation = CreateTrigger(  )
    call TriggerAddAction( gg_trg_proximity_agitation, function Trig_proximity_agitation_Actions )
endfunction
 
function escape takes unit u, real angle returns real
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real dx = 500 * Cos(angle)
    local real dy = 500 * Sin(angle)
    local boolean valid = false
        loop
            exitwhen valid == true
            if RectContainsCoords(GetPlayableMapRect(),x+dx,y+dy) == true then
                set valid = true
            else
                set angle = angle + .5
                set dx = 500 * Cos(angle)
                set dy = 500 * Sin(angle)
            endif
        endloop      
    call IssuePointOrder(u,"move",x+dx,y+dy)
    return angle
endfunction

function Trig_alerted_pump_Func001002 takes nothing returns nothing
    local integer age = LoadInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("agitation"))
    local integer flight_threshold = LoadInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("flight"))
    local real angle = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("escapeangle"))
    local integer pumpid = LoadInteger(udg_hash,GetHandleId(GetEnumUnit()),StringHash("pumpid"))
    if pumpid != udg_pumpid then // a receives a pumpid (0-99) when it spawns
    else
        if (age > flight_threshold) and not (IsUnitInGroup(GetEnumUnit(),udg_survivors)) then
            //if GetUnitTypeId(GetEnumUnit()) == 'n003' then
                if GetRandomInt(0,9) == 0 then
                    //call say("juked",GetEnumUnit(),100,100,100)
                    set angle = angle+GetRandomInt(-100,100)*.01
                endif
            //endif
            set angle = escape(GetEnumUnit(),angle)
        endif
        call agitate(GetEnumUnit(),-20)
        //call say(R2S(age),GetEnumUnit(),100,100,100)
        if age < 1 then
            call GroupRemoveUnit(udg_agitated,GetEnumUnit())
        endif
        call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("escapeangle"),angle)
    endif
endfunction

function Trig_alerted_pump_Actions takes nothing returns nothing
    call ForGroupBJ(udg_agitated, function Trig_alerted_pump_Func001002)
    set udg_pumpid = ModuloInteger(udg_pumpid+1,100)
endfunction

//===========================================================================
function InitTrig_alerted_pump takes nothing returns nothing
    set gg_trg_alerted_pump = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_alerted_pump, .02 )
    call TriggerAddAction( gg_trg_alerted_pump, function Trig_alerted_pump_Actions )
endfunction
test proximity
  Events
    Unit - A unit Is attacked
  Conditions
  Actions
    Custom script: call DisplayTextToForce(GetPlayersAll(),"boo")
    Custom script: call agitate(GetTriggerUnit(),10)
    Unit - Order No unit to Hold Position.
    Unit - Create 1.Footman for Neutral Passive at (Center of (Playable map area)) facing Default building facing degrees
    Unit - Add a 60 second Generic expiration timer to (Triggering unit)
treatwood
  Events
    Unit - A unit Finishes training a unit
  Conditions
    (Unit-type of (Trained unit)) Equal to Treat Wood
  Actions
    Custom script: call say("+20",GetTrainedUnit(),0,100,0)
    Unit - Remove (Trained unit) from the game
    Player - Add 20 to (Triggering player).Current lumber
function itisafire takes unit u returns boolean
    if GetUnitTypeId(u) == 'h002' then
        return true
    elseif GetUnitTypeId(u) == 'h008' then
        return true
    elseif GetUnitTypeId(u) == 'h00R' then
        return true
    endif
    return false
endfunction

function unburned2burned takes integer unburned returns integer
    if unburned == 'I005' then   // permanent version of meat
        return 'I008' // powerup version of cooked meat
    elseif unburned == 'I007' then // permanent cooked meat
        return 'I00A' // powerup version of burned meat
    endif
    return 0
endfunction

function burnit takes unit u, item i returns nothing
    local integer unburned = GetItemTypeId(i)
    local integer burned = unburned2burned(unburned)
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local item newitem
    if burned != 0 then
        set newitem = CreateItem(burned,x,y)
        call SetItemCharges(newitem,GetItemCharges(i))
        call RemoveItem(i)
        //call DisplayTextToForce(GetPlayersAll(),"oh look i dropped it")
    endif    
endfunction

function itemkey2permkey takes integer itemkey returns integer
    // return the powerup item's permanent version
    if itemkey == 'I003' then // this is the powerup version of an arrow
        return 'I002'         // this is the permanent version of an arrow
    elseif itemkey == 'I004' then // this is the powerup version of 5 arrows
        return 'I002'             // permanent version of 1 arrow
    elseif itemkey == 'I006' then // powerup version of meat
        return 'I005'             // permanent version of meat
    elseif itemkey == 'I008' then // powerup version of cooked meat
        return 'I007'                 // permanent version of cooked meat
    elseif itemkey == 'I00A' then // powerup version of burned meat
        return 'I009'                 // permanent version of burned meat
    elseif itemkey == 'I00B' then // powerup version of torch
        return 'I001'                 // permanent version of torch
    elseif itemkey == 'I00G' then // powerup version of first aid kit
        return 'I00F'             // permanent version of first aid kit
    elseif itemkey == 'I00E' then // powerup version of bolas
        return 'I00D'             // permanent version of bolas
    elseif itemkey == 'I00I' then // powerup version of bolas
        return 'I00H'             // permanent version of bolas
    elseif itemkey == 'I00N' then // powerup version of poisoned meat
        return 'I00M'             // permanent version of poisoned meat
    elseif itemkey == 'I00O' then // powerup version of wolf lichen
        return 'I00P'             // permanent version of wolf lichen
    elseif itemkey == 'I00Q' then // powerup version of poisoned arrow
        return 'I00R'             // permanent version of poisoned arrow        
    endif
    return 0
endfunction

function player2maxcharges takes player p, integer itemkey, unit u returns integer
    // return the max charges of each item
    local integer researchlevel
    if GetUnitTypeId(u) == 'n005' then // bear
        return 10
    elseif GetUnitTypeId(u) == 'n001' then // wolf
        return 5
    elseif GetUnitTypeId(u) == 'n002' then // raccoon
        return 1    
    elseif itemkey == 'I002' then //arrow
        set researchlevel = GetPlayerTechCount(p,'R005',false) //quiver
        return researchlevel*5+5
    elseif itemkey == 'I00R' then // permanent poison arrow
        set researchlevel = GetPlayerTechCount(p,'R005',false) //quiver
        return researchlevel*5+5
    elseif itemkey == 'I005' then // permanent meat
        return 3
    elseif itemkey == 'I007' then // permanent cooked meat
        return 4
    elseif itemkey == 'I009' then // permanent burned meat
        return 5
    elseif itemkey == 'I001' then // permanent torch
        return 3
    elseif itemkey == 'I00D' then // permanent bolas
        return 3
    elseif itemkey == 'I00F' then // permanent first aid kit
        return 5
    elseif itemkey == 'I00H' then // permanent boomerang
        return 3
    elseif itemkey == 'I00M' then // permanent poisoned meat
        return 3
    elseif itemkey == 'I00P' then // permanent wolf lichen
        return 20
    endif
    return 1
endfunction

function itemkey2dropkey takes integer itemkey returns integer
    if itemkey == 'I003' then // 1 powerup arrow is picked up
        return 'I003'         // 1 powerup arrow drops
    elseif itemkey == 'I004' then // 5 powerup arrows are picked up
        return 'I003'             // 1 powerup arrow w/ 5 charges would be dropped  
    endif
    return itemkey
endfunction

function add_to_current_items takes unit u, integer permkey, integer maxcapacity, integer charges returns integer    
    // @param u: unit acquiring item
    // @param permkey: integer (ex. 'I000') that represents the permanent version of acquired item
    // @param maxcapacity: total charges per slot that a player can own (ex. 5 arrows per slot allowed)
    // @param charges: total charges of the item player receives (ex. picks up 10 arrows)
    local integer ix = 0
    local integer capacity
    local item slotitem
    loop
        exitwhen ix == UnitInventorySize(u)
        set slotitem = UnitItemInSlot(u,ix)
        set capacity = maxcapacity - GetItemCharges(slotitem)
        if (GetItemTypeId(slotitem) == permkey) and (capacity > 0) then
            if charges > capacity then
                call SetItemCharges(slotitem,maxcapacity)
                set charges = charges - capacity
            else
                call SetItemCharges(slotitem,GetItemCharges(slotitem)+charges)
                set charges = 0
            endif
        endif
        set ix = ix + 1  
    endloop
    return charges
endfunction

function fill_empty_slots takes unit u, integer permkey, integer maxcapacity, integer charges returns integer
    // @param u: unit acquiring item
    // @param permkey: integer (ex. 'I000') that represents the permanent version of acquired item
    // @param maxcapacity: total charges per slot that a player can own (ex. 5 arrows per slot allowed)
    // @param charges: total charges of the item player receives (ex. picks up 10 arrows)    
    local integer ix = 0
    local item slotitem
    local item dupeditem
    if permkey == 0 then
        return 0
    endif
    loop
        exitwhen ix == UnitInventorySize(u)
        set slotitem = UnitItemInSlot(u,ix)
        if (GetItemTypeId(slotitem) == null) and (charges > 0) then
            set dupeditem = CreateItem(permkey,GetUnitX(u),GetUnitY(u))
            call UnitAddItem(u,dupeditem)
            if maxcapacity > charges then
                call SetItemCharges(dupeditem,charges)
                set charges = 0
            else
                set charges = charges - maxcapacity
                call SetItemCharges(dupeditem,maxcapacity)
            endif
        endif
        set ix = ix + 1
    endloop
    return charges
endfunction

function item2resource takes unit u, item i returns nothing
    local item m
    local integer charges = R2I(Pow(GetItemCharges(i),.36)-3)
    local integer corpsegold = R2I(GetItemCharges(i)/50)
    local integer gold = GetPlayerState(GetOwningPlayer(u),PLAYER_STATE_RESOURCE_GOLD)
    if GetItemTypeId(i) == 'I00L' then
        call SetPlayerState(GetOwningPlayer(u),PLAYER_STATE_RESOURCE_GOLD,gold+corpsegold)
        call say("+"+I2S(corpsegold),u,100,80,0)
        set m = CreateItem('I006',GetUnitX(u),GetUnitY(u))
        call SetItemCharges(m,charges)
        call UnitAddItem(u,m)
    endif
endfunction

function Trig_stackitems_Actions takes nothing returns nothing
    local player p = GetOwningPlayer(GetTriggerUnit())
    local integer itemkey = GetItemTypeId(GetManipulatedItem())
    local integer permkey = itemkey2permkey(itemkey)
    local integer dropkey = itemkey2dropkey(itemkey)
    local integer maxitemcapacity = player2maxcharges(p,permkey,GetTriggerUnit())
    local integer remainingcharges = GetItemCharges(GetManipulatedItem())
    local item extraitem
    local location itempos = GetItemLoc(GetManipulatedItem())
    call item2resource(GetTriggerUnit(),GetManipulatedItem()) // special case if the item is a corpse or debris
    set remainingcharges = add_to_current_items(GetTriggerUnit(),permkey,maxitemcapacity,remainingcharges)
    set remainingcharges = fill_empty_slots(GetTriggerUnit(),permkey,maxitemcapacity,remainingcharges)
    if remainingcharges > 0 then
        set extraitem = CreateItem(dropkey,GetLocationX(itempos),GetLocationY(itempos))
        call SetItemCharges(extraitem,remainingcharges)
    endif      
    call RemoveLocation(itempos)
    set itempos = null
    if IsItemPowerup(GetManipulatedItem()) then
        call RemoveItem(GetManipulatedItem())
    endif
endfunction

//===========================================================================
function InitTrig_stackitems takes nothing returns nothing
    set gg_trg_stackitems = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_stackitems, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( gg_trg_stackitems, function Trig_stackitems_Actions )
endfunction

 
function permkey2itemkey takes integer permkey returns integer
    if permkey == 'I002' then // dropping a permanent arrow
        return 'I003' // it *reallY* drops a powerup arrow
    elseif permkey == 'I005' then // permanent meat
        return 'I006'         // powerup meat
    elseif permkey == 'I007' then // permanent cooked meat
        return 'I008'             // powerup cooked meat
    elseif permkey == 'I009' then // permanent burned meat
        return 'I00A'             // powerup burned meat
    elseif permkey == 'I001' then // permanent torch
        return 'I00B'             // powerup torch
    elseif permkey == 'I00F' then // permanent first aid kit
        return 'I00G'             // powerup first aid kit
    elseif permkey == 'I00D' then // permanent bolas
        return 'I00E'             // powerup bolas
    elseif permkey == 'I00H' then // permanent boomerang
        return 'I00I'             // powerup boomerang
    elseif permkey == 'I00M' then // permanent poisoned meat
        return 'I00N'             // powerup poisoned meat
    elseif permkey == 'I00P' then // permanent wolf lichen
        return 'I00O'             // powerup wolf lichen
    elseif permkey == 'I00R' then // permanent poison arrow
        return 'I00Q'             // powerup poison arrow
    endif
    return 0
endfunction

function Trig_dropitem_Actions takes nothing returns nothing
    local integer permkey = GetItemTypeId(GetManipulatedItem())
    local integer itemkey = permkey2itemkey(permkey)
    local integer permanentcharges
    local item permanent_is_now_a_powerup
    local location itempos
    set permanentcharges = GetItemCharges(GetManipulatedItem())
    if permkey != 0 then // if there exists an alternate form needing to be dropped
        call TriggerSleepAction(.01)
        if IsItemOwned(GetManipulatedItem()) == true then
             return
        endif
        set itempos = GetItemLoc(GetManipulatedItem())
        if GetItemCharges(GetManipulatedItem()) != 0 then
            call RemoveItem(GetManipulatedItem())
            set permanent_is_now_a_powerup = CreateItem(itemkey,GetLocationX(itempos),GetLocationY(itempos))
            call SetItemCharges(permanent_is_now_a_powerup,permanentcharges)        
            //call DisplayTextToForce(GetPlayersAll(),I2S(permanentcharges))
           
        endif
    endif
    call RemoveLocation(itempos)
    set itempos = null
endfunction

//===========================================================================
function InitTrig_dropitem takes nothing returns nothing
    set gg_trg_dropitem = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_dropitem, EVENT_PLAYER_UNIT_DROP_ITEM )
    call TriggerAddAction( gg_trg_dropitem, function Trig_dropitem_Actions )
endfunction
function ismeat takes item i returns boolean
    if (GetItemTypeId(i) == 'I005') or(GetItemTypeId(i) == 'I007') or (GetItemTypeId(i) == 'I009') then
        return true
    else
        return false
    endif
endfunction

function joinswappeditems takes unit u, item pickeditem, item targetitem returns nothing
    // note: place beneath the trigger "stackitems" because stack items has the function
    //       named "player2maxcharges"
    local integer maxcharges = player2maxcharges(GetOwningPlayer(u),GetItemTypeId(pickeditem),u)
    local integer pickedcharge = GetItemCharges(pickeditem)
    local integer targetcharge = GetItemCharges(targetitem)
    local item newitem
    if pickeditem == targetitem then
    elseif GetItemTypeId(pickeditem) == GetItemTypeId(targetitem) then
        if pickedcharge + targetcharge <= maxcharges then
            call SetItemCharges(targetitem, pickedcharge + targetcharge)
            call RemoveItem(pickeditem)
        else
            call SetItemCharges(pickeditem, maxcharges)
            call SetItemCharges(targetitem,pickedcharge+targetcharge - maxcharges)
        endif
    elseif (GetItemTypeId(pickeditem) == 'I00P') and ismeat(targetitem) then
        if pickedcharge < 1 then
            call RemoveItem(pickeditem)
        else
            call SetItemCharges(pickeditem,pickedcharge-1)
        endif
        call RemoveItem(targetitem)
        set newitem = CreateItem('I00M',GetUnitX(u),GetUnitY(u))
        call SetItemCharges(newitem,targetcharge)
        call UnitAddItem(u,newitem)
        call CreateUnit(Player(0),'h01G',GetUnitX(u),GetUnitY(u),0)      
    elseif (GetItemTypeId(pickeditem) == 'I00P') and (GetItemTypeId(targetitem) == 'I002') then
        if pickedcharge < 1 then
            call RemoveItem(pickeditem)
        else
            call SetItemCharges(pickeditem,pickedcharge-1)
        endif
        call RemoveItem(targetitem)
        set newitem = CreateItem('I00R',GetUnitX(u),GetUnitY(u))
        call SetItemCharges(newitem,targetcharge)
        call UnitAddItem(u,newitem)
        call CreateUnit(Player(0),'h01G',GetUnitX(u),GetUnitY(u),0)
    endif        
endfunction

function Trig_swapitem_Actions takes nothing returns nothing
//Yes, use order ids. The ids are 852002 to 852007, or 852002 + i, where i is the slot index. Note that because these are orders, at the time the trigger actions are run the item has not been moved yet.
    local integer itemix = GetIssuedOrderId()-852002
    local item pickeditem = GetOrderTargetItem()  // item that player right clicks
    local item targetitem = UnitItemInSlot(GetTriggerUnit(),itemix) // item on which player releases right click
    if (GetIssuedOrderId() >= 852002) and (GetIssuedOrderId() <= 852007) then
        call joinswappeditems(GetTriggerUnit(),pickeditem,targetitem)
    endif
endfunction

//===========================================================================
function InitTrig_swapitem takes nothing returns nothing
    set gg_trg_swapitem = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_swapitem, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
    call TriggerAddAction( gg_trg_swapitem, function Trig_swapitem_Actions )
endfunction
function Trig_arrowhit_Actions takes nothing returns nothing
    local unit source = GetEventDamageSource()
    local unit target = GetTriggerUnit()
    local item slotitem
    local integer charges
    local integer ix = 0
    local unit dmg
    if GetUnitTypeId(source) == 'h004' then // hit with an archer
        loop
            exitwhen ix == UnitInventorySize(source)
            set slotitem = UnitItemInSlot(source,ix)
            set charges = GetItemCharges(slotitem)
            if GetItemTypeId(slotitem) == 'I002' then // normal arrow
                call SetItemCharges(slotitem,charges-1)
                if charges == 1 then // if it was 1 when the loop started, it's 0 now and that means we're out
                    call RemoveItem(slotitem)
                endif
                set ix = UnitInventorySize(source) // terminate loop
                //call DisplayTextToForce(GetPlayersAll(),"normal")
            elseif GetItemTypeId(slotitem) == 'I00R' then // poison arrow
                call SetItemCharges(slotitem,charges-1)
                if charges == 1 then // if it was 1 when the loop started, it's 0 now and that means we're out
                    call RemoveItem(slotitem)
                endif
                set ix = UnitInventorySize(source) // terminate loop
                set dmg = CreateUnit(GetOwningPlayer(source),'h00I',GetUnitX(target),GetUnitY(target),0)
                call UnitAddAbility(dmg,'ACss')
                call IssueTargetOrder(dmg,"shadowstrike",target)
                call UnitApplyTimedLife(dmg,'BTLF',1)
            else
                set ix = ix + 1
            endif
        endloop
    endif
endfunction

//===========================================================================
function InitTrig_arrowhit takes nothing returns nothing
    set gg_trg_arrowhit = CreateTrigger(  )
    call TriggerAddAction( gg_trg_arrowhit, function Trig_arrowhit_Actions )
endfunction
function Trig_decreasearrows_Actions takes nothing returns nothing
    local integer ix = 0
    local item slotitem
    local boolean arrowfound = false
    if GetUnitTypeId(GetAttacker()) == 'h004' then
        loop
            exitwhen ix == UnitInventorySize(GetAttacker())
            set slotitem = UnitItemInSlot(GetAttacker(),ix)
            if (GetItemTypeId(slotitem) == 'I002') or (GetItemTypeId(slotitem) == 'I00R') then
                set arrowfound = true        
            endif
            set ix = ix + 1
        endloop
        if arrowfound == true then
        else
            call DisplayTextToPlayer(GetOwningPlayer(GetAttacker()),0,0,"Out of Arrows")
            call IssueImmediateOrder(GetAttacker(),"stop")    
        endif
    endif
endfunction

//===========================================================================
function InitTrig_decreasearrows takes nothing returns nothing
    set gg_trg_decreasearrows = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_decreasearrows, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( gg_trg_decreasearrows, function Trig_decreasearrows_Actions )
endfunction
money
  Events
  Conditions
  Actions
    Player - Set Player 1 (Red).Current gold to 750
    Player - Set Player 1 (Red).Current lumber to 750
enablevision
  Events
  Conditions
  Actions
    Visibility - Disable fog of war
    Visibility - Disable black mask
detectleaver
  Events
    Player - Player 1 (Red) leaves the game
    Player - Player 2 (Blue) leaves the game
    Player - Player 3 (Teal) leaves the game
    Player - Player 4 (Purple) leaves the game
    Player - Player 5 (Yellow) leaves the game
    Player - Player 6 (Orange) leaves the game
    Player - Player 7 (Green) leaves the game
  Conditions
  Actions
    Game - Display to (All players) the text: ((Name of (Triggering player)) + has left the game.)
    Player Group - Remove (Triggering player) from players.
    Unit Group - Pick every unit in (Units in (Playable map area) owned by (Triggering player)) and do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            Or - Any (Conditions) are true
              Conditions
                (Unit-type of (Picked unit)) Equal to Frozen Survivor (Impaired)
                (Unit-type of (Picked unit)) Equal to Survivor (Axe)
                (Unit-type of (Picked unit)) Equal to Survivor (Bow)
          Then - Actions
            Unit - Remove (Picked unit) from the game
          Else - Actions
            Unit - Make (Picked unit) Rescuable by players
callradiorescue
  Events
  Conditions
  Actions
    Countdown Timer - Start rescue as a One-shot timer that will expire in 1800.00 seconds
    Countdown Timer - Create a timer window for (Last started timer) with title Helicopter Arrives
    Set VariableSet helicopterarrived = True
    Trigger - Turn off (This trigger)
function removetreesforheli takes nothing returns nothing
    call KillDestructable(GetEnumDestructable())
endfunction

function enumallyup takes nothing returns nothing
    call SetPlayerAllianceStateBJ( Player(8), GetEnumPlayer(), bj_ALLIANCE_ALLIED_ADVUNITS )
endfunction

function allyup takes nothing returns nothing
    call ForForce( udg_players, function enumallyup )
endfunction

function Trig_helicopterarrives_Actions takes nothing returns nothing
    local string fx = "Abilities\\Spells\\Other\\Incinerate\\IncinerateBuff.mdl"
    local integer ix = 0
    local location center
    local location loc
    call MoveRectToLoc(gg_rct_helizone,GetRandomLocInRect(gg_rct_bearzone))
    call allyup()
    set center = Location(GetRectCenterX(gg_rct_helizone),GetRectCenterY(gg_rct_helizone))
    set udg_helicopterarrived = true
    set udg_helicopter = CreateUnitAtLoc(Player(8),'h007',center,0)
    call DestroyTimerDialogBJ( GetLastCreatedTimerDialogBJ() )
    loop
        exitwhen ix == 6
        set ix = ix + 1
        set loc = PolarProjectionBJ(center,400,60*I2R(ix))
        call AddSpecialEffect(fx,GetLocationX(loc),GetLocationY(loc))
    endloop
    call PlaySoundAtPointBJ(gg_snd_GyrocopterLoop1, 100, center, 200 )
    call PingMinimap(GetRectCenterX(gg_rct_helizone),GetRectCenterY(gg_rct_helizone),300)
    set ix = 0
    loop
        exitwhen ix == 12
        set ix = ix + 1
        set loc = PolarProjectionBJ(center,1000,30*I2R(ix))
        call AddSpecialEffect(fx,GetLocationX(loc),GetLocationY(loc))
    endloop
    call EnumDestructablesInCircleBJ(1000,center,function removetreesforheli)
    call StartTimerBJ( udg_departure, false, 120.00 )
    call CreateTimerDialogBJ( GetLastCreatedTimerBJ(),"Departure")        
endfunction

//===========================================================================
function InitTrig_helicopterarrives takes nothing returns nothing
    set gg_trg_helicopterarrives = CreateTrigger(  )
    call TriggerRegisterTimerExpireEventBJ( gg_trg_helicopterarrives, udg_rescue )
    call TriggerAddAction( gg_trg_helicopterarrives, function Trig_helicopterarrives_Actions )
endfunction
 
victory
  Events
    Time - departure expires
  Conditions
  Actions
    Cinematic - Apply a filter over 2 seconds using Normal blending on texture White Mask, starting with color (100%, 100%, 100%) and 100% transparency and ending with color (0%, 0%, 0%) and 0% transparency
    Countdown Timer - Destroy (Last created timer window)
    Unit Group - Pick every unit in survivors and do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            ((Picked unit) is loaded into helicopter.) Equal to True
          Then - Actions
            Game - Display to (Player group((Owner of (Picked unit)))) the text: The warm cabin of the helicopter reminds you of the comfort of home. You sip warm tea from a mug as you watch the harsh, boreal landscape fade beneath you.|r
            Game - Victory (Owner of (Picked unit)) (Show dialogs, Show scores)
          Else - Actions
            Game - Display to (Player group((Owner of (Picked unit)))) the text: |cffff0000The helicopter is gone. Wolves cry in the distance and the chill of the north wind runs hauntingly up your spine. Now you will die alone in winter.|r
    Unit - Remove helicopter from the game
function isstringint takes string s returns boolean
    if (s == "1") or (s == "2") or (s == "3") or (s == "4") or (s == "5") or (s == "6") or (s == "7") or (s == "8") or (s == "9") then
        return true
    endif
    return false
endfunction

function Trig_unally_ally_zoom_Actions takes nothing returns nothing
    local integer playernumber
    local string entered_int
    if SubStringBJ(GetEventPlayerChatString(), 2, 7) == "unally" then
        set entered_int = SubStringBJ(GetEventPlayerChatString(), 9, 9)
        if isstringint(entered_int) == true then
            call SetPlayerAllianceStateBJ( GetTriggerPlayer(), ConvertedPlayer(S2I(entered_int)), bj_ALLIANCE_UNALLIED )
        else
            call DisplayTextToPlayer(GetOwningPlayer(GetTriggerUnit()),0,0,"Invalid Player")
        endif  
    elseif SubStringBJ(GetEventPlayerChatString(), 2, 5) == "ally" then
        set entered_int = SubStringBJ(GetEventPlayerChatString(), 7, 7)
        if isstringint(entered_int) == true then
            call SetPlayerAllianceStateBJ( GetTriggerPlayer(), ConvertedPlayer(S2I(entered_int)), bj_ALLIANCE_ALLIED )
        else
            call DisplayTextToPlayer(GetOwningPlayer(GetTriggerUnit()),0,0,"Invalid Player")
        endif
   
    elseif SubStringBJ(GetEventPlayerChatString(), 2, 5) == "zoom" then
        set entered_int = SubStringBJ(GetEventPlayerChatString(), 7, 7)
        if isstringint(entered_int) == true then
            call SetCameraFieldForPlayer( GetTriggerPlayer(), CAMERA_FIELD_ZOFFSET, S2R(entered_int) * 300.00, 0)
        else
            call DisplayTextToPlayer(GetOwningPlayer(GetTriggerUnit()),0,0,"Invalid Zoom")
        endif
    endif
endfunction

//===========================================================================
function InitTrig_unally_ally_zoom takes nothing returns nothing
    set gg_trg_unally_ally_zoom = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_unally_ally_zoom, Player(0), "-", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_unally_ally_zoom, Player(1), "-", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_unally_ally_zoom, Player(2), "-", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_unally_ally_zoom, Player(3), "-", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_unally_ally_zoom, Player(4), "-", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_unally_ally_zoom, Player(5), "-", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_unally_ally_zoom, Player(6), "-", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_unally_ally_zoom, Player(7), "-", false )
    call TriggerAddAction( gg_trg_unally_ally_zoom, function Trig_unally_ally_zoom_Actions )
endfunction

 
function unit2friction takes unit u, real velocity returns real
    // increase skier friction if he's not on snow
    local integer terrain = GetTerrainType(GetUnitX(u),GetUnitY(u))
    local unit d
    local real friction
    if (terrain == 'Nsnw') or (terrain == 'Isnw') then // snows
        set friction = .001
        //set terrain = null
        return 0.001
    else
        set friction = .1
        call PlaySoundOnUnitBJ(gg_snd_DefendCaster,100,u)
        //set terrain = null
        //set d = CreateUnit(Player(0),'h01F',GetUnitX(u),GetUnitY(u),0)
        //call SetUnitScale(d,friction*velocity,friction*velocity,friction*velocity)
        return .1
    endif
    //return 0.001
endfunction

function unitpos2slope takes unit u, boolean forwards returns real
    // determine the slope in front of and behind a unit
    local real theta = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_theta"))
    local location present_l = GetUnitLoc(u)
    local location future_l = PolarProjectionBJ(present_l,128,bj_RADTODEG*theta)
    local location past_l = PolarProjectionBJ(present_l,128,bj_RADTODEG*theta-180)
    local integer cliff = GetTerrainCliffLevel(GetUnitX(u),GetUnitY(u))
    local real height
    local real slope
    if forwards == true then
        // anywhere outside of playable rect is a huge cliff
        if RectContainsCoords(GetPlayableMapRect(),GetLocationX(future_l),GetLocationY(future_l)) == false then
            //set height = GetLocationZ(future_l) - GetLocationZ(present_l)
            set slope = 1.5
        else
            set height = GetLocationZ(future_l) - GetLocationZ(present_l)
            set slope = Atan(height/128)
        endif    
    else
        set height = GetLocationZ(present_l) - GetLocationZ(past_l)
        set slope = Atan(height/128)
    endif
    call RemoveLocation(present_l)
    call RemoveLocation(future_l)
    call RemoveLocation(past_l)
    set present_l = null
    set future_l = null
    set past_l = null
    return slope
endfunction

function spawneffect takes integer uid, real x, real y, real scale, real theta, sound sfx returns nothing
    local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),uid,x,y,theta)
    call PlaySoundOnUnitBJ( sfx, 100, u )
    call SetUnitScale(u,scale,scale,scale)
    call UnitApplyTimedLifeBJ(1, 'BTLF', u )
endfunction

function MoveAngleTowardsAngle takes real a1, real a2, real i returns real
    //
 local real x
    set a1=ModuloReal(a1,360)
    set a2=ModuloReal(a2,360)
    if a1>a2 then
        set x=a1-360
        if a1-a2 > a2-x then
            set a1=x
        endif
    else
        set x=a2-360
        if a2-a1 > a1-x then
            set a2=x
        endif
    endif
    if a1>a2 then
        set x=a1-i
        if x<=a2 then
            return bj_DEGTORAD*a2
        endif
       return bj_DEGTORAD*x
    endif
    set x=a1+i
    if x>=a2 then
        return bj_DEGTORAD*a2
    endif
 return bj_DEGTORAD*x
endfunction


function unit2corneringangle takes unit u returns real
    local real horizontal_angle = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_theta"))
    local real horizontal_velocity = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_force"))
    local real turn_x = LoadReal(udg_hash,GetHandleId(u),StringHash("turn_x"))
    local real turn_y = LoadReal(udg_hash,GetHandleId(u),StringHash("turn_y"))
    local real turn_angle = Atan2(turn_y - GetUnitY(u),turn_x - GetUnitX(u))
    local real next_horizontal_angle = MoveAngleTowardsAngle(bj_RADTODEG*horizontal_angle,bj_RADTODEG*turn_angle,udg_TURNINGANGLE)
    local real cornering_angle = RAbsBJ(horizontal_angle - next_horizontal_angle)
    return cornering_angle
endfunction

function skijump takes unit u returns nothing
    // if skier is fast enough, jump
    local boolean flying = LoadBoolean(udg_hash,GetHandleId(u),StringHash("flying"))
    local real horizontal_velocity = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_force"))
    local real vertical_velocity
    local real height
    local location l = GetUnitLoc(u)
    if flying == false then
        //call BJDebugMsg("tried to jump")
        set vertical_velocity = RAbsBJ(horizontal_velocity*Sin(bj_DEGTORAD*45))
        if vertical_velocity - udg_GRAVITY - RAbsBJ(10/horizontal_velocity) > 0 then
            //call say("wheee!",u,100,100,100)
            call SaveBoolean(udg_hash,GetHandleId(u),StringHash("flying"),true)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("height"),GetLocationZ(l))
            call SaveReal(udg_hash,GetHandleId(u),StringHash("vertical_velocity"),vertical_velocity)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("angular_velocity"),unit2corneringangle(u))
            call SaveReal(udg_hash,GetHandleId(u),StringHash("facing"),GetUnitFacing(u))
            call SaveReal(udg_hash,GetHandleId(u),StringHash("total_spin"),0)            
            call SaveReal(udg_hash,GetHandleId(u),StringHash("total_velocity"),0)            
            call SetUnitPathing(u,false)
        endif
    endif
    call RemoveLocation(l)
    set l = null
endfunction

function unitisflat takes unit u returns boolean
    if GetUnitTypeId(u) == 'h010' then // basic snare
        return true
    elseif GetUnitTypeId(u) == 'h019' then // lowered palisade
        return true
    elseif GetUnitTypeId(u) == 'h012' then // strong snare
        return true
    elseif GetUnitTypeId(u) == 'h013' then // wide snare
        return true
    elseif GetUnitTypeId(u) == 'h014' then // ultimate snare
        return true
    endif
    return false    
endfunction

function unitcollision takes nothing returns boolean
    // stop the skier, shake the skier's screen, and explode any small wildlife
    //local boolean involuntary = LoadBoolean(udg_hash,GetHandleId(udg_tempcollider),StringHash("involuntary"))
    local real velocity = LoadReal(udg_hash,GetHandleId(udg_tempcollider),StringHash("inertia_force"))
    //local real slopeforward = unitpos2slope(udg_tempcollider,true)
    local unit u = GetFilterUnit()
    local real maxlife_target = GetUnitState(u,UNIT_STATE_MAX_LIFE)
    local real life_target = GetUnitState(u,UNIT_STATE_LIFE)
    local real maxlife_skier = GetUnitState(udg_tempcollider,UNIT_STATE_MAX_LIFE)
    local real life_skier = GetUnitState(udg_tempcollider,UNIT_STATE_LIFE)
    local real damage = velocity*udg_COLLISIONDAMAGE
    local real target_percent = maxlife_skier/(maxlife_target+maxlife_skier)
    local real target_damage = damage*target_percent
    local real skier_percent = maxlife_target/(maxlife_target+maxlife_skier)
    local real skier_damage = damage*skier_percent
    if (u == udg_tempcollider) or (IsUnitDeadBJ(u) == true) then
    elseif GetUnitTypeId(u) == 'h01D' then // you hit a ramp
        call skijump(udg_tempcollider)
    elseif unitisflat(u) == true then // cant bump into things on the ground
    //elseif involuntary == true then
    else
        if IsUnitInGroup(u,udg_carngroup) or IsUnitInGroup(u,udg_herbgroup) then // animal
            if velocity > 4 then
                call SetUnitExploded(u,true)
                call SetUnitState(u,UNIT_STATE_LIFE,life_target - target_damage)
                //call UnitDamageTarget(udg_tempcollider,u,target_damage,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC,null)
            endif
        endif
        call CameraSetEQNoiseForPlayer(GetOwningPlayer(u),(velocity/8)*target_percent)
        call CameraSetEQNoiseForPlayer(GetOwningPlayer(udg_tempcollider),(velocity/8)*skier_percent)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("shaking"),(velocity/8)*target_percent)
        call SaveReal(udg_hash,GetHandleId(udg_tempcollider),StringHash("shaking"),(velocity/8)*skier_percent)
        call SaveReal(udg_hash,GetHandleId(udg_tempcollider),StringHash("inertia_force"),0)
        call GroupAddUnit(udg_shakers,u)
        call GroupAddUnit(udg_shakers,udg_tempcollider)  
    endif
    return false
endfunction

function treecollision takes nothing returns nothing
    local unit u = udg_tempcollider
    local real velocity = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_force"))
    local boolean involuntary = LoadBoolean(udg_hash,GetHandleId(u),StringHash("involuntary"))
    //local real slopeforward = unitpos2slope(u,true)
    if involuntary == true then
        call KillDestructable(GetEnumDestructable())
    elseif velocity < 2 then
    elseif IsDestructableAliveBJ(GetEnumDestructable()) == true then
        call CameraSetEQNoiseForPlayer(GetOwningPlayer(u),velocity/16)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("shaking"),velocity/32)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("inertia_force"),0)
        call GroupAddUnit(udg_shakers,u)
        if velocity > 8 then
            call KillDestructable(GetEnumDestructable())
        endif
    endif
endfunction

function wallcollision takes unit u returns nothing
    local real velocity = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_force"))
    local real slopeforward = unitpos2slope(u,true)
    if slopeforward > bj_DEGTORAD*60 then
        call CameraSetEQNoiseForPlayer(GetOwningPlayer(u),velocity/4)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("shaking"),velocity/4)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("inertia_force"),0)
        call GroupAddUnit(udg_shakers,u)
    endif
endfunction

function tryflying takes unit u returns nothing
    // use the angle of the slope behind and in front of the unit
    // to determine if it's at an apex. if so, see if it's going
    // fast enough to become airborn.
    local boolean flying = LoadBoolean(udg_hash,GetHandleId(u),StringHash("flying"))
    local real horizontal_velocity = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_force"))
    local real vertical_velocity
    local real slopeforward = unitpos2slope(u,true)
    local real slopebackward = unitpos2slope(u,false)
    local real height
    local location l = GetUnitLoc(u)
    if (slopeforward < slopebackward) and (flying == false) then
        set vertical_velocity = RAbsBJ(horizontal_velocity*Sin(slopeforward))
        if vertical_velocity - udg_GRAVITY - RAbsBJ(10/horizontal_velocity) > 0 then
            //call say("wheee!",u,100,100,100)
            call SaveBoolean(udg_hash,GetHandleId(u),StringHash("flying"),true)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("height"),GetLocationZ(l))
            call SaveReal(udg_hash,GetHandleId(u),StringHash("vertical_velocity"),vertical_velocity)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("angular_velocity"),unit2corneringangle(u))
            call SaveReal(udg_hash,GetHandleId(u),StringHash("facing"),GetUnitFacing(u))
            call SaveReal(udg_hash,GetHandleId(u),StringHash("total_spin"),0)            
            call SaveReal(udg_hash,GetHandleId(u),StringHash("total_velocity"),0)            
            call SetUnitPathing(u,false)
        endif
    endif
    call RemoveLocation(l)
    set l = null
endfunction

function fly takes unit u returns nothing
    local boolean flying = LoadBoolean(udg_hash,GetHandleId(u),StringHash("flying"))
    local real horizontal_velocity = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_force"))
    local real horizontal_angle = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_theta"))
    local real angular_velocity = LoadReal(udg_hash,GetHandleId(u),StringHash("angular_velocity"))
    local real facing = LoadReal(udg_hash,GetHandleId(u),StringHash("facing"))
    local real total_spin = LoadReal(udg_hash,GetHandleId(u),StringHash("total_spin"))
    local real total_distance = LoadReal(udg_hash,GetHandleId(u),StringHash("total_distance"))
    local boolean involuntary = LoadBoolean(udg_hash,GetHandleId(u),StringHash("involuntary"))
    local real d_x
    local real d_y
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real vertical_velocity = LoadReal(udg_hash,GetHandleId(u),StringHash("vertical_velocity"))
    local real height = LoadReal(udg_hash,GetHandleId(u),StringHash("height"))
    local location l = GetUnitLoc(u)
    if flying == true then
        if height < GetLocationZ(l)-30 then
            call SetUnitFlyHeight(u,0,0)
            call SetUnitPathing(u,true)
            call spawneffect('h00E',GetUnitX(u),GetUnitY(u),1,0,null) //'h00E' gryphon missile special
            call SaveBoolean(udg_hash,GetHandleId(u),StringHash("flying"),false)
            if bj_RADTODEG*total_spin > 90 then
                //call say(I2S(R2I(bj_RADTODEG*total_spin))+" degree spin!",u,100,100,100)
            endif
            if involuntary == true then
                if (GetUnitTypeId(u) == 'h001') or (GetUnitTypeId(u) == 'h004') then
                else
                    call GroupRemoveUnit(udg_skiiers,u)
                endif
                call GroupAddUnit(udg_shot,u)
                call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("shot_angle"),horizontal_angle)
                call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("shot_amount"),horizontal_velocity)

                call SaveBoolean(udg_hash,GetHandleId(u),StringHash("involuntary"),false)            
            endif
            //if total_distance
            //    call DisplayTextToForce(GetPlayersAll(),R2S(total_distance))
        else    
            set vertical_velocity = vertical_velocity - udg_GRAVITY        
            set height = height + vertical_velocity  
            set horizontal_velocity = horizontal_velocity - horizontal_velocity*horizontal_velocity*udg_WINDRESISTANCE*.001
            set d_x = horizontal_velocity * Cos(horizontal_angle)
            set d_y = horizontal_velocity * Sin(horizontal_angle)
            call SetUnitPosition(u,x+d_x,y+d_y)
            set l = GetUnitLoc(u)
            call SetUnitFlyHeight(u,height-GetLocationZ(l),0)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("inertia_force"),horizontal_velocity)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("vertical_velocity"),vertical_velocity)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("height"),height)
            set facing = facing + angular_velocity
            call SaveReal(udg_hash,GetHandleId(u),StringHash("facing"),facing)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("total_spin"),total_spin + angular_velocity)
            call SaveReal(udg_hash,GetHandleId(u),StringHash("total_distance"),total_distance + horizontal_velocity)            
            call SetUnitFacing(u,bj_RADTODEG*facing)
            //call SetUnitFacing(u,0)
        endif
    endif
    call RemoveLocation(l)
    set l = null
endfunction

function ski takes unit u returns nothing
    local boolean flying = LoadBoolean(udg_hash,GetHandleId(u),StringHash("flying"))
    local real horizontal_velocity = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_force"))
    local real horizontal_angle = LoadReal(udg_hash,GetHandleId(u),StringHash("inertia_theta"))
    local real turn_x = LoadReal(udg_hash,GetHandleId(u),StringHash("turn_x"))
    local real turn_y = LoadReal(udg_hash,GetHandleId(u),StringHash("turn_y"))
    local real turn_angle = Atan2(turn_y - GetUnitY(u),turn_x - GetUnitX(u))
    local real next_horizontal_angle = MoveAngleTowardsAngle(bj_RADTODEG*horizontal_angle,bj_RADTODEG*turn_angle,udg_TURNINGANGLE)  
    local real cornering_angle = unit2corneringangle(u)
    local real longitudinal_velocity
    local real lateral_force
    local real friction
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real d_x
    local real d_y
    local real slopeforward = unitpos2slope(u,true)
    local location l = GetUnitLoc(u)
    if (flying == false) then// and (horizontal_velocity > 1) then
        //call BJDebugMsg("Going")
        set friction = unit2friction(u,horizontal_velocity) // this function also causes sound and FX
        set horizontal_velocity = horizontal_velocity - Sin(slopeforward)*udg_GRAVITY
        set horizontal_velocity = horizontal_velocity - (horizontal_velocity*friction)
        set horizontal_velocity = (RAbsBJ(horizontal_velocity) - horizontal_velocity*horizontal_velocity*udg_WINDRESISTANCE*.001)*RSignBJ(horizontal_velocity)
        set longitudinal_velocity = Cos(cornering_angle) * horizontal_velocity
        set lateral_force = Sin(cornering_angle) * horizontal_velocity *udg_CORNERINGFRICTION
        if lateral_force > .1 then
            call spawneffect('h00F',GetUnitX(u),GetUnitY(u),5*lateral_force,bj_RADTODEG*horizontal_angle,gg_snd_Feedback)
        endif
        set horizontal_velocity = longitudinal_velocity-lateral_force
        set d_x = horizontal_velocity * Cos(next_horizontal_angle)
        set d_y = horizontal_velocity * Sin(next_horizontal_angle)
        if (GetTerrainType(GetUnitX(u)+d_x,GetUnitY(u)+d_y) == 'Nsnw') or (GetTerrainType(GetUnitX(u)+d_x,GetUnitY(u)+d_y) == 'Isnw') then
            call SetTerrainType(GetUnitX(u)+d_x,GetUnitY(u)+d_y,'Nsnw',1,1,0)
        endif
        call SetUnitPosition(u,x+d_x,y+d_y)
        //call BJDebugMsg("Gone")
        call SetUnitFacing(u,bj_RADTODEG*turn_angle)
        call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("inertia_force"),horizontal_velocity)
        call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("inertia_theta"),next_horizontal_angle)
    endif
    call RemoveLocation(l)
    set l = null
endfunction

function collide takes unit u returns nothing
    local real s = 128
    local rect r = Rect(GetUnitX(u)-s,GetUnitY(u)-s,GetUnitX(u)+s,GetUnitY(u)+s)
    set udg_tempcollider = u
    call EnumDestructablesInRect(r,Filter(function ReturnTrue), function treecollision)
    call GroupEnumUnitsInRect(udg_dummygroup,r,Filter(function unitcollision))
    call RemoveRect(r)
    set r = null
endfunction

function maketheunitski takes nothing returns nothing
    if LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("inertia_force")) > 1 then
        call tryflying(GetEnumUnit())
        call fly(GetEnumUnit())
        call ski(GetEnumUnit())
        if LoadBoolean(udg_hash,GetHandleId(GetEnumUnit()),StringHash("flying")) == false then
            call collide(GetEnumUnit())
        endif
    endif
endfunction

function Trig_skipump_Actions takes nothing returns nothing
    call ForGroup(udg_skiiers, function maketheunitski)
endfunction

//===========================================================================
function InitTrig_skipump takes nothing returns nothing
    set gg_trg_skipump = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_skipump, .0167)
    call TriggerAddAction( gg_trg_skipump, function Trig_skipump_Actions )
endfunction
function makeskier takes nothing returns nothing
    local unit u = GetEnumUnit()
    if GetOwningPlayer(udg_tempunit) == GetOwningPlayer(u) then
        call GroupAddUnit(udg_skiiers,u)
        call UnitAddAbility(u,'Amrf')
        call UnitRemoveAbility(u,'Amrf')
        call SaveBoolean(udg_hash,GetHandleId(u),StringHash("isskiing"),true)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("vertical_velocity"),0)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("horizontal_acceleration"),0)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("inertia_theta"),bj_DEGTORAD*GetUnitFacing(u))
        call SaveReal(udg_hash,GetHandleId(u),StringHash("height"),0)
        call SaveReal(udg_hash,GetHandleId(u),StringHash("inertia_force"),0)
        call StartSound(bj_questItemAcquiredSound)
    endif
endfunction

function Trig_upgrades_skis_Actions takes nothing returns nothing
    if GetResearched() == 'R009' then
        set udg_tempunit = GetTriggerUnit()
        call ForGroup(udg_survivors, function makeskier)      
    endif
endfunction

//===========================================================================
function InitTrig_upgrades_skis takes nothing returns nothing
    set gg_trg_upgrades_skis = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_upgrades_skis, EVENT_PLAYER_UNIT_RESEARCH_FINISH )
    call TriggerAddAction( gg_trg_upgrades_skis, function Trig_upgrades_skis_Actions )
endfunction
function Trig_skiturn_Actions takes nothing returns nothing
    local boolean isskiing = LoadBoolean(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("isskiing"))
    local real x = GetOrderPointX()
    local real y = GetOrderPointY()
    local location a = GetUnitLoc(GetTriggerUnit())
    local location b = GetOrderPointLoc()
    local unit new_u
    local unit old_u
    if isskiing == true then    
        if OrderId2String(GetIssuedOrderId()) == "smart" then
            call IssueImmediateOrder(GetTriggerUnit(),"stop")
            set old_u = LoadUnitHandle(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("waypoint"))
            call RemoveUnit(old_u)
            set new_u = CreateUnit(GetOwningPlayer(GetTriggerUnit()),'h00G',x,y,0)
            call SaveUnitHandle(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("waypoint"),new_u)        
            call SaveReal(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("turn_x"),x)
            call SaveReal(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("turn_y"),y)
        endif
    endif
    call RemoveLocation(a)
    call RemoveLocation(b)
    set a = null
    set b = null
endfunction

//===========================================================================
function InitTrig_skiturn takes nothing returns nothing
    set gg_trg_skiturn = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_skiturn, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
    call TriggerAddAction( gg_trg_skiturn, function Trig_skiturn_Actions )
endfunction
function Trig_skigo_Actions takes nothing returns nothing
    local boolean flying = LoadBoolean(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("flying"))
    local real horizontal_velocity = LoadReal(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("inertia_force"))
    local real kick_force = GetUnitMoveSpeed(GetTriggerUnit())/85
    local unit u = GetTriggerUnit()
    if GetSpellAbilityId() == 'A00A' then
        if flying == false then
            //if horizontal_velocity < 2 then
            //    call SaveReal(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("intertia_angle"),GetUnitFacing(GetTriggerUnit())*bj_DEGTORAD)
            //endif
            call SaveReal(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("inertia_force"),horizontal_velocity+kick_force)
            call PlaySoundOnUnitBJ( gg_snd_CryptFiendMissileHit3, 100, GetTriggerUnit())
        endif
    endif
    if GetSpellAbilityId() == 'A00B' then
        if flying == false then
            if horizontal_velocity < 2 then
                set horizontal_velocity = 0
            else
                set horizontal_velocity = horizontal_velocity - 2
                call SaveReal(udg_hash,GetHandleId(GetTriggerUnit()),StringHash("inertia_force"),horizontal_velocity)
                call spawneffect('h00S',GetUnitX(u),GetUnitY(u),1,0,null)
            endif
        endif      
    endif
       
endfunction

//===========================================================================
function InitTrig_skigo takes nothing returns nothing
    set gg_trg_skigo = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_skigo, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddAction( gg_trg_skigo, function Trig_skigo_Actions )
endfunction
Untitled Trigger 002
  Events
  Conditions
  Actions