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 havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  5. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  6. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  7. The results are out! Check them out.
    Dismiss Notice
  8. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  9. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  10. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Trigger Viewer

toysoldiers_156.w3x
Variables
Initialization
bla
mody
replay
Safety
config
vectorsystem
TextLabel
spell
item
creep
player
game
AI
gui
remove blood
DIE
vykal
srajda
zbrane
zbran drop
zbran pick
zbran buy
sentry turret
minion attackfix
die turret
bear trap
cmd rr
cmd mode
cmd end
cmd swap
cmd null
cmd kill
cmd stats
cmd zombie
cmd help
cmd fix
cmd kick
cmd ai
trunk
quest
test
Untitled Trigger 001
MODEL TEST
LIGHTNING TEST
Untitled Trigger 003
Untitled Trigger 005 Copy
Untitled Trigger 007

		
Name Type Is Array Initial Value
explosion2.mp3 je bugged
trojka teez

pekne textury:
UI\Glues\BattleNet\BattlenetWorking\star.blp
UI\Widgets\BattleNet\bnet-tournament-clock.blp
ReplaceableTextures\WorldEditUI\Editor-Toolbar-AIEditor.blp
UI\Widgets\BattleNet\friends-chatroom.blp
UI\Feedback\Resources\ResourceLumber.blp

menu border:
UI\Widgets\Glues\GlueScreen-CampaignButton-BackdropBorder-Disabled.blp


Collected Damage Types:
-------------------------------------------
Type Applies Armour Value Classification
Normal Yes Physical
Enhanced No Physical
Magic No Magical
Universal No Universal
0 - team dm
1 - tanks
2 - bomb



team dm - klasika
assault - jedny sa furt respawnuju? 3x zivot? obranci len raz?
mission - klasika
vlak?

Assault
tak oba tymi budu mat namiesto score v tabulke ze lives:
ked panak stujpi do teleportu tak minus life defenderom
ked skape panak z teamu 2 tak minus life attackerom


Abilities\Spells\Orc\CommandAura\CommandAura.mdl


pri leaveroch tie gulicky zobarzuju aj enemy :D
satelit discs

mortar cost 1 grenade
opertar - miesto smoke - artillery - 2 grenade cost
//TESH.scrollpos=0
//TESH.alwaysfold=0
function InitTrig_replay takes nothing returns nothing
endfunction
//======================================================================
library replay requires config

globals
    public boolean game=true
endglobals

function B2S takes boolean b returns string
if b then
return "true"
endif
return "false"
endfunction

public function Init takes nothing returns nothing
local real CameraX=GetCameraTargetPositionX()
local real CameraY=GetCameraTargetPositionY()
call EnableUserControl(false)
call PauseGame(true)
call TriggerSleepAction(0)
call SetCameraPosition(CameraX+50,CameraY+50)
call TriggerSyncReady()
call TriggerSleepAction(0)
call PauseGame(false)
if R2I(GetCameraTargetPositionX())!=R2I(CameraX) then
call SetCameraPosition(CameraX,CameraY)
set game=true
else
  //call msg(Player(0),R2S(GetCameraTargetPositionX())+" / "+R2S(CameraX+1),"")
set game=false
endif
call EnableUserControl(true)
  //call msg(Player(0),"is this replay? "+B2S(not game),"")
endfunction

endlibrary
//TESH.scrollpos=14
//TESH.alwaysfold=0
function InitTrig_Safety takes nothing returns nothing
endfunction
//======================================================================
library Safety

//######################################################################
//#
//# library Safety
//#
//######################################################################

globals
    private timer H
    private timer array T
    private integer N=0
endglobals

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

function NewTimer takes nothing returns timer
    if N==0 then
        set H=CreateTimer()
    else  
        set N=N-1
        set H=T[N]
    endif

 return H
endfunction

function ReleaseTimer takes timer t returns nothing
    call PauseTimer(t)
    if N==8191 then
        //stack is full, the map already has much more troubles than the chance of bug
        call DestroyTimer(t)
    else
        set T[N]=t
        set N=N+1
    endif    
endfunction

endlibrary
function TreeShakeEnd takes nothing returns nothing
local destructable d=GetEnumDestructable()
if GetDestructableLife(d)>.405 then
call SetDestructableAnimationSpeed(d,1.0)
call SetDestructableAnimation(d,"stand")
else
call TreeHide(d)
endif
set d=null
endfunction

if x>0 then
set vol1=R2I(d*60)
elseif x<0 then
set vol2=R2I(d*60)
endif

if y>0 then
set vol1=vol1+R2I(d*40)
elseif y<0 then
set vol2=vol2+R2I(d*40)
endif

if vol1>vol2 then
call SetSoundPitch(s1,GetRandomReal(0.9,1.1))
call SetSoundPitch(s2,d*0.6)
else
call SetSoundPitch(s2,GetRandomReal(0.9,1.1))
call SetSoundPitch(s1,d*0.6)
endif
//TESH.scrollpos=1178
//TESH.alwaysfold=0
function InitTrig_config takes nothing returns nothing
endfunction
//===========================================================================
library config initializer Init requires Safety

globals

  constant integer FILES=64
  integer FILE=0
  real FILEPROCESS=0.

  constant integer FORCES=2
  constant integer MAXPLAYERS=10
   
  integer map=6
  rect rect_map
  boolean loaded=false
  integer main_cliff=0
  constant integer min_map=3
  constant integer max_map=8
 
  constant real MAP_SELECT=40.
  constant real ROUND_SETUP_DELAY=2.5
  constant real ROUND_END_DELAY=6.
  constant real ROUND_END_WAIT=30.
  constant real GAME_END_WAIT=60.
  constant real ROUND_CLASS=15.
  constant real ROUND_ZOMBIE=25.
  real ROUND_MAX=0
  constant real CAMERA_DELAY=0.3
  constant real CAMERA_ZOFFSET=1675.
  constant real SOUND_FOG_DIST=700.

  constant real UNIT_HEIGHT=80.
  constant real UNIT_MAX_HEIGHT=1000.
  constant real ITEM_RANGE=92.

  constant string MODEL_WINNER="Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl"
  constant string MODEL_WATER_SPLASH="water.mdl"
  constant string MODEL_DUST_SPLASH="dust.mdl"
  constant string MODEL_DUST_IMPACT="impactdust.mdl"
  //constant string MODEL_BACKSTAB="Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
  constant string MODEL_ITEM="Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl"
  //constant string MODEL_ARROW="Abilities\\Weapons\\GuardTowerMissile\\GuardTowerMissile.mdl"
  //constant string MODEL_WALL="Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
  //constant string MODEL_WAVE="Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveMissile.mdl"
  //constant string MODEL_NINJAKIN="Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl"
  //constant string MODEL_GRIND="Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
  //constant string MODEL_STUN="Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
  //constant string MODEL_FIREBALL="Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
  //constant string MODEL_SHURIKEN="Abilities\\Weapons\\SentinelMissile\\SentinelMissile.mdl"
  //constant string MODEL_BIG_EXPLOSION="Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl"
  //constant string MODEL_HUGE_EXPLOSION="Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
  //constant string MODEL_SMALL_EXPLOSION="Abilities\\Spells\\Other\\TinkerRocket\\TinkerRocketMissile.mdl"
  //constant string MODEL_HEAL="Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
  //constant string MODEL_MJOLNIR="Abilities\\Spells\\Human\\StormBolt\\StormBoltMissile.mdl"
  //constant string MODEL_DAMAGEBONUS="damagebonus.mdl"
  //constant string MODEL_ACID="acid.mdl"

  // salamander
  constant string MODEL_HIT="hit.mdl"
  constant string MODEL_HIT2="hit2.mdl"
  constant string MODEL_HITW="hit_wood.mdl"
  constant string MODEL_EXPLO_AIR="Model\\EXair.mdl"
  constant string MODEL_EXPLO_GROUND="Model\\EXground.mdl"
  constant string MODEL_ALCHEMY="Model\\Nade.mdl"
  constant string MODEL_BONES="Model\\Bones.mdl"
  constant string MODEL_BLOOD="Model\\Blood.mdl"
  constant string MODEL_BULLET="Model\\Bullet.mdl"
  constant string MODEL_BULLET2="Model\\Bullet2.mdl"
  constant string MODEL_EXPLO_FLARE="Model\\Flare.mdl"
  constant string MODEL_EXPLO_FLARE2="Model\\FlareKnife.mdl"
  constant string MODEL_FIRE="Model\\Fire.mdl"
  constant string MODEL_AIRSTRIKE="Abilities\\Weapons\\GyroCopter\\GyroCopterMissile.mdl"
  constant string MODEL_ROCKET="Model\\bluerocket.mdl"
  constant string MODEL_ROCKET2="Model\\redrocket.mdl"
  constant string MODEL_AOE="Model\\AOE.mdl"
  constant string MODEL_ICON_BOMB="Model\\ping_bomb.mdl"
  constant string MODEL_ICON_NADE="Model\\ping_nade.mdl"
  constant string MODEL_ICON_SMOKE="Model\\ping_smoke.mdl"
  constant string MODEL_ICON_LSD="Model\\ping_lsd.mdl"
  constant string MODEL_ICON_STICKY="Model\\ping_sticky.mdl"
  constant string MODEL_ICON_DEATH="Model\\ping_death.mdl"
  //constant string MODEL_AOE="Abilities\\Spells\\NightElf\\TrueshotAura\\TrueshotAura.mdl"
 
  constant string SOUND_GUN="Units\\Human\\Rifleman\\RiflemanAttack1.wav"
  constant string SOUND_BOUNCE="Sound\\Flechete.wav"
  constant string SOUND_FEET="Sound\\Feet.wav"
  constant string SOUND_PICKUP="Sound\\pickup.wav"
  constant string SOUND_GIBS="Sound\\gibs.wav"
  constant string SOUND_MSG="Sound\\Interface\\hint.wav"
  constant string SOUND_LEAVER="Abilities\\Spells\\NightElf\\shadowstrike\\ShadowStrikeBirth1.wav"
  constant string SOUND_HIT_FLESH="Sound\\hitflesh.mp3"
  constant string SOUND_HIT_WOOD="Sound\\hitwood.mp3"
 
  constant integer RAW_ABIL_ATTACK=     'A000'
  constant integer RAW_ABIL_NADEGLOW=   'AId8'
 
  // toy soldier
  constant integer RAW_MISSION=         'hrtt'
  constant integer RAW_BOMB=            'n001'
  constant integer RAW_ABIL_NADE=       'A002'
 
  constant integer RAW_MARINE=          'Hapm'
  constant integer RAW_MEDIC=           'Hart'
  constant integer RAW_SCOUT=           'Hpb2'
  constant integer RAW_SNIPER=          'Hgam'
  constant integer RAW_OPERATOR=        'Hant'
  constant integer RAW_GUNNER=          'Hmgd'
  constant integer RAW_STALKER=         'Hpb1'
  constant integer RAW_CLOAKED=         'Harf'
  constant integer RAW_ZOMBIE=          'Huth'
  constant integer RAW_MINION=          'ugho'

  constant integer RAW_FLYHACK=         'Amrf'
  constant integer RAW_DUMMY=           'ushd'
  constant integer RAW_MIRROR=          'negf'
  constant integer RAW_WALL_WOODEN=     'h003'
  constant integer RAW_CLASS=           'hhou'

  constant string COLOR_TEAM1=          "|c00FF4040"
  constant string COLOR_TEAM2=          "|c000080FF"
  constant string COLOR_TEAM3=          "|c00808080"
  constant string COLOR_END=            "|r"
  constant string STRING_NOTICE=        "|c00FFFF00Notice:|r "
  constant string STRING_GAME=          "|c0080FF00Game:|r "





  boolexpr BOOLEXPR_TRUE
  boolexpr BOOLEXPR_FALSE

  real MAX_X=0
  real MIN_X=0
  real MAX_Y=0
  real MIN_Y=0

  real SPAWN_X=0
  real SPAWN_Y=0

  unit placeholdunit=null
  mobile placeholdmobile=0
  Item placeholditem=0
  item lastitem=null
  boolean itempickup=true

  location Z_HACK=null
  group TREES=null
 
  integer array STATS_CLASSES_USED
  string array STATS_CLASSES_ID
endglobals








function echo takes string m returns nothing
  if autor!=null then
    call DisplayTimedTextToPlayer(autor,0,0,10,m)
  endif
endfunction

function CinematicFadeWithUI takes real sred, real sgreen, real sblue, real red, real green, real blue, real duration, string tex, real startTrans, real endTrans returns nothing
  if duration==0 then
    set startTrans=endTrans
  endif
  call SetCineFilterTexture(tex)
  call SetCineFilterBlendMode(BLEND_MODE_BLEND)
  call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
  call SetCineFilterStartUV(0,0,1,1)
  call SetCineFilterEndUV(0,0,1,1)
  call SetCineFilterStartColor(PercentTo255(sred),PercentTo255(sgreen),PercentTo255(sblue),PercentTo255(100-startTrans))
  call SetCineFilterEndColor(PercentTo255(red),PercentTo255(green),PercentTo255(blue),PercentTo255(100-endTrans))
  call SetCineFilterDuration(duration)
  call DisplayCineFilter(true)
endfunction

function CinematicFadeWithUI2 takes real red, real green, real blue, real duration, string tex, real startTrans, real endTrans returns nothing
  if duration==0 then
    set startTrans=endTrans
  endif
  call SetCineFilterTexture(tex)
  call SetCineFilterBlendMode(BLEND_MODE_BLEND)
  call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
  call SetCineFilterStartUV(0, 0, 1, 1)
  call SetCineFilterEndUV(0, 0, 1, 1)
  call SetCineFilterStartColor(PercentTo255(red),PercentTo255(green),PercentTo255(blue),PercentTo255(100-startTrans))
  call SetCineFilterEndColor(PercentTo255(red),PercentTo255(green),PercentTo255(blue),PercentTo255(100-endTrans))
  call SetCineFilterDuration(duration)
  call DisplayCineFilter(true)
endfunction



function SOUND_EXPLO takes nothing returns string
  //return "Sound\\explosion"+I2S(GetRandomInt(1,1))+".mp3"
  return "Sound\\explosion1.mp3"
endfunction

function SOUND_IMPACT takes nothing returns string
  local integer r=GetRandomInt(0,3)
  if r>0 then
    return "Sound\\impact7.wav"
  endif
  return "Sound\\impact"+I2S(GetRandomInt(4,6))+".wav"
endfunction

function SOUND_METAL_IMPACT takes nothing returns string
  return "Sound\\impact"+I2S(GetRandomInt(1,3))+".wav"
endfunction

private function returnfalse takes nothing returns boolean
  return false
endfunction
private function returntrue takes nothing returns boolean
  return true
endfunction

function KillUnitA takes unit a returns nothing
  call ShowUnit(a,false)
  call SetUnitExploded(a,true)
  call KillUnit(a)
endfunction

//######################################################################
//#
//# Init
//#
//######################################################################

function AddSound takes unit u, string file returns nothing
  local sound s=CreateSound(file,false,true,false,10,10,"")
  call SetSoundPitch(s,GetRandomReal(0.75,1.25))
  call SetSoundVolume(s,128)
  call SetSoundDistances(s,600,10000)
  call SetSoundDistanceCutoff(s,3000)
  call AttachSoundToUnit(s,u)
  call StartSound(s)
  call KillSoundWhenDone(s)
  set s=null
endfunction

function PreloadSnd3d takes string file returns nothing
  local sound s=CreateSound(file,false,true,false,10,10,"")
  call SetSoundVolume(s,1)
  call SetSoundPosition(s,0,0,0)
  call SetSoundDistances(s,1000000,1000000)
  call SetSoundDistanceCutoff(s,1000000)
  call StartSound(s)
  call KillSoundWhenDone(s)
  set s=null
endfunction

function PreloadSnd2d takes string file returns nothing
  local sound s=CreateSound(file,false,false,false,10,10,"")
  call SetSoundVolume(s,1)
  call StartSound(s)
  call KillSoundWhenDone(s)
  set s=null
endfunction

function PreloadSnd takes string file, boolean s returns nothing
  //call FogEnable(false)
  if s then
    call PreloadSnd3d(file)
  else
    call PreloadSnd2d(file)
  endif
  call TriggerSleepAction(0)
  set FILE=FILE+1
  //call FogEnable(true)
endfunction



function PreloadProcessFinal takes nothing returns nothing
  local integer s=100
  local real x=GetStartLocationX(GetPlayerStartLocation(Player(0)))
  local real y=GetStartLocationY(GetPlayerStartLocation(Player(0)))
  local real a
  local real b
  local integer i=2
  loop
      set i=i-1
      set a=x+GetRandomInt(-s,s)
      set b=y+GetRandomInt(-s,s)
      //call KillDestructable(CreateDestructableZ('B000',a,b,650,GetRandomReal(0,360),1.5,1))
      call KillDestructable(CreateDestructableZ('B000',a,b,660,GetRandomReal(0,360),.7,1))
      exitwhen i<=0
  endloop
  set s=160
  set i=5
  loop
      set i=i-1
      call KillDestructable(CreateDestructableZ('B001',x+GetRandomInt(-s,s),y+GetRandomInt(-s,s),661,GetRandomReal(0,360),.5,1))
      exitwhen i<=0
  endloop
  call AddSound(gg_unit_hpea_0010,"Sound\\shotgun.wav")
  call UnitApplyTimedLife(gg_unit_hpea_0010,0,5)
endfunction

function PreloadProcess takes nothing returns nothing
  local timer t=GetExpiredTimer()
  local real bit=100./FILES
  //local integer s=150
  //local real x=GetStartLocationX(GetPlayerStartLocation(Player(0)))
  //local real y=GetStartLocationY(GetPlayerStartLocation(Player(0)))
  //call echo(I2S(FILE)+"/"+I2S(FILES))
  if FILEPROCESS<FILE*bit then
    set FILEPROCESS=FILEPROCESS+1.
    //call KillDestructable(CreateDestructableZ('B00C',x+GetRandomInt(-s,s),y+GetRandomInt(-s,s),650,GetRandomReal(0,360),0.1,1))
  endif
  call SetTextTagText(LABELPROCESS.t,I2S(R2I(RMinBJ(FILEPROCESS+.5,100)))+"%",TextTagSize2Height(LABELPROCESS.size))
  if FILEPROCESS>=100. then
    call ReleaseTimer(t)
    //call SetTextTagPermanent(LABELPROCESS.t,false)
    call LABELPROCESS.timed(1,2.5)
    set FILE=-1
    set loaded=true
    call PreloadProcessFinal()
  endif
 
  set t=null
endfunction



private function Init takes nothing returns nothing
  local integer i=0
  call SetAllyColorFilterState(0)
  call EnableMinimapFilterButtons(false,false)
  //konfiguracie premennych
  set BOOLEXPR_TRUE= Condition(function returntrue)
  set BOOLEXPR_FALSE=Condition(function returnfalse)
  set MAX_X=GetCameraBoundMaxX()
  set MIN_X=GetCameraBoundMinX()
  set MAX_Y=GetCameraBoundMaxY()
  set MIN_Y=GetCameraBoundMinY()
  set Z_HACK=Location(0,0)
  set mission_unit[0]=null
  set mission_unit[1]=null
  set TREES=CreateGroup()
  //statistika
  set STATS_CLASSES_USED[0]=7
  loop
      set i=i+1
      set STATS_CLASSES_USED[i]=0
      exitwhen i==STATS_CLASSES_USED[0]
  endloop
  set STATS_CLASSES_ID[1]="Mar"
  set STATS_CLASSES_ID[2]="Rec"
  set STATS_CLASSES_ID[3]="Med"
  set STATS_CLASSES_ID[4]="Sni"
  set STATS_CLASSES_ID[5]="Op"
  set STATS_CLASSES_ID[6]="MG"
  set STATS_CLASSES_ID[7]="St"

  //vypnutie blbych zvukov, rusivych :P
  call StopSound(bj_dayAmbientSound,true,true)
  call StopSound(bj_nightAmbientSound,true,true)
  set bj_useDawnDuskSounds=false
  call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_AMBIENTSOUNDS,.5)

  //loading
  call ShowUnit(gg_unit_hpea_0010,false)
  call TimerStart(NewTimer(),.05,true,function PreloadProcess)
  call CinematicFadeWithUI2(0,0,0,1,"ReplaceableTextures\\CameraMasks\\Black_mask.blp",0,255)
  //loading
 
  //blbosti
  call CameraSetSmoothingFactor(100)
  call FogMaskEnable(false)
  call FogEnable(false)
  call SetFloatGameState(GAME_STATE_TIME_OF_DAY,0)
  call SetTimeOfDayScale(0) //200% cas, default 2
  //call SetDayNightModels("","")
 
  //masivny preload
  call ShowInterface(false,.01)
   
  call TriggerSleepAction(0)
 
  // pocet suborov je riadok posledneho - riadok prveho + 1
 
  //call ExecuteFunc("replay_Init")
  //call PreloadSnd("Sound\\Interface\\QuestNew.wav",false)
  //call PreloadSnd("Sound\\Interface\\QuestCompleted.wav",false)
  //call PreloadSnd("Sound\\Interface\\QuestFailed.wav",false)
  //call PreloadSnd("Abilities\\Spells\\Human\\Slow\\SlowTarget.wav",false)
  call PreloadSnd("Sound\\Interface\\ArrangedTeamInvitation.wav",false)
  call PreloadSnd("Abilities\\Spells\\Other\\AcidBomb\\AlchemistAcidBurnMissileDeath1.wav",true)
  call PreloadSnd("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltHit1.wav",true)
  call PreloadSnd("sound\\buildings\\shared\\BuildingPlacement.wav",true)
  call PreloadSnd("Sound\\alarm.mp3",false)
  call PreloadSnd("Sound\\explosion1.mp3",true)
  call PreloadSnd("Sound\\explosion_blast.mp3",true)
  call PreloadSnd("Sound\\explosion_L.mp3",false)
  call PreloadSnd("Sound\\explosion_R.mp3",false)
  call PreloadSnd("Sound\\turret.mp3",true)
  call PreloadSnd("Sound\\machinegun.wav",true)
  call PreloadSnd("Sound\\machinegun_.mp3",false)
  call PreloadSnd("Sound\\shotgun.wav",true)
  call PreloadSnd("Sound\\smoke.mp3",true)
  call PreloadSnd("Sound\\silencer.mp3",true)
  call PreloadSnd("Sound\\sticky.mp3",true)
  call PreloadSnd("Abilities\\Spells\\Human\\FlakCannons\\FlakCannon.wav",true)
  call PreloadSnd("Sound\\impact1.wav",true)
  call PreloadSnd("Sound\\impact2.wav",true)
  call PreloadSnd("Sound\\impact3.wav",true)
  call PreloadSnd("Sound\\impact4.wav",true)
  call PreloadSnd("Sound\\impact5.wav",true)
  call PreloadSnd("Sound\\impact6.wav",true)
  call PreloadSnd("Sound\\impact7.wav",true)
  call PreloadSnd("Sound\\Step\\inwater.wav",true)
  call PreloadSnd("Sound\\Step\\dirt1.wav",true)
  call PreloadSnd("Sound\\Step\\dirt2.wav",true)
  call PreloadSnd("Sound\\Step\\dirt3.wav",true)
  call PreloadSnd("Sound\\Step\\dirt4.wav",true)
  call PreloadSnd("Sound\\Step\\grass1.wav",true)
  call PreloadSnd("Sound\\Step\\grass2.wav",true)
  call PreloadSnd("Sound\\Step\\grass3.wav",true)
  call PreloadSnd("Sound\\Step\\grass4.wav",true)
  call PreloadSnd("Sound\\Step\\gravel1.wav",true)
  call PreloadSnd("Sound\\Step\\gravel2.wav",true)
  call PreloadSnd("Sound\\Step\\gravel3.wav",true)
  call PreloadSnd("Sound\\Step\\gravel4.wav",true)
  call PreloadSnd("Sound\\Step\\slosh1.wav",true)
  call PreloadSnd("Sound\\Step\\slosh2.wav",true)
  call PreloadSnd("Sound\\Step\\slosh3.wav",true)
  call PreloadSnd("Sound\\Step\\slosh4.wav",true)
  call PreloadSnd("Sound\\gibs.wav",true)
  call PreloadSnd("Sound\\drug.mp3",true)
  call PreloadSnd("Sound\\pills.mp3",true)
  call PreloadSnd("Sound\\satellite.mp3",true)
  call PreloadSnd("Sound\\flyby.mp3",false)
  call PreloadSnd("Units\\Orc\\HeroBladeMaster\\HeroBladeMasterAttack1.wav",true)
  call PreloadSnd("Sound\\knife.mp3",true)
  call PreloadSnd("Units\\Undead\\Ghoul\\Cannibalize.wav",true)
  call PreloadSnd(SOUND_GUN,true)
  call PreloadSnd(SOUND_BOUNCE,true)
  call PreloadSnd(SOUND_FEET,true)
  call PreloadSnd(SOUND_PICKUP,true)
  call PreloadSnd(SOUND_MSG,false)
  call PreloadSnd("Sound\\hit.mp3",false)
  call PreloadSnd("Sound\\hitflesh.mp3",true)
  call PreloadSnd("Sound\\hitwood.mp3",true)
  call PreloadSnd("Sound\\Whistle.mp3",true)
  call PreloadSnd("Sound\\UI\\redteamwins.mp3",false)
  call PreloadSnd("Sound\\UI\\blueteamwins.mp3",false)
  call PreloadSnd("Sound\\UI\\neitherteamwins.mp3",false)
  call PreloadSnd("Sound\\UI\\firstblood.mp3",false)
  call PreloadSnd("Sound\\UI\\bombplant.mp3",false)
  call PreloadSnd("Sound\\UI\\bombdefuse.mp3",false)
 
  //call TriggerSleepAction(2)
  call ShowInterface(true,.01)
  //set loaded=true
endfunction










function AddSound2D takes player p, string file returns nothing
  local sound s=CreateSound(file,false,false,false,10,10,"")
  local integer vol=0
  //call SetSoundPitch(s,GetRandomReal(0.5,0.75))
  if GetLocalPlayer()==p then
    set vol=100
  endif
  call SetSoundVolume(s,vol)
  call StartSound(s)
  call KillSoundWhenDone(s)
  set s=null
endfunction

function AddSound2DForce takes integer p, string file returns nothing
  local sound s=CreateSound(file,false,false,false,10,10,"")
  local integer vol=0
  if IsPlayerInForce(GetLocalPlayer(),player_Force[p]) then
    set vol=100
  endif
  call SetSoundVolume(s,vol)
  call StartSound(s)
  call KillSoundWhenDone(s)
  set s=null
endfunction

function msg takes player p, string m, string snd returns nothing
  call DisplayTimedTextToPlayer(p,0,0,1,m)
  if snd!="" then
    call AddSound2D(p,snd)
  endif
endfunction

function msg_timed takes player p, real t, string m, string snd returns nothing
  call DisplayTimedTextToPlayer(p,0,0,t,m)
  if snd!="" then
    call AddSound2D(p,snd)
  endif
endfunction

function statistics takes nothing returns nothing
  local real t=30
  local string s=""
  local integer i=0
  local integer n=0
  local integer z
  call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,t,"Statistics:")
  loop
      set i=i+1
      set n=n+STATS_CLASSES_USED[i]
      exitwhen i==STATS_CLASSES_USED[0]
  endloop
  set i=0
  loop
      set i=i+1
      set z=R2I(I2R(STATS_CLASSES_USED[i])/n*100+0.5)
      set s=s+"|c00FFB3FF"+STATS_CLASSES_ID[i]+"|r=|c0080FFFF"+I2S(z)+"|r% ; "
      exitwhen i==STATS_CLASSES_USED[0]
  endloop
  call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,t,"|c0080FF00Classes used:|r
"
+s)
  set i=0
  set z=0
  loop
      exitwhen i==MAXPLAYERS
      if player_drug[i]>z then
        set z=player_drug[i]
        set n=i
      endif
      set i=i+1
  endloop
  if z>0 then
    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,t,"|c0080FF00Drug abuser:|r "+GetPlayerName(Player(n)))
  endif
 
  set i=0
  set z=0
  loop
      exitwhen i==MAXPLAYERS
      if player_stats_kill[i]>z then
        set z=player_stats_kill[i]
        set n=i
      endif
      set i=i+1
  endloop
  if z>0 then
    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,t,"|c0080FF00Most kills:|r "+GetPlayerName(Player(n)))
  endif
 
  set i=0
  set z=0
  loop
      exitwhen i==MAXPLAYERS
      if player_stats_death[i]>z then
        set z=player_stats_death[i]
        set n=i
      endif
      set i=i+1
  endloop
  if z>0 then
    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,t,"|c0080FF00Most deaths:|r "+GetPlayerName(Player(n)))
  endif
 
  set i=0
  set z=0
  loop
      exitwhen i==MAXPLAYERS
      if player_stats_fb[i]>z then
        set z=player_stats_fb[i]
        set n=i
      endif
      set i=i+1
  endloop
  if z>0 then
    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,t,"|c0080FF00Most firstblood:|r "+GetPlayerName(Player(n)))
  endif
endfunction










function DamageArea takes real distance, real radius, real maxdmg returns real
  return (radius-distance)/radius*maxdmg
endfunction

function GetZ takes real x, real y returns real
  call MoveLocation(Z_HACK,x,y)
  return GetLocationZ(Z_HACK)
  return 0.
endfunction

function GetAngleFix takes real a returns real
//  set a=-2120
//  call BJDebugMsg("calc="+R2S(a))
  if a>360 then
    set a=a - R2I(a/360.)*360.
  elseif a<0 then
//    call BJDebugMsg("calc x="+R2S(I2R(R2I(RAbsBJ(a)/360.)+1)))
//    call BJDebugMsg("calc base="+R2S((R2I(RAbsBJ(a)/360.)+1)*360.))
    set a=I2R(R2I(RAbsBJ(a)/360.)+1)*360. + a
  endif
//  call BJDebugMsg("calc end="+R2S(a))
  return a
endfunction



function AddSoundFog takes unit u, string file returns nothing
  local sound s=CreateSound(file,false,false,false,10,10,"")
  local integer vol=0
  call SetSoundPitch(s,GetRandomReal(0.5,0.75))
  if GetLocalPlayer()!=Player(12) then
    if RAbsBJ(GetCameraTargetPositionX()-GetUnitX(u))>SOUND_FOG_DIST and RAbsBJ(GetCameraTargetPositionY()-GetUnitY(u))>SOUND_FOG_DIST then
      set vol=32
    endif
  endif
  if IsFoggedToPlayer(GetUnitX(u),GetUnitY(u),GetLocalPlayer()) then
    set vol=32
  endif
  call SetSoundVolume(s,vol)
  call StartSound(s)
  call KillSoundWhenDone(s)
  set s=null
endfunction

//function AddSoundFogStereo takes unit u, string file, boolean left returns nothing
//  local sound s=CreateSound(file,false,false,false,10,10,"")
//  local integer vol=0
//  call SetSoundPitch(s,GetRandomReal(0.75,0.8))
//  if IsFoggedToPlayer(GetUnitX(u),GetUnitY(u),GetLocalPlayer()) then
//    if GetCameraEyePositionX()>GetUnitX(u) and left then
//      set vol=32
//    elseif GetCameraEyePositionX()<GetUnitX(u) and not left then
//      set vol=32
//    endif
//  endif
//  call SetSoundVolume(s,vol)
//  call StartSound(s)
//  call KillSoundWhenDone(s)
//  set s=null
//endfunction

function AddSoundStereo takes unit u, string left, string right returns nothing
  local sound s1=CreateSound(left,false,false,false,10,10,"")
  local sound s2=CreateSound(right,false,false,false,10,10,"")
  local integer vol1=0
  local integer vol2=0
  local real x=0
  local real y=0
  local real a=0
  local real d=100
  local real range=3500
  local real hyp=0
  //GetLocalPlayer()==GetLocalPlayer()
  if GetLocalPlayer()!=Player(12) then
    set x=GetCameraEyePositionX()-GetUnitX(u)
    set y=GetCameraEyePositionY()-GetUnitY(u)
    set hyp=SquareRoot(x*x+y+y)
    if hyp==0 then
      set hyp=1
    endif
    set a=y/hyp
    if a<0 then
      set a=a*-1
    endif
    set d=(range-hyp)/range//SquareRoot(x*x+y+y)
    //set a=bj_RADTODEG*Atan2(y,x)
     if x>0 then
      set vol1=R2I(d*75*a)
      set vol2=R2I(d*55)
      call SetSoundPitch(s1,GetRandomReal(.8,1.1))
      call SetSoundPitch(s2,.5+a*0.45)
    elseif x<0 then
      set vol1=R2I(d*55)
      set vol2=R2I(d*75*a)
      call SetSoundPitch(s1,.5+a*0.45)
      call SetSoundPitch(s2,GetRandomReal(.8,1.1))
    endif
    //call msg(GetLocalPlayer(),"a: "+R2S(a),"")
    //call msg(GetLocalPlayer(),"l: "+I2S(vol1),"")
    //call msg(GetLocalPlayer(),"r: "+I2S(vol2),"")
  endif
  call SetSoundVolume(s1,vol1)
  call SetSoundVolume(s2,vol2)
  call StartSound(s1)
  call StartSound(s2)
  call KillSoundWhenDone(s1)
  call KillSoundWhenDone(s2)
  set s1=null
  set s2=null
endfunction

function SetSpawn takes player p returns nothing
  if IsPlayerInForce(p,player_Force[0]) then
    set SPAWN_X=player_SpawnX[0]
    set SPAWN_Y=player_SpawnY[0]
  elseif IsPlayerInForce(p,player_Force[1]) then
    set SPAWN_X=player_SpawnX[1]
    set SPAWN_Y=player_SpawnY[1]
  endif
endfunction














function IsWallFilter takes nothing returns boolean
  return(GetUnitAbilityLevel(GetFilterUnit(),'Avul')==1 and IsUnitType(GetFilterUnit(),UNIT_TYPE_MECHANICAL))
endfunction

function TreeHide takes destructable d returns nothing
  local real x=GetDestructableX(d)
  local real y=GetDestructableY(d)
  local group g=CreateGroup()
  local boolexpr filter=Condition(function IsWallFilter)
  local unit c
  call GroupEnumUnitsInRange(g,x,y,48.,filter)
  call DestroyBoolExpr(filter)
  set filter=null
  loop
      set c=FirstOfGroup(g)
      exitwhen c==null
      call GroupRemoveUnit(g,c)
      call ShowUnit(c,false)
      call GroupAddUnit(TREES,c)
  endloop
 
  call DestroyGroup(g)
  set g=null
  set c=null
  //call echo("TreeHide")
endfunction

function TreeShake takes nothing returns nothing
  local destructable d=GetEnumDestructable()
  if GetDestructableLife(d)>.405 then
    call SetDestructableLife(d,GetDestructableLife(GetEnumDestructable())-10)
    if GetDestructableLife(d)>.405 then
      //call SetDestructableAnimationSpeed(d,0.35)
      call SetDestructableAnimation(d,"stand - hit")
    else
      call TreeHide(d)
    endif
  endif
  set d=null
endfunction

function TreeKill takes nothing returns nothing
  call KillDestructable(GetEnumDestructable())
  call TreeHide(GetEnumDestructable())
endfunction

function TreeRevive takes nothing returns nothing
  call DestructableRestoreLife(GetEnumDestructable(),GetDestructableMaxLife(GetEnumDestructable()),true)
endfunction

function TreeShowRespawn takes nothing returns nothing
  call ShowUnit(GetEnumUnit(),true)
endfunction

function TreeRespawn takes nothing returns nothing
  call EnumDestructablesInRect(bj_mapInitialPlayableArea,null,function TreeRevive)
  call ForGroup(TREES,function TreeShowRespawn)
  call GroupClear(TREES)
endfunction

function EnumDestructablesInCircleFilter takes nothing returns boolean
  local location d
  local boolean result=false
  if GetDestructableTypeId(GetFilterDestructable())=='ATtr' then
    set d=GetDestructableLoc(GetFilterDestructable())
    set result=DistanceBetweenPoints(d,bj_enumDestructableCenter)<=bj_enumDestructableRadius
    call RemoveLocation(d)
    set d=null
  endif
  return result
endfunction

function EnumDestructablesInCircle takes real x, real y, real radius, code actionFunc returns nothing
  local rect r
  local boolexpr filter
  //call echo("EnumDestructablesInCircle")
  if radius>0. then
    set bj_enumDestructableCenter=Location(x,y)
    set bj_enumDestructableRadius=radius
    set r=Rect(x-radius,y-radius,x+radius,y+radius)
    set filter=Condition(function EnumDestructablesInCircleFilter)
    call EnumDestructablesInRect(r,filter,actionFunc)
    call DestroyBoolExpr(filter)
    set filter=null
    call RemoveRect(r)
    set r=null
    call RemoveLocation(bj_enumDestructableCenter)
  endif
endfunction



// To make the dummy face a 2 dimensional orientation instantly:
function SetDummyFacing takes unit u, real angle returns nothing
  call SetUnitLookAt(u, "Bone_Head", u, Cos(angle)*1000000., Sin(angle)*1000000., 0.)
endfunction

// To make the dummy face a 3 dimensional orientation instantly:
function SetDummyOrientation takes unit u, real x, real y, real z returns nothing
  call SetUnitLookAt(u, "Bone_Head", u, x*1000000., y*1000000., z*1000000.)
endfunction

//To make the dummy always face a particular unit, for homing missiles:
function SetDummyHomingTarget takes unit u, unit target returns nothing
  call SetUnitLookAt(u, "Bone_Head", target, 0., 0., 0.)
endfunction

//######################################################################
//#
//# Maps
//#
//######################################################################

function MAP_STATS takes nothing returns nothing
  local integer m=R2I(ROUND_MAX/60)
  local integer s=R2I(ROUND_MAX-m*60)
  local string x=""
  if s>0 then
    set x=I2S(s)+"|c00808080s|r"
  endif
  call msg_timed(GetLocalPlayer(),15,"|c00FFFF00Grenades:|r "+I2S(max_grenades),null)
  if mod!=4 then
    call msg_timed(GetLocalPlayer(),15,"|c00FFFF00Round length:|r "+I2S(m)+"|c00808080m|r "+x,null)
  endif
  call CinematicFadeWithUI2(0,0,0,3,"ReplaceableTextures\\CameraMasks\\Black_mask.blp",0,255)
endfunction

function MAP_BOMBAREA_DO takes nothing returns nothing
  local unit u
  if mod==2 then
    //call UnitSetUsesAltIcon(u,true)
    call SetUnitVertexColor(u,32,0,0,0)
    call UnitAddAbility(u,'ACav')
    if GetUnitUserData(u)==0 then
      call IssueImmediateOrder(u,"waterelemental")
    endif
    call SetUnitUserData(u,1)
  else
    //call UnitSetUsesAltIcon(u,false)
    call SetUnitVertexColor(u,0,0,0,0)
    call UnitRemoveAbility(u,'ACav')
    call IssuePointOrder(u,"dispel",GetUnitX(u),GetUnitY(u))
    call SetUnitUserData(u,0)
  endif
  set u=null
endfunction

function MAP_0 takes nothing returns nothing
  local group g
  call SetWaterBaseColor(128,128,255,255)
  call SetTerrainFogEx(0,1000,6000,0,0,0,0)
  call SetSkyModel("Environment\\Sky\\FelwoodSky\\FelwoodSky.mdl")
  set ROUND_MAX=60*4
  set max_grenades=6
  set mod=1
  set player_SpawnX[0]=-3700
  set player_SpawnY[0]=3000
  set player_SpawnX[1]=4300
  set player_SpawnY[1]=-4200
  set rect_map=gg_rct_MAP0
 
  set g=GetUnitsOfTypeIdAll('h001')
  call ForGroup(g,function MAP_BOMBAREA_DO)
  call DestroyGroup(g)
  set g=null
 
  set player_ObsCam[0]=gg_cam_MAP0_1
  set player_ObsCam[1]=gg_cam_MAP0_2
  set player_ObsCam[2]=gg_cam_MAP0_3
  set player_ObsCam[3]=gg_cam_MAP0_4
  set player_ObsCam[4]=gg_cam_MAP0_5
  set player_actual_ObsCam=0
  set player_max_ObsCam=4
 
  call ClearTextMessages()
  call msg_timed(GetLocalPlayer(),15,"|c0080FF00Operation:|r   C A N D Y   B O X


|c0080FF00Assault:|r
  Destroy tank at enemy spawn or kill all opponents !
"
,SOUND_MSG)
  call MAP_STATS()
endfunction

function MAP_1 takes nothing returns nothing
  local group g
  call SetWaterBaseColor(128,128,255,255)
  call SetTerrainFogEx(0,1000,6000,0,0,0,0)
  call SetSkyModel("Environment\\Sky\\DalaranSky\\DalaranSky.mdl")
  set ROUND_MAX=60*2.5
  set max_grenades=5
  set mod=0
  set player_SpawnX[0]=-3700
  set player_SpawnY[0]=3000
  set player_SpawnX[1]=4300
  set player_SpawnY[1]=-4200
  set rect_map=gg_rct_MAP0
 
  set g=GetUnitsOfTypeIdAll('h001')
  call ForGroup(g,function MAP_BOMBAREA_DO)
  call DestroyGroup(g)
  set g=null
 
  set player_ObsCam[0]=gg_cam_MAP0_5
  set player_ObsCam[1]=gg_cam_MAP0_2
  set player_ObsCam[2]=gg_cam_MAP0_3
  set player_ObsCam[3]=gg_cam_MAP0_4
  set player_ObsCam[4]=gg_cam_MAP0_1
  set player_actual_ObsCam=0
  set player_max_ObsCam=4
 
  call ClearTextMessages()
  call msg_timed(GetLocalPlayer(),15,"|c0080FF00Operation:|r   C A N D Y   B O X


|c0080FF00Team Deathmatch:|r
  Kill all your opponents !
"
,SOUND_MSG)
  call MAP_STATS()
endfunction

function MAP_2 takes nothing returns nothing
  local group g
  call SetWaterBaseColor(128,128,255,255)
  call SetTerrainFogEx(0,1000,6000,0,0,0,0)
  call SetSkyModel("Environment\\Sky\\DalaranSky\\DalaranSky.mdl")
  set ROUND_MAX=60*1.75
  set max_grenades=6
  set mod=2
  set player_SpawnX[0]=-3700
  set player_SpawnY[0]=3000
  set player_SpawnX[1]=4300
  set player_SpawnY[1]=-4200
  set rect_map=gg_rct_MAP0
  //set max_areas=3
  call SetAltMinimapIcon("UI\\MiniMap\\MinimapIcon\\MinimapIconStartLoc.blp")
  set g=GetUnitsOfTypeIdAll('h001')
  call ForGroup(g,function MAP_BOMBAREA_DO)
  call DestroyGroup(g)
  set g=null
 
  set player_ObsCam[0]=gg_cam_MAP0_BOMB1
  set player_ObsCam[1]=gg_cam_MAP0_BOMB2
  set player_ObsCam[2]=gg_cam_MAP0_BOMB3
  set player_actual_ObsCam=0
  set player_max_ObsCam=2
 
  call ClearTextMessages()
  call msg_timed(GetLocalPlayer(),15,"|c0080FF00Operation:|r   C A N D Y   B O X


|c0080FF00Bomb/Defuse:|r
  Attackers - plant bomb in one of the bomb area and let it explode
  Defenders - defend bomb areas, prevent bomb to be planted, defuse bomb (use Knife)
"
,SOUND_MSG)
  call MAP_STATS()
endfunction

function MAP_3 takes nothing returns nothing
  local group g
  call SetWaterBaseColor(128,255,0,255)
  call SetTerrainFogEx(0,1000,6000,0,0.627,0.471,0.294)
  call SetSkyModel("Environment\\Sky\\DalaranSky\\DalaranSky.mdl")
  set ROUND_MAX=115
  set max_grenades=6
  set mod=2
  set player_SpawnX[1]=7700
  set player_SpawnY[1]=2700
  set player_SpawnX[0]=10000
  set player_SpawnY[0]=-2800
  set player_Force_rotate[0]=0
  set player_Force_rotate[1]=0//180
  set rect_map=gg_rct_MAP1

  call SetAltMinimapIcon("UI\\MiniMap\\MinimapIcon\\MinimapIconStartLoc.blp")
  set g=GetUnitsOfTypeIdAll('h001')
  call ForGroup(g,function MAP_BOMBAREA_DO)
  call DestroyGroup(g)
  set g=null
 
  set player_ObsCam[0]=gg_cam_MAP1_1
  set player_actual_ObsCam=0
  set player_max_ObsCam=0
 
  call ClearTextMessages()
  call msg_timed(GetLocalPlayer(),15,"|c0080FF00Operation:|r   I N F E R N O


|c0080FF00Bomb/Defuse:|r
|c00FF4040Red Team|r - plant bomb in one of the bomb site and let it explode
|c000080FFBlue Team|r - defend bomb sites, prevent bomb to be planted, defuse bomb
"
,SOUND_MSG)
  call MAP_STATS()
endfunction

function MAP_4 takes nothing returns nothing
  local group g
  call SetWaterBaseColor(128,255,0,255)
  call SetTerrainFogEx(0,600,5900,0,0.115,0.055,0.195)
  call SetSkyModel("Environment\\Sky\\DalaranSky\\DalaranSky.mdl")
  set ROUND_MAX=180
  set max_grenades=4
  set mod=3
  set mission_player=11
  set player_SpawnX[1]=10360
  set player_SpawnY[1]=-315
  set player_SpawnX[0]=10360
  set player_SpawnY[0]=-315
  set player_Force_rotate[0]=0
  set player_Force_rotate[1]=0//180
  set rect_map=gg_rct_MAP1

  set g=GetUnitsOfTypeIdAll('h001')
  call ForGroup(g,function MAP_BOMBAREA_DO)
  call DestroyGroup(g)
  set g=null
 
  set player_ObsCam[0]=gg_cam_MAP1_1
  set player_actual_ObsCam=0
  set player_max_ObsCam=0
 
  call ClearTextMessages()
  call msg_timed(GetLocalPlayer(),15,"|c0080FF00Operation:|r   I N F E R N O


|c0080FF00Zombie mode:|r
|c00FF4040Red Team|r - soldiers, kill all zombies and don't get killed
|c000080FFBlue Team|r - zombies, kill all soldiers to infect them
"
,SOUND_MSG)
  call MAP_STATS()
endfunction

function MAP_5 takes nothing returns nothing
  local group g
  call SetWaterBaseColor(128,255,0,255)
  call SetTerrainFogEx(0,1000,6000,0,0.725,0.525,0.305)
  call SetSkyModel("Environment\\Sky\\DalaranSky\\DalaranSky.mdl")
  set ROUND_MAX=300
  set max_grenades=6
  set mod=0
  set player_SpawnX[1]=7700
  set player_SpawnY[1]=2700
  set player_SpawnX[0]=10000
  set player_SpawnY[0]=-2800
  set player_Force_rotate[0]=0
  set player_Force_rotate[1]=0//180
  set rect_map=gg_rct_MAP1

  call SetAltMinimapIcon("UI\\MiniMap\\MinimapIcon\\MinimapIconStartLoc.blp")
  set g=GetUnitsOfTypeIdAll('h001')
  call ForGroup(g,function MAP_BOMBAREA_DO)
  call DestroyGroup(g)
  set g=null
 
  set player_ObsCam[0]=gg_cam_MAP1_1
  set player_actual_ObsCam=0
  set player_max_ObsCam=0
 
  call ClearTextMessages()
  call msg_timed(GetLocalPlayer(),15,"|c0080FF00Operation:|r   I N F E R N O


|c0080FF00Team Deathmatch:|r
  Kill all your opponents !
"
,SOUND_MSG)
  call MAP_STATS()
endfunction



function MAP_6 takes nothing returns nothing
  local group g
  call SetWaterBaseColor(128,128,255,255)
  call SetTerrainFogEx(0,800,6000,0,0.325,0.425,0.635)
  call SetSkyModel("Environment\\Sky\\FoggedSky\\FoggedSky.mdl")
  set ROUND_MAX=300
  set max_grenades=6
  set mod=0
  set player_SpawnX[1]=2270
  set player_SpawnY[1]=3370
  set player_SpawnX[0]=5340
  set player_SpawnY[0]=-3530
  set player_Force_rotate[0]=0
  set player_Force_rotate[1]=0//180
  set rect_map=gg_rct_MAP0

  call SetAltMinimapIcon("UI\\MiniMap\\MinimapIcon\\MinimapIconStartLoc.blp")
  set g=GetUnitsOfTypeIdAll('h001')
  call ForGroup(g,function MAP_BOMBAREA_DO)
  call DestroyGroup(g)
  set g=null
 
  set player_ObsCam[0]=gg_cam_MAP0_1
  set player_ObsCam[1]=gg_cam_MAP0_2
  set player_ObsCam[2]=gg_cam_MAP0_3
  set player_ObsCam[3]=gg_cam_MAP0_4
  set player_actual_ObsCam=0
  set player_max_ObsCam=3
 
  call ClearTextMessages()
  call msg_timed(GetLocalPlayer(),15,"|c0080FF00Operation:|r   T H O U S A N D   C A N E S


|c0080FF00Team Deathmatch:|r
  Kill all your opponents !
"
,SOUND_MSG)
  call MAP_STATS()
endfunction

function MAP_7 takes nothing returns nothing
  local group g
  call SetWaterBaseColor(128,128,255,255)
  call SetTerrainFogEx(0,600,5900,0,0.115,0.055,0.195)
  call SetSkyModel("Environment\\Sky\\FoggedSky\\FoggedSky.mdl")
  set ROUND_MAX=200
  set max_grenades=4
  set mod=3
  set mission_player=11
  set player_SpawnX[1]=2370
  set player_SpawnY[1]=-300
  set player_SpawnX[0]=2370
  set player_SpawnY[0]=-300
  set player_Force_rotate[0]=0
  set player_Force_rotate[1]=0//180
  set rect_map=gg_rct_MAP0

  set g=GetUnitsOfTypeIdAll('h001')
  call ForGroup(g,function MAP_BOMBAREA_DO)
  call DestroyGroup(g)
  set g=null
 
  set player_ObsCam[0]=gg_cam_MAP0_1
  set player_ObsCam[1]=gg_cam_MAP0_2
  set player_ObsCam[2]=gg_cam_MAP0_3
  set player_ObsCam[3]=gg_cam_MAP0_4
  set player_actual_ObsCam=0
  set player_max_ObsCam=3
 
  call ClearTextMessages()
  call msg_timed(GetLocalPlayer(),15,"|c0080FF00Operation:|r   T H O U S A N D   C A N E S


|c0080FF00Zombie mode:|r
|c00FF4040Red Team|r - soldiers, kill all zombies and don't get killed
|c000080FFBlue Team|r - zombies, kill all soldiers to infect them
"
,SOUND_MSG)
  call MAP_STATS()
endfunction

function MAP_8 takes nothing returns nothing
  local group g
  call SetWaterBaseColor(128,128,255,255)
  call SetTerrainFogEx(0,600,5900,0,0.115,0.055,0.195)
  call SetSkyModel("Environment\\Sky\\FoggedSky\\FoggedSky.mdl")
  set ROUND_MAX=200
  set max_grenades=5
  set mod=4
  set main_cliff=5
  set wave=1
  set player_SpawnX[1]=2370
  set player_SpawnY[1]=-300
  set player_SpawnX[0]=2370
  set player_SpawnY[0]=-300
  set player_Force_rotate[0]=0
  set player_Force_rotate[1]=0//180
  set rect_map=gg_rct_MAP0

  set g=GetUnitsOfTypeIdAll('h001')
  call ForGroup(g,function MAP_BOMBAREA_DO)
  call DestroyGroup(g)
  set g=null
 
  set player_ObsCam[0]=gg_cam_MAP0_1
  set player_ObsCam[1]=gg_cam_MAP0_2
  set player_ObsCam[2]=gg_cam_MAP0_3
  set player_ObsCam[3]=gg_cam_MAP0_4
  set player_actual_ObsCam=0
  set player_max_ObsCam=3
 
  call ClearTextMessages()
  call msg_timed(GetLocalPlayer(),15,"|c0080FF00Operation:|r   T H O U S A N D   C A N E S


|c0080FF00Cooperative:|r
  Survive creep waves !
"
,SOUND_MSG)
  call MAP_STATS()
endfunction





function MAP_ObsCam takes nothing returns nothing
  local integer i=0
  loop
      //exitwhen mission_unit[100]==null
      call TriggerSleepAction(GetRandomReal(2,3))
      call TriggerSleepAction(0)
      call TriggerSleepAction(0)
      set i=i+1
      if i>player_max_ObsCam then
        set i=0
      endif
      set player_actual_ObsCam=i
      exitwhen mission_unit[100]==null
  endloop
  call echo("obs cam ended")
endfunction

function MAP_Timer takes nothing returns nothing
  if mission_unit[100]!=null then
    //call MAP_0()
    //set map=0
    call IssueImmediateOrder(mission_unit[100],"flamestrike")
  endif
endfunction

function MAP_Init takes nothing returns nothing
  local integer n=MAXPLAYERS

  if game_timer_class==null or not possible_rr or game_About2End then
    return
  endif
  if rounds>1 then
    call ExecuteFunc("GameNull")
  endif
  set mission_unit[100]=CreateUnit(Player(0),'hbar',0,0,0)
  call ExecuteFunc("Force5V5Start")
  set rounds=0
  set possible_rr=false
  call ExecuteFunc("RoundClear")
  call PauseTimer(game_timer_round)
  call PauseTimer(game_timer_class)
  call DestroyTimerDialog(game_td_round)
  call DestroyTimerDialog(game_td_class)
 
  call EnableWorldFogBoundary(false)
  call SetCameraBoundsToRect(bj_mapInitialPlayableArea)
  call ExecuteFunc("MAP_"+I2S(map))
  //set map=5
  call ExecuteFunc("MAP_ObsCam")
 
  loop
      set n=n-1
      exitwhen n<0
      if(GetPlayerSlotState(Player(n))==PLAYER_SLOT_STATE_PLAYING)then
        call SetUnitOwner(mission_unit[100],Player(n),false)
        //set n=0
      endif
  endloop
 
  if GetLocalPlayer()==GetOwningPlayer(mission_unit[100]) then
    call ClearSelection()
    call SelectUnit(mission_unit[100],true)
  endif
 
  call TimerStart(game_timer_map,MAP_SELECT,false,function MAP_Timer)
  set game_td_map=CreateTimerDialog(game_timer_map)
  call TimerDialogSetTitle(game_td_map,"Select Operation")
  call TimerDialogDisplay(game_td_map,true)
 
  call CameraSetSourceNoiseEx(1,5,true)
endfunction

endlibrary
//TESH.scrollpos=145
//TESH.alwaysfold=0
function InitTrig_vectorsystem takes nothing returns nothing
endfunction
//===========================================================================
library vectorsystem requires config



//  **********************
//  **  VECTOR SYSTEM   **
//  **********************

//  Original concept by iNfraNe
//  Then Made by Anitarf
// ported to structs by vexorian (actually just copied the math)


struct vector
   real x=0.
   real y=0.
   real z=0.

 


   private boolean safety=true

   private method onDestroy takes nothing returns nothing
       set this.safety=false
   endmethod

   method created takes nothing returns boolean
       return this.safety
   endmethod

   method length takes nothing returns real
       return SquareRoot(this.x*this.x + this.y*this.y+this.z*this.z)
   endmethod

   method lengthSquare takes nothing returns real
       return SquareRoot(this.x*this.x + this.y*this.y+this.z*this.z)
   endmethod
   
   method add takes vector B returns nothing
      set this.x=this.x+B.x
      set this.y=this.y+B.y
      set this.z=this.z+B.z
   endmethod


   method add_factored takes vector B, real fc returns nothing
      set this.x=this.x+fc*B.x
      set this.y=this.y+fc*B.y
      set this.z=this.z+fc*B.z
   endmethod

   method substract takes vector B returns nothing
      set this.x=this.x-B.x
      set this.y=this.y-B.y
      set this.z=this.z-B.z
   endmethod

   static method sum takes vector A, vector B returns vector
    local vector C=vector.create()

      set C.x=A.x+B.x
      set C.y=A.y+B.y
      set C.z=A.z+B.z
    return C
   endmethod

   static method difference takes vector A, vector B returns vector
    local vector C=vector.create()

      set C.x=A.x-B.x
      set C.y=A.y-B.y
      set C.z=A.z-B.z
    return C
   endmethod

   method scale takes real factor returns nothing
      set this.x=this.x*factor
      set this.y=this.y*factor
      set this.z=this.z*factor
   endmethod

   static method amplify takes vector A, real factor returns vector
    local vector C=vector.create()
      set C.x=A.x*factor
      set C.y=A.y*factor
      set C.z=A.z*factor
    return C
   endmethod

   static method productScalar takes vector A, vector B returns real
       return A.x*B.x+A.y*B.y+A.z*B.z
   endmethod

   method dot takes vector B returns real
       return this.x*B.x+this.y*B.y+this.z*B.z
   endmethod

   static method productVector takes vector A, vector B returns vector
    local vector C=vector.create()

       set C.x= A.y*B.z - A.z*B.y
       set C.y= A.z*B.x - A.x*B.z
       set C.z= A.x*B.y - A.y*B.x
    return C
   endmethod

   method project takes vector B returns vector
    local vector C=vector.create()
    local real r=this.dot(B)
    local real l=B.dot(B)
       if (l==0.) then
           return 0
       endif
    return vector.amplify(B,r/l)
   endmethod

   method projectPlane takes vector planeNormal returns vector
    local vector vect= this.project(planeNormal)
    local vector vect2= vector.difference(this,vect)
        call vect.destroy()
    return vect2
   endmethod


   method setLength takes real length returns boolean
    local real l=this.length()
       if (l==0) then
           return false
       endif
       call this.scale(length/l)
    return true
   endmethod

   method clone takes nothing returns vector
    local vector C=vector.create()
       set C.x=this.x
       set C.y=this.y
       set C.z=this.z
    return C
   endmethod

   static method angle takes vector A, vector B returns real
    local real l1=A.length()
    local real l2=B.length()
        if (l1==0) or (l2==0) then
            return 0.
        endif
        return Acos(vector.productScalar(A,B)/(l1*l2) )
   endmethod


   static method distance takes vector A, vector B returns real
       return SquareRoot((A.x-B.x)*(A.x-B.x)+(A.x-B.x)*(A.y-B.y)+(A.z-B.z)*(A.z-B.z))
   endmethod

   static method distanceSquare takes vector A, vector B returns real
       return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)+(A.z-B.z)*(A.z-B.z)
   endmethod


   method rotate takes vector axis, real angle returns vector
    local vector locX
    local vector locY
    local vector locZ= this.project(axis)
    local vector result

    if locZ == 0 then
        return 0
    endif
    set locX = vector.difference(this,locZ)
    set locY = vector.productVector(this, locX)
    call locY.setLength(locX.length())
    call locX.scale(Cos(angle))
    call locY.scale(Sin(angle))
    set result= vector.sum(locX,locY)
    call result.add(locZ)

    call locX.destroy()
    call locY.destroy()
    call locZ.destroy()

    return result
   endmethod

   static method createFrom takes real x, real y, real z returns vector
    local vector C=vector.create()
       set C.x=x
       set C.y=y
       set C.z=z
    return C
   endmethod

   static method getTerrainPosition takes real x, real y returns vector
    local vector C=vector.create()
       set C.x=x
       set C.y=y
       set C.z=GetZ(x,y)
    return C
   endmethod

   static method getTerrainNormal takes real x, real y, real sampleRadius returns vector
    local real z1=GetZ(x-sampleRadius,y)
    local real z2=GetZ(x+sampleRadius,y)
    local real z3=GetZ(x,y-sampleRadius)
    local real z4=GetZ(x,y+sampleRadius)
    local vector xvect=vector.createFrom(2*sampleRadius,0.,z2-z1)
    local vector yvect=vector.createFrom(0.,2*sampleRadius,z4-z3)
    local vector normvect=vector.productVector(xvect,yvect)

    call xvect.destroy()
    call yvect.destroy()
    return normvect
   endmethod

   method inCylinder takes vector cylinderOriginV, vector cylinderHeightV, real cylinderRadius returns boolean
    local vector v1
    local vector v2
    local vector v3
    local boolean b = false
    local real l = cylinderHeightV.length()
    if (l > 0.) then
        set v1=vector.difference(this, cylinderOriginV)
        set v2=vector.difference(v1, cylinderHeightV)
        set v3=v1.projectPlane( cylinderHeightV)
        if vector.productScalar(v1, cylinderHeightV)>=0 and vector.productScalar(v2, cylinderHeightV)<=0 and vector.productScalar(v3, v3)<=cylinderRadius*cylinderRadius then
            set b = true
        endif
        call v1.destroy()
        call v2.destroy()
        call v3.destroy()
    endif
    return b
   endmethod

   method move takes real x, real y, real z returns nothing
      set this.x=x
      set this.y=y
      set this.z=z
   endmethod

    method inCone takes vector coneOriginV, vector coneHeightV, vector coneRadius returns boolean
    local vector v1
    local vector v2
    local vector v3
    local vector v4
    local boolean b = false
    local real r
    local real l = coneHeightV.length()
    if (l>0.0) then
        set v1=vector.difference(this, coneOriginV)
        set v2=vector.difference(v1, coneHeightV)
        set v3=v1.project( coneHeightV)
        set v4=vector.difference(v1,v3)
        set r = 1.0-( v3.length()/l )
        if vector.productScalar(v1, coneHeightV)>=0 and v4.length()<=(coneRadius*r) then
            set b = true
        endif
        call v1.destroy()
        call v2.destroy()
        call v3.destroy()
        call v4.destroy()
    endif
    return b
    endmethod

    method inSphere takes vector sphereOriginV, real sphereRadius returns boolean
    local vector v
    local boolean b

        set v=vector.difference(this, sphereOriginV)
        set b= (vector.productScalar(v,v)<= sphereRadius*sphereRadius)
        call v.destroy()
    return b
    endmethod

   
   


endstruct




endlibrary


 
local label a
set a=label.Create(GetLocalPlayer(),0,10,10,"lol",15,255,255,0,128)
call a.timed(5,10)

//call SetTextTagPos(.t,GetCameraEyePositionX()+.x,GetCameraEyePositionY()+.y,GetCameraTargetPositionZ())
//TESH.scrollpos=186
//TESH.alwaysfold=0
function InitTrig_TextLabel takes nothing returns nothing
endfunction
//======================================================================
library Label initializer Init requires config

//######################################################################
//#
//# library Label
//#
//######################################################################

globals
  private constant real period=0.04
  private constant integer ui_bit=5
  private constant integer ui_all=100/ui_bit
  private constant string ui_char="||||"
  private label array mobs
  private integer N=0
  label LABELPROCESS
endglobals

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

function label_ui2 takes integer hp returns string
  local string r="[|c0000FF00|||||||||||r]"
  if hp<100 then
    set r="[|c0080FF00|||||||||||r]"
  endif
  if hp<90 then
    set r="[|c0080FF00|||||||||r|c00000000|||r]"
  endif
  if hp<75 then
    set r="[|c00FFF900|||||||r|c00000000|||||r]"
  endif
  if hp<50 then
    set r="[|c00FF8040|||||r|c00000000|||||||r]"
  endif
  if hp<25 then
    set r="[|c00FF0000|||r|c00000000|||||||||r]"
  endif
  if hp<10 then
    set r="[|c00000000|||||||||||r]"
  endif
  return r
endfunction

function label_ui takes integer hp returns string
  local string r=""
  local integer c=0
 
  if hp<=100 then
    set r=r+"|c0080FF00"
  endif
  if hp<90 then
    set r=r+"|c0080FF00"
  endif
  if hp<75 then
    set r=r+"|c00FFF900"
  endif
  if hp<60 then
    set r=r+"|c00FF8040"
  endif
  if hp<45 then
    set r=r+"|c00FF0000"
  endif
  if hp<25 then
    set r=r+"|c00800000"
  endif

  loop
      exitwhen hp<=0
      set r=r+ui_char
      set c=c+1
      set hp=hp-ui_bit
  endloop
  set r=r+"|r|c00000000"
  set c=ui_all-c
  loop
      exitwhen c<=0
      set r=r+ui_char
      set c=c-1
  endloop

  set r=r+"|r"
 
  return r
endfunction

struct label
  texttag t=null
  unit u=null
  real x
  real y
  real dur
  player p=null
  string text
  integer slot
  integer c
  boolean ui=false
  real size

  static method Create takes player p, integer slot, real x, real y, string text, real size, integer r, integer g, integer b returns label
    local label t=label.create()
    local integer i=0

    if slot<10 then
    loop
        exitwhen i==N
        if(mobs[i].p==p)then
          if(mobs[i].slot==slot)then
            if p==Player(11) then
              call SetTextTagVisibility(mobs[i].t,false)
            else
              //if GetLocalPlayer()==p then
              //  call SetTextTagVisibility(mobs[i].t,false)
              //endif
              set mobs[i].dur=0
            endif
          endif
        endif
        set i=i+1
    endloop
    endif

    set t.x=x
    set t.y=y
    set t.text=text
    set t.p=p
    set t.slot=slot
    set t.size=size
    set t.dur=1
    set t.c=0

    set t.t=CreateTextTag()
    call SetTextTagText(t.t,text,TextTagSize2Height(size))
    call SetTextTagPos(t.t,0,0,0)
    call SetTextTagColor(t.t,r,g,b,255)
    call SetTextTagPermanent(t.t,false)

    if p==Player(11) then
      call SetTextTagVisibility(t.t,true)
    else
      call SetTextTagVisibility(t.t,(GetLocalPlayer()==p))
    endif

    return t
  endmethod

  method timed takes real fadefrom, real fadeto returns nothing
    call SetTextTagFadepoint(.t,fadefrom)
    call SetTextTagLifespan(.t,fadeto+period)
    set .dur=fadeto
  endmethod

  method anim takes nothing returns boolean
    local real x
    local real y
    local real z
    //if GetLocalPlayer()==.p then
      if .u!=null then
        set x=GetUnitX(.u)
        set y=GetUnitY(.u)
        set z=GetUnitFlyHeight(.u)+GetZ(x,y)-GetZ(x+.x,y+.y)
        call SetTextTagPos(.t,x+.x,y+.y,z)
        if .ui then
          if .c<=0 then
            call SetTextTagText(.t,label_ui(R2I(GetUnitStatePercent(.u,UNIT_STATE_LIFE,UNIT_STATE_MAX_LIFE))),TextTagSize2Height(.size))
            set .c=10
          else
            set .c=.c-1
          endif
        endif
      else
        if GetLocalPlayer()==GetLocalPlayer() then
          set x=GetCameraTargetPositionX()
          set y=GetCameraTargetPositionY()
          set z=GetZ(x,y)-GetZ(x+.x,y+.y)
          call SetTextTagPos(.t,x+.x,y+.y,z)
          //GetCameraTargetPositionZ()/2
        endif
        set .dur=.dur-period
      endif
    //endif
    return (.dur<=0)//and not(.dur<-1)
  endmethod

  method onDestroy takes nothing returns nothing
    call SetTextTagPermanent(.t,false)
    call SetTextTagLifespan(.t,0.)
    //call DestroyTextTag(.t)
    set .t=null
    set .u=null
    set .p=null
  endmethod

endstruct



private function movelabels takes nothing returns nothing
  local integer i=0

    loop
        exitwhen i==N
        if (mobs[i].anim()) then
            call mobs[i].destroy()
            set mobs[i]=mobs[N-1]
            set N=N-1
        else
            set i=i+1
        endif
    endloop
endfunction

public function addlabel takes label t returns nothing
  set mobs[N]=t
  set N=N+1
endfunction

public function count takes nothing returns integer
    return N
endfunction

//######################################################################
//#
//# Init
//#
//######################################################################

private function Init takes nothing returns nothing
  set LABELPROCESS=label.Create(Player(11),-1,-315,-135,"0%",10,255,255,255)
  call SetTextTagPermanent(LABELPROCESS.t,true)
  set LABELPROCESS.dur=999
  call Label_addlabel(LABELPROCESS)
 
  call TimerStart(CreateTimer(),period,true,function movelabels)
endfunction

endlibrary
call CreateBloodsplat(GetUnitX(m.u)+GetRandomReal(-25,25),GetUnitY(m.u)+GetRandomReal(-25,25),GetRandomReal(.5,1))
call SetParticleSpeed(u,1500*CosBJ(a)*Cos(aoa),1500*SinBJ(a)*Cos(aoa),1500*Sin(aoa))
function SpellDummy takes player p,real x,real y,real z,integer id,string o,integer lvl,unit u,real timed returns boolean
static method Create takes player p, real x, real y, real z, real a returns wave
//if IsAnotherPlayer(m.u,picked) then

//endif
//set m.alpha=0
//set m.terminate=true
call IsShield(m.u,picked)
//set placeholdmobile=0

bombtime
//TESH.scrollpos=0
//TESH.alwaysfold=0
function InitTrig_spell takes nothing returns nothing
endfunction
//===========================================================================
library spell initializer Init requires Safety, vectorsystem, Label

globals
  private constant real period=0.025
  constant real fadeduration=0.5
  private mobile array mobs
  private integer N=0
 
  constant real spell_z=26
  constant integer ping_delay=3
 
  private unit placeholdunit2=null
  unit conunit=null
  real array filter_red
  real array filter_green
  real array filter_blue

  timer ta=null
  integer strike=0
  private integer FIX=1
 
  private integer MOVING=0
  private real turret_x=0
  private real turret_y=0
endglobals



function SpellDummy takes player p,real x,real y,real z,integer id,string o,integer lvl,unit u,real timed returns boolean
  local boolean b
  local unit d=CreateUnit(p,RAW_DUMMY,x,y,0)
  call SetUnitX(d,x)
  call SetUnitY(d,y)
  call SetUnitFlyHeight(d,z,0.)
  call UnitAddAbility(d,id)
  call SetUnitAbilityLevel(d,id,lvl)
  if timed==0 then
    set timed=3
  endif
  call UnitApplyTimedLife(d,0,timed)
  if u==null then
    set b=IssueImmediateOrder(d,o)
  else
    set b=IssueTargetOrder(d,o,u)
  endif
  set d=null
  return b
endfunction

function CreateBloodsplat takes real x, real y, real size returns nothing
  local integer id='B000'+GetRandomInt(0,3)
  call KillDestructable(CreateDestructable(id,x,y,GetRandomReal(0,360),size,1))
endfunction

function UnitColorByHP takes unit u returns nothing
  local real a=GetUnitState(u,UNIT_STATE_MAX_LIFE)
  local real b=GetWidgetLife(u)
  local integer r=R2I(255*((b)/(a))+.5) //b*b / a*a
  call SetUnitVertexColor(u,r,r,r,255)
  //call echo(GetUnitName(u)+": "+I2S(R2I(b))+"/"+I2S(R2I(a)))
endfunction

function UnitBurn takes unit c, unit u returns nothing
  call SpellDummy(GetOwningPlayer(c),GetUnitX(u),GetUnitY(u),0,'Auhf',"unholyfrenzy",1,u,16)
  return //necem to teraz
 
 
  if GetWidgetLife(u)>=100 then
    call SpellDummy(GetOwningPlayer(u),GetUnitX(u),GetUnitY(u),0,'Auhf',"unholyfrenzy",1,u,0)
    //call UnitAddAbility(u,'A001')
  else
    call SpellDummy(GetOwningPlayer(u),GetUnitX(u),GetUnitY(u),0,'Auhf',"unholyfrenzy",2,u,0)
    //call echo(R2S(GetWidgetLife(u)))
    call SetUnitVertexColor(u,0,0,0,255)
    call IssuePointOrder(u,"move",GetUnitX(u)+GetRandomReal(-10,10)*50,GetUnitY(u)+GetRandomReal(-10,10)*50)
    //call AddSpecialEffectTarget(MODEL_FIRE,u,"chest")
    //call AddSpecialEffectTarget(MODEL_FIRE,u,"origin")
    //call AddSpecialEffectTarget(MODEL_FIRE,u,"head")
    call UnitRemoveAbility(u,'Aatk')
    call UnitAddAbility(u,'Atwa')
    call UnitApplyTimedLife(u,0,GetRandomReal(8,14))
    call SetUnitPathing(u,true)
  endif
endfunction



function IsNonLocust takes unit u returns boolean
  return GetUnitAbilityLevel(u,'Aloc')==0
endfunction

function IsAnotherPlayer takes unit u, unit c returns boolean
  return GetOwningPlayer(u)!=GetOwningPlayer(c)
endfunction

function IsAlive takes unit u returns boolean
  return GetWidgetLife(u)>.405
endfunction

function IsGibbed takes unit u returns boolean
  return (not IsAlive(u) and IsUnitHidden(u))
endfunction

function IsWall takes unit u returns boolean
  return (GetUnitAbilityLevel(u,'Avul')==1 and not IsUnitHidden(u))or(GetUnitTypeId(u)=='h004')
endfunction

function IsAll takes nothing returns boolean
  return (IsAlive(GetFilterUnit()) and IsNonLocust(GetFilterUnit()) and not IsUnitHidden(GetFilterUnit()))
endfunction

function IsRespawnable takes nothing returns boolean
  //and GetPlayerSlotState(GetOwningPlayer(GetFilterUnit()))==PLAYER_SLOT_STATE_PLAYING
  return (IsUnitAlly(GetFilterUnit(),GetOwningPlayer(conunit)) and GetUnitUserData(GetFilterUnit())>0 and not IsAlive(GetFilterUnit()) and IsNonLocust(GetFilterUnit()) )
endfunction

function IsAlly takes nothing returns boolean
  return (IsAnotherPlayer(GetFilterUnit(),conunit) and IsUnitAlly(GetFilterUnit(),GetOwningPlayer(conunit)) and IsAlive(GetFilterUnit()) and IsNonLocust(GetFilterUnit()))
endfunction

function IsEnemy takes nothing returns boolean
  return (not IsUnitInvisible(GetFilterUnit(),GetOwningPlayer(conunit)) and IsAnotherPlayer(GetFilterUnit(),conunit) and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(conunit)) and IsAlive(GetFilterUnit()) )//and IsNonLocust(GetFilterUnit()))
endfunction

function IsOK takes nothing returns boolean
  return (IsAnotherPlayer(GetFilterUnit(),conunit) and IsAlive(GetFilterUnit()) and IsNonLocust(GetFilterUnit()))
endfunction

function IsEnemyNoMirror takes nothing returns boolean
  return (IsAnotherPlayer(GetFilterUnit(),conunit) and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(conunit)) and IsAlive(GetFilterUnit()) and IsNonLocust(GetFilterUnit()) and GetUnitTypeId(GetFilterUnit())!=RAW_MIRROR)
endfunction

function IsEnemyMelee takes nothing returns boolean
  return (not IsUnitInvisible(GetFilterUnit(),GetOwningPlayer(conunit)) and IsAnotherPlayer(GetFilterUnit(),conunit) and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(conunit)) and IsAlive(GetFilterUnit()) and IsNonLocust(GetFilterUnit()) and GetUnitTypeId(GetFilterUnit())!=RAW_MIRROR)
endfunction


function IsShield takes unit u, unit s returns boolean
  local missile m=GetUnitUserData(u)
  local Hero h
  if GetUnitTypeId(s)=='h004' then
    set m.a=2*(GetUnitFacing(s)+90)-(GetUnitFacing(u)+GetRandomReal(-25,25))
    call SetDummyFacing(u,m.a*bj_DEGTORAD)
    set m.timed=m.timed*.5
    set m.aux1=m.aux1*.66
    call SetUnitOwner(u,GetOwningPlayer(s),false) //Player(11)
    set h=player_PlayerHero[GetPlayerId(GetOwningPlayer(s))]
    call GroupAddUnit(m.g,h.u)
    return true
  endif
  return false
endfunction

function IsAbleToShot takes unit u returns boolean
  return (IsAlive(u) and u!=null)
endfunction


function Con takes nothing returns boolean
  return GetUnitTypeId(GetFilterUnit())!=RAW_DUMMY
endfunction

function DestroyBool takes boolexpr b returns nothing
  if b!=BOOLEXPR_TRUE and b!=BOOLEXPR_FALSE then
    call DestroyBoolExpr(b)
  endif
endfunction









interface mobile
  unit u
  integer red=255
  integer green=255
  integer blue=255
  integer alpha=255
  real aux1=0
  real aux2=0
  real aux3=0
  integer aux4=0
  boolean terminate=false

  method anim takes nothing returns boolean
  method fade takes nothing returns boolean
endinterface

private function movemobiles takes nothing returns nothing
  local integer i=0

    loop
        exitwhen i==N
        if (mobs[i].terminate) then
            if (mobs[i].fade()) then
                call mobs[i].destroy()
                set mobs[i]=mobs[N-1]
                set N=N-1
            else
                set i=i+1
            endif
        elseif (mobs[i].anim()) then
            if (mobs[i].fade()) then
                call mobs[i].destroy()
                set mobs[i]=mobs[N-1]
                set N=N-1
            else
                set i=i+1
            endif
        else
            set i=i+1
        endif
    endloop
endfunction

public function respawnmobiles takes nothing returns nothing
  local integer i=0

    loop
        exitwhen i==N
        //if not IsHeroUnitId(GetUnitTypeId(mobs[i].u)) then
        set mobs[i].terminate=true
        //endif
        set i=i+1
    endloop
endfunction

public function addmobile takes mobile m returns nothing
  set mobs[N]=m
  set N=N+1
endfunction

public function count takes nothing returns integer
    return N
endfunction




struct ray extends mobile
  real x1
  real y1
  real z1
  real x2
  real y2
  real z2
  real r=1
  real g=1
  real b=1
  real a=1
  lightning lx
  real timed=-1.
  real fadeduration=fadeduration
  string funcdeath="DoNothing"
  real random1=0
  real random2=0

  static method Create takes string id, real x1, real y1, real z1, real x2, real y2, real z2 returns ray
    local ray s=ray.create()
    set s.lx=AddLightningEx(id,false,x1,y1,z1,x2,y2,z2)
    set s.x1=x1
    set s.y1=y1
    set s.z1=z1
    set s.x2=x2
    set s.y2=y2
    set s.z2=z2
    return s
  endmethod

  method anim takes nothing returns boolean
    if .random1>0 or .random2>0 then
      call MoveLightningEx(.lx,false,.x1+GetRandomReal(-.random1,.random1),.y1+GetRandomReal(-.random1,.random1),.z1+GetRandomReal(-.random1,.random1),.x2+GetRandomReal(-.random2,.random2),.y2+GetRandomReal(-.random2,.random2),.z2+GetRandomReal(-.random2,.random2))
    endif
    if .timed!=-1. then
      set .timed=.timed-period
      if .timed<=0 then
        return true
      endif
      return false
    endif
    return true
  endmethod

  method fade takes nothing returns boolean
    set .a=.a-period/this.fadeduration
    if (.a<=0) then
      call SetLightningColor(.lx,.r,.g,.b,0)
      return true
    endif
    call SetLightningColor(.lx,.r,.g,.b,.a)
    return false
  endmethod

  method onDestroy takes nothing returns nothing
    set placeholdmobile=this
    call ExecuteFunc(.funcdeath)
    call DestroyLightning(.lx)
  endmethod

endstruct

struct ping extends mobile
  unit u
  integer t=ping_delay
  //lightning l1
  //lightning l2
  //lightning l3
  //lightning l4
  //lightning l5
  unit u1
  unit u2
  unit u3
  unit u4
  unit u5
  //string id="CLPB"
  real z=900
 
  static method Create takes unit u returns ping
    local ping s=ping.create()
    local real x=-6000
    local real y=4800
    local integer id='u000'
    set s.u=u

    set s.u1=CreateUnit(GetOwningPlayer(u),id,x,y,0)
    set s.u2=CreateUnit(GetOwningPlayer(u),id,x,y,0)
    set s.u3=CreateUnit(GetOwningPlayer(u),id,x,y,0)
    set s.u4=CreateUnit(GetOwningPlayer(u),id,x,y,0)
    set s.u5=CreateUnit(GetOwningPlayer(u),id,x,y,0)
    call SetUnitVertexColor(s.u1,0,0,0,0)
    call SetUnitVertexColor(s.u2,0,0,0,0)
    call SetUnitVertexColor(s.u3,0,0,0,0)
    call SetUnitVertexColor(s.u4,0,0,0,0)
    call SetUnitVertexColor(s.u5,0,0,0,0)
    //if GetLocalPlayer()==GetOwningPlayer(u) then
    //  call SetUnitVertexColor(s.u1,96,196,0,255)
    //  call SetUnitVertexColor(s.u2,96,196,0,255)
    //  call SetUnitVertexColor(s.u3,96,196,0,255)
    //  call SetUnitVertexColor(s.u4,96,196,0,255)
    //  call SetUnitVertexColor(s.u5,96,196,0,255)
    //endif
    return s
  endmethod
 
  method anim takes nothing returns boolean
    local integer i=0
    local real x
    local real y
    local real a
    local unit u
    local real d
    local real d1=300
    local real d2=800*800
    local real d3=d2+1000000
    local integer alpha=255
    local player p
    if IsAlive(.u) then
      if .t==0 then
        set .t=ping_delay
        if not IsUnitAlly(.u,Player(0)) then
          set i=5
        endif
       
        set x=GetUnitX(.u)
        set y=GetUnitY(.u)
        set p=GetOwningPlayer(.u)
        // ---------------------------
        set u=player_PlayerHero[0+i].u
        if .u!=u and u!=null and IsUnitAlly(u,p) then
          set d=SquareRoot((GetUnitX(u)-x)*(GetUnitX(u)-x)+(GetUnitY(u)-y)*(GetUnitY(u)-y))//-d3
          //set alpha=255-R2I(DamageArea(d,d2,255))
          //set alpha=255-R2I(DamageArea(d,d2,128))
          set a=Atan2(GetUnitY(u)-y,GetUnitX(u)-x)
          if d<d1 then
            call SetUnitX(.u1,GetUnitX(u))
            call SetUnitY(.u1,GetUnitY(u))
          else
            call SetUnitX(.u1,x+Cos(a)*d1)
            call SetUnitY(.u1,y+Sin(a)*d1)
          endif
          if GetLocalPlayer()==GetOwningPlayer(.u) then
            if IsAlive(u) then
              call SetUnitVertexColor(.u1,96,196,0,alpha)
            else
              if IsGibbed(u) then
                call SetUnitVertexColor(.u1,96,64,0,alpha)
              else
                call SetUnitVertexColor(.u1,255,8,0,alpha)
              endif
            endif
          endif
          //call MoveLightningEx(.l1,false,x+Cos(a)*d1,y+Sin(a)*d1,.z,x+Cos(a)*d2,y+Sin(a)*d2,.z)
        else
          call SetUnitVertexColor(.u1,0,0,0,0)
        endif
        // ---------------------------
        set u=player_PlayerHero[1+i].u
        if .u!=u and u!=null and IsUnitAlly(u,p) then
          set d=SquareRoot((GetUnitX(u)-x)*(GetUnitX(u)-x)+(GetUnitY(u)-y)*(GetUnitY(u)-y))//-d3
          //set alpha=255-R2I(DamageArea(d,d2,128))
          set a=Atan2(GetUnitY(u)-y,GetUnitX(u)-x)
          if d<d1 then
            call SetUnitX(.u2,GetUnitX(u))
            call SetUnitY(.u2,GetUnitY(u))
          else
            call SetUnitX(.u2,x+Cos(a)*d1)
            call SetUnitY(.u2,y+Sin(a)*d1)
          endif
          if GetLocalPlayer()==GetOwningPlayer(.u) then
            if IsAlive(u) then
              call SetUnitVertexColor(.u2,96,196,0,alpha)
           else
              if IsGibbed(u) then
                call SetUnitVertexColor(.u2,96,64,0,alpha)
              else
                call SetUnitVertexColor(.u2,255,8,0,alpha)
              endif
            endif
          endif
        else
          call SetUnitVertexColor(.u2,0,0,0,0)
        endif
        // ---------------------------
        set u=player_PlayerHero[2+i].u
        if .u!=u and u!=null and IsUnitAlly(u,p) then
          set d=SquareRoot((GetUnitX(u)-x)*(GetUnitX(u)-x)+(GetUnitY(u)-y)*(GetUnitY(u)-y))//-d3
          //set alpha=255-R2I(DamageArea(d,d2,128))
          set a=Atan2(GetUnitY(u)-y,GetUnitX(u)-x)
          if d<d1 then
            call SetUnitX(.u3,GetUnitX(u))
            call SetUnitY(.u3,GetUnitY(u))
          else
            call SetUnitX(.u3,x+Cos(a)*d1)
            call SetUnitY(.u3,y+Sin(a)*d1)
          endif
          if GetLocalPlayer()==GetOwningPlayer(.u) then
            if IsAlive(u) then
              call SetUnitVertexColor(.u3,96,196,0,alpha)
            else
              if IsGibbed(u) then
                call SetUnitVertexColor(.u3,96,64,0,alpha)
              else
                call SetUnitVertexColor(.u3,255,8,0,alpha)
              endif
            endif
          endif
        else
          call SetUnitVertexColor(.u3,0,0,0,0)
        endif
        // ---------------------------
        set u=player_PlayerHero[3+i].u
        if .u!=u and u!=null and IsUnitAlly(u,p) then
          set d=SquareRoot((GetUnitX(u)-x)*(GetUnitX(u)-x)+(GetUnitY(u)-y)*(GetUnitY(u)-y))//-d3
          //set alpha=255-R2I(DamageArea(d,d2,128))
          set a=Atan2(GetUnitY(u)-y,GetUnitX(u)-x)
          if d<d1 then
            call SetUnitX(.u4,GetUnitX(u))
            call SetUnitY(.u4,GetUnitY(u))
          else
            call SetUnitX(.u4,x+Cos(a)*d1)
            call SetUnitY(.u4,y+Sin(a)*d1)
          endif
          if GetLocalPlayer()==GetOwningPlayer(.u) then
            if IsAlive(u) then
              call SetUnitVertexColor(.u4,96,196,0,alpha)
            else
              if IsGibbed(u) then
                call SetUnitVertexColor(.u4,96,64,0,alpha)
              else
                call SetUnitVertexColor(.u4,255,8,0,alpha)
              endif
            endif
          endif
        else
          call SetUnitVertexColor(.u4,0,0,0,0)
        endif
        // ---------------------------
        set u=player_PlayerHero[4+i].u
        if .u!=u and u!=null and IsUnitAlly(u,p) then
          set d=SquareRoot((GetUnitX(u)-x)*(GetUnitX(u)-x)+(GetUnitY(u)-y)*(GetUnitY(u)-y))//-d3
          //set alpha=255-R2I(DamageArea(d,d2,128))
          set a=Atan2(GetUnitY(u)-y,GetUnitX(u)-x)
          if d<d1 then
            call SetUnitX(.u5,GetUnitX(u))
            call SetUnitY(.u5,GetUnitY(u))
          else
            call SetUnitX(.u5,x+Cos(a)*d1)
            call SetUnitY(.u5,y+Sin(a)*d1)
          endif
          if GetLocalPlayer()==GetOwningPlayer(.u) then
            if IsAlive(u) then
              call SetUnitVertexColor(.u5,96,196,0,alpha)
            else
              if IsGibbed(u) then
                call SetUnitVertexColor(.u5,96,64,0,alpha)
              else
                call SetUnitVertexColor(.u5,255,8,0,alpha)
              endif
            endif
          endif
        else
          call SetUnitVertexColor(.u5,0,0,0,0)
        endif

        set u=null
        set p=null
      else
        set .t=.t-1
      endif
      return false
    endif
    return true
  endmethod
 
  method fade takes nothing returns boolean
    return true
  endmethod
 
  method onDestroy takes nothing returns nothing
    call KillUnitA(.u1)
    call KillUnitA(.u2)
    call KillUnitA(.u3)
    call KillUnitA(.u4)
    call KillUnitA(.u5)
  endmethod
endstruct



function PingIcon takes integer p, string fx returns nothing
  local integer n=MAXPLAYERS/2
  local integer i=0
  local unit u=null
  local string s
   
  if IsPlayerInForce(Player(p),player_Force[1]) then
    set i=5
    set n=n+i
    set p=p-5
  endif
 
  loop
      exitwhen i==n
      if p==0 then
        set u=player_PlayerHero[i].ping.u1
      elseif p==1 then
        set u=player_PlayerHero[i].ping.u2
      elseif p==2 then
        set u=player_PlayerHero[i].ping.u3
      elseif p==3 then
        set u=player_PlayerHero[i].ping.u4
      elseif p==4 then
        set u=player_PlayerHero[i].ping.u5
      endif
      set s=""
      if fx==MODEL_ICON_DEATH then
        if GetLocalPlayer()==Player(i) and GetUnitTypeId(player_PlayerHero[i].u)==RAW_MEDIC then
          set s=fx
        endif
      else
        if GetLocalPlayer()==Player(i) then
          set s=fx
        endif
      endif
      call DestroyEffect(AddSpecialEffectTarget(s,u,"origin"))
      set i=i+1
  endloop
 
  set u=null
endfunction








struct blur extends mobile
  unit u
  effect fx
  real timed=1.
  real fadeduration=fadeduration
  string funcdeath="DoNothing"

  static method Create takes integer id, real x, real y, real z, real a, real aoa returns blur
    local blur s=blur.create()
    set s.u=CreateUnit(Player(15),id,x,y,a)
    call SetUnitX(s.u,x)
    call SetUnitY(s.u,y)
    call SetUnitAnimationByIndex(s.u,R2I(aoa*100+.5)+90)
    call UnitAddAbility(s.u,RAW_FLYHACK)
    call UnitRemoveAbility(s.u,RAW_FLYHACK)
    call SetUnitFlyHeight(s.u,z,0.)
    set s.fx=null
    return s
  endmethod

  method addfx takes string model, string part returns nothing
    if this.fx!=null then
      call DestroyEffect(this.fx)
    endif
    set this.fx=AddSpecialEffectTarget(model,this.u,part)
  endmethod

  method anim takes nothing returns boolean
    if this.timed!=-1. then
      set this.timed=this.timed-period
      if this.timed<=0 then
        return true
      endif
      return false
    endif
    return true
  endmethod

  method fade takes nothing returns boolean
    set this.alpha=this.alpha-R2I((255*period)/this.fadeduration)
    if (this.alpha<=0) then
      call SetUnitVertexColor(this.u,this.red,this.green,this.blue,0)
      return true
    endif
    call SetUnitVertexColor(this.u,this.red,this.green,this.blue,this.alpha)
    return false
  endmethod

   method onDestroy takes nothing returns nothing
     set placeholdmobile=this
     call ExecuteFunc(.funcdeath)
     call DestroyEffect(.fx)
     call KillUnitA(.u)
   endmethod

endstruct



struct foot extends mobile
  unit u
  unit detect=null
  unit shield=null
  item i_shield=null
  real x
  real y
  integer delay=0
  boolean moving=false
  boolean water=false
  unit vision

  static method Create takes unit u returns foot
    local foot s=foot.create()
    set s.u=u
    set s.x=GetUnitX(u)
    set s.y=GetUnitY(u)
    set s.vision=CreateUnit(GetOwningPlayer(u),'hphx',s.x,s.y,0)
    if mod==3 then
      set s.detect=CreateUnit(GetOwningPlayer(u),RAW_DUMMY,s.x,s.y,270)
      call UnitAddAbility(s.detect,'AId2')
      call SetUnitVertexColor(s.detect,0,0,0,0)
    endif
    return s
  endmethod
 
  method anim takes nothing returns boolean
    local real x=GetUnitX(.u)
    local real y=GetUnitY(.u)
    local real a
    local integer t
    local string s
    local sound snd
    local boolean b=GetUnitTypeId(.u)!=RAW_CLOAKED
    local boolean b2
    local Hero h=GetUnitUserData(.u)

    if .u==null then
      return true
    endif
   
    if AI_active[GetPlayerId(GetOwningPlayer(.u))]==false then
      if not IsUnitSelected(.u,GetOwningPlayer(.u)) then
        set h.selected=false
        call UnitRemoveItem(.u,h.i_weapon)
        call SetItemVisible(h.i_weapon,false)
      else
        if h.selected==false then
          call UnitRemoveItemFromSlot(.u,0)
          call SetItemVisible(h.i_weapon,true)
          call UnitAddItem(.u,h.i_weapon)
          set h.selected=true
        endif
      endif
    endif
   
    if GetUnitAbilityLevel(.u,'AId0')>0 then
      set a=GetUnitFacing(.u)
      if .moving then
        set a=a+15
      endif
      if .shield==null then
        set .shield=CreateUnit(GetOwningPlayer(.u),'h004',x,y,a)
        if GetItemCharges(.i_shield)>0 then
          call SetWidgetLife(.shield,GetItemCharges(.i_shield))
        endif
        //call SetUnitPathing(.shield,true)
      elseif not IsAlive(.shield) then
        call RemoveItem(.i_shield)
        call AddSound(.shield,"Abilities\\Spells\\Other\\FrostBolt\\FrostBoltHit1.wav")
      endif
      call SetUnitX(.shield,x+CosBJ(a)*50)
      call SetUnitY(.shield,y+SinBJ(a)*50)
      call SetUnitFacing(.shield,a)
      call SetItemCharges(.i_shield,R2I(GetWidgetLife(.shield)+.5))
    else
      call KillUnitA(.shield)
      set .shield=null
    endif
   
    if not b then
      call SetUnitState(.u,UNIT_STATE_MANA,GetUnitState(.u,UNIT_STATE_MANA)-0.4)
      if GetUnitState(.u,UNIT_STATE_MANA)<1.01 then
        call IssueImmediateOrder(.u,"unstoneform")
      endif
    endif
   
    //tower increased vision
    //if GetUnitAbilityLevel(this.u,'BOae')==1 then
    //  call UnitAddAbility(.vision,'AIsi')
    //else
    //  call UnitRemoveAbility(.vision,'AIsi')
    //endif
    call SetUnitX(.vision,x)
    call SetUnitY(.vision,y)
    if mod==3 and replay_game and IsAlive(.u) then
      call SetUnitX(.detect,x)
      call SetUnitY(.detect,y)
      set b2=IsPlayerInForce(GetLocalPlayer(),player_Force[1])
      if b2 and IsUnitFogged(.u,GetLocalPlayer()) then
        call SetUnitVertexColor(.detect,255,255,255,255)
        call SetTextTagVisibility(h.namepointer.t,false)
        call SetTextTagVisibility(h.hppointer.t,false)
      elseif b2 then
        call SetUnitVertexColor(.detect,0,0,0,0)
        call SetTextTagVisibility(h.namepointer.t,true)
        call SetTextTagVisibility(h.hppointer.t,true)
      else
        call SetUnitVertexColor(.detect,0,0,0,0)
      endif
    endif
   
    set this.delay=this.delay-1
    // *'Adrt'  *'Adrd' *'Agrs' 'Arck' *'Agrd' *'Adrg' 'Alvd'
    if this.delay<=0 then
   
      if (x!=this.x or y!=this.y) and GetUnitFlyHeight(this.u)<1 then
        if not this.moving then
          set this.moving=true
          set MOVING=MOVING+1
        endif
     
        set this.delay=R2I(6000/GetUnitMoveSpeed(this.u))
       
        if b then//
          call SetUnitVertexColor(this.u,255,255,255,255)
       
        if not IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
          if not this.water then
            set s="Sound\\Step\\inwater.wav"
            set this.water=true
          else
            set s="Sound\\Step\\Slosh"+I2S(GetRandomInt(1,4))+".wav"
          endif
          call DestroyEffect(AddSpecialEffect(MODEL_WATER_SPLASH,x,y))
        else
          set this.water=false
          set t=GetTerrainType(x,y)
          if t=='Adrt' or t=='Adrg' then
            set s="Sound\\Step\\Dirt"+I2S(GetRandomInt(1,4))+".wav"
          elseif t=='Agrs' or t=='Agrd' then
            set s="Sound\\Step\\Grass"+I2S(GetRandomInt(1,4))+".wav"
          elseif t=='Arck' or t=='Adrd' then
            set s="Sound\\Step\\Gravel"+I2S(GetRandomInt(1,4))+".wav"
          else
            set s="Sound\\Step\\Dirt"+I2S(GetRandomInt(1,4))+".wav"
          endif
          //call DestroyEffect(AddSpecialEffect(MODEL_DUST_SPLASH,x,y))
        endif
       
        set snd=CreateSound(s,false,true,false,10,10,"MissilesEAX")
        //call SetSoundDuration(snd,GetSoundDuration(snd)-MOVING*40)
        call SetSoundPitch(snd,GetRandomReal(0.8,1.1))
        call SetSoundVolume(snd,127)
        call SetSoundDistances(snd,100,1200)
        call SetSoundDistanceCutoff(snd,1200)
        call AttachSoundToUnit(snd,this.u)
        call StartSound(snd)
        call KillSoundWhenDone(snd)
        set snd=null
        else
          call SetUnitVertexColor(this.u,72,200,64,60) // cloaked (moving)
        endif
      else
        if b then
          if GetUnitAbilityLevel(this.u,'BEar')==1 then
            call SetUnitVertexColor(this.u,255,255,255,100) // normal (cover)
            //call UnitAddAbility(this.u,'AId3')
          else
            call SetUnitVertexColor(this.u,255,255,255,255) // normal
            //call UnitRemoveAbility(this.u,'AId3')
          endif
        else
          call SetUnitVertexColor(this.u,72,255,64,20) // cloaked (standing)
        endif
        if this.moving then
          set this.moving=false
          set MOVING=MOVING-1
        endif
      endif
     
      if GetUnitAbilityLevel(this.u,'AIlf')==1 or GetUnitAbilityLevel(this.u,'B004')==1 then
        call SetUnitVertexColor(this.u,255,16,16,255) // painkiller
      endif
     
      //if GetWidgetLife(this.u)<.405 then
      //  return true
      //endif
     
    endif
   
    if GetWidgetLife(this.u)<.405 then
      return true
    endif
   
    set this.x=x
    set this.y=y
   
    return false
  endmethod

  method fade takes nothing returns boolean
    return true
  endmethod

  method onDestroy takes nothing returns nothing
    //call KillUnitA(.vision)
    call SetUnitExploded(.vision,true)
    call UnitApplyTimedLife(.vision,0,2)
    call KillUnitA(.shield)
    call RemoveItem(.i_shield)
    call KillUnitA(.detect)
  endmethod
 
endstruct

struct mover extends mobile
  unit u
  unit target=null
  unit target2=null
  real vx=0
  real vy=0
  real vz=0
  real x
  real y
  real z
  real range=0
  real G=-20
  real timed=-1.
  effect fx
  group g
  boolean vertical=true
  boolean horizontal=true
  boolean zangle=false

  string funchit="DoNothing"
  boolexpr conhit=BOOLEXPR_FALSE
  string funcimpact="DoNothing"
  string funcgen="DoNothing"
  string funcdeath="DoNothing"
  real gen=-1.
  real geno=-1.



  static method Create takes unit u returns mover
    local mover s=mover.create()
    set s.u=u
    set s.x=GetUnitX(u)
    set s.y=GetUnitY(u)
    set s.z=GetZ(s.x,s.y)+GetUnitFlyHeight(u)
    call UnitAddAbility(u,RAW_FLYHACK)
    call UnitRemoveAbility(u,RAW_FLYHACK)
    set s.g=CreateGroup()
    call SetUnitPathing(u,false)
    call SetUnitX(s.u,s.x)
    call SetUnitY(s.u,s.y)
    set s.target=null
    return s
  endmethod

  method addfx takes string model, string part returns nothing
    if .fx!=null then
      call DestroyEffect(.fx)
    endif
    set .fx=AddSpecialEffectTarget(model,.u,part)
  endmethod

  private method collision takes nothing returns boolean
    local boolean r=false
    local unit picked
    local real z1
    local real z2=GetUnitFlyHeight(this.u)
    local real zz=20+RAbsBJ(.range*2)
    local boolexpr con=Condition(function Con)
    local group g=CreateGroup()
    call GroupEnumUnitsInRange(g,this.x,this.y,this.range,con)//this.conhit)
    call DestroyBool(con)
    set con=null
    call GroupRemoveUnit(g,this.u)
    loop
        set picked=FirstOfGroup(g)
        exitwhen (picked==null or placeholdmobile==0)
        if(not IsUnitInGroup(picked,this.g) and not IsUnitHidden(picked))then
          set z1=GetUnitFlyHeight(picked)+UNIT_HEIGHT
          //call BJDebugMsg("z1:"+R2S(z1) + "   " + "z2:"+R2S(z2))
          if z1<=z2+zz and z1>=z2-zz then
            set placeholdunit=picked
            set r=true
            call ExecuteFunc(this.funchit)
          endif
        endif
        call GroupRemoveUnit(g,picked)
    endloop
    call DestroyGroup(g)
    set g=null
    set picked=null
    return r
  endmethod
 
  method anim takes nothing returns boolean
    local real Gz=0
    local real a
    local real aoa

    call SetUnitPathing(this.u,false)
    set placeholdmobile=this
    set conunit=this.u

    if this.timed!=-1. then
      set this.timed=this.timed-period
      if this.timed<=0 then
        //call BJDebugMsg("missile: time expired")
        call ExecuteFunc(this.funcimpact)
        return true
      endif
    endif
   
    if this.gen!=-1. then
      set this.gen=this.gen-period
      if this.gen<=0 then
        call ExecuteFunc(this.funcgen)
        set this.gen=this.geno
      endif
    endif

    if this.horizontal then
      set this.x=this.x + this.vx*period
      set this.y=this.y + this.vy*period
    else
      set this.x=GetUnitX(this.u)
      set this.y=GetUnitY(this.u)
    endif
    set this.z=this.z + this.vz*period
    set Gz=GetZ(this.x,this.y)
    if this.z>UNIT_MAX_HEIGHT+Gz then
      set this.z=UNIT_MAX_HEIGHT+Gz
      set this.vz=-this.vz
    endif
    set this.vz=this.vz+this.G

//    if(this.x>MAX_X) or (this.y>MAX_Y) or (this.x<MIN_X) or (this.y<MIN_Y)then
    if IsTerrainPathable(.x,.y,PATHING_TYPE_FLYABILITY) then
      if this.horizontal then

        if (this.vx > 0. and IsTerrainPathable(this.x+8,this.y,PATHING_TYPE_FLYABILITY)) or (this.vx < 0. and IsTerrainPathable(this.x-8,this.y,PATHING_TYPE_FLYABILITY)) then
          set this.vx=-this.vx
        endif

        if (this.vy > 0. and IsTerrainPathable(this.x,this.y+8,PATHING_TYPE_FLYABILITY)) or (this.vy < 0. and IsTerrainPathable(this.x,this.y-8,PATHING_TYPE_FLYABILITY)) then
          set this.vy=-this.vy
        endif

      else
        set a=GetUnitFacing(this.u)

        if (this.vx > 0. and IsTerrainPathable(this.x+8,this.y,PATHING_TYPE_FLYABILITY)) or (this.vx < 0. and IsTerrainPathable(this.x-8,this.y,PATHING_TYPE_FLYABILITY)) then
          call echo("bounce X")
          set this.vx=CosBJ(-a)*600
        else
          set this.vx=CosBJ(a)*600
        endif

        if (this.vy > 0. and IsTerrainPathable(this.x,this.y+8,PATHING_TYPE_FLYABILITY)) or (this.vy < 0. and IsTerrainPathable(this.x,this.y-8,PATHING_TYPE_FLYABILITY)) then
          call echo("bounce Y")
          set this.vy=SinBJ(-a)*600
        else
          set this.vy=SinBJ(a)*600
        endif

        //set this.vz=this.G
        set this.horizontal=true
      endif
      set this.x=this.x + this.vx*period
      set this.y=this.y + this.vy*period
    endif
    if(this.z<Gz)then
      call ExecuteFunc(this.funcimpact)
      //call BJDebugMsg("missile: out of map")
      return false
    endif

    if this.fx!=null and this.zangle then
      set aoa=Atan2(.vz,SquareRoot(.vx*.vx+.vy*.vy))
      call SetUnitAnimationByIndex(.u,R2I(aoa*50+.5)+90) //aoa*100+.5
    endif
    if this.horizontal then
      call SetUnitX(.u,.x)
      call SetUnitY(.u,.y)
    endif
    if this.vertical then
      call SetUnitFlyHeight(.u,.z-Gz,0)
    else
      call SetUnitFlyHeight(.u,.0,0)
    endif

    //call SetUnitFacing(this.u,a)

    if this.range>0. then
      //set conunit=this.u
      if this.collision() then
        //call ExecuteFunc(this.funchit)
        return this.terminate
      endif
    endif

    return false
  endmethod

  method fade takes nothing returns boolean
    return true
  endmethod

  method onDestroy takes nothing returns nothing
    set placeholdmobile=this
    call ExecuteFunc(.funcdeath)
    call DestroyBool(.conhit)
    call DestroyEffect(.fx)
    call DestroyGroup(.g)
    //call KillUnitA(.u)
    call SetUnitPathing(.u,true)
  endmethod

endstruct

struct missile extends mobile
  unit u
  unit target=null
  unit target2=null
  real speed
  real x
  real y
  real z
  real a
  real G=-0.1
  real range
  real timed=-1.
  effect fx
  group g

  string funchit="DoNothing"
  boolexpr conhit=BOOLEXPR_FALSE
  string funcimpact="DoNothing"
  string funcgen="DoNothing"
  string funcdeath="DoNothing"
  real gen=-1.
  real geno=-1.



  static method Create takes player p, real x, real y, real z, real a returns missile
    local missile s=missile.create()
    set s.u=CreateUnit(p,RAW_DUMMY,x,y,a)
    call SetUnitX(s.u,x)
    call SetUnitY(s.u,y)
    call SetUnitAnimationByIndex(s.u,90)
    call UnitAddAbility(s.u,RAW_FLYHACK)
    call UnitRemoveAbility(s.u,RAW_FLYHACK)
    call SetUnitFlyHeight(s.u,z,0.)
    set s.x=x
    set s.y=y
    set s.z=z+GetZ(x,y)
    set s.a=-1.
    set s.target=null
    set s.fx=null
    set s.g=CreateGroup()
    call SetUnitUserData(s.u,s)
    return s
  endmethod

  method addfx takes string model, string part returns nothing
    if this.fx!=null then
      call DestroyEffect(this.fx)
    endif
    set this.fx=AddSpecialEffectTarget(model,this.u,part)
  endmethod

  private method collision takes nothing returns boolean
    local boolean r=false
    local unit picked
    local real z1
    local real z2=GetUnitFlyHeight(this.u)
    local real zz=this.range+20//this.speed*period*10
    local boolexpr con=Condition(function Con)
    local group g=CreateGroup()
    call GroupEnumUnitsInRange(g,this.x,this.y,this.range,con)//this.conhit)
    call DestroyBool(con)
    set con=null
    call GroupRemoveUnit(g,this.u)
    loop
        set picked=FirstOfGroup(g)
        exitwhen (picked==null or placeholdmobile==0)
        if(not IsUnitInGroup(picked,this.g) and not IsUnitHidden(picked))then
          set z1=GetUnitFlyHeight(picked)+UNIT_HEIGHT
          //call BJDebugMsg("z1:"+R2S(z1) + "   " + "z2:"+R2S(z2))
          if z1<=z2+zz and z1>=z2-zz then
            set placeholdunit=picked
            set r=true
            call ExecuteFunc(this.funchit)
          endif
        endif
        call GroupRemoveUnit(g,picked)
    endloop
    call DestroyGroup(g)
    set g=null
    set picked=null
    return r
  endmethod

  method anim takes nothing returns boolean
    local real x=0
    local real y=0
    local real z=0
    local real Gz=0
    local real a
    local real aoa

    set placeholdmobile=this
    set conunit=this.u

    if this.timed!=-1. then
      set this.timed=this.timed-period
      if this.timed<=0 then
        //call BJDebugMsg("missile: time expired")
        call ExecuteFunc(this.funcimpact)
        return true
      endif
    endif

    if this.gen!=-1. then
      set this.gen=this.gen-period
      if this.gen<=0 then
        call ExecuteFunc(this.funcgen)
        if this.terminate then
          return true
        endif
        set this.gen=this.geno
      endif
    endif

    if this.target!=null and IsAlive(this.target) then
      set x=GetUnitX(this.target)-this.x
      set y=GetUnitY(this.target)-this.y
      set z=UNIT_HEIGHT+GetZ(GetUnitX(this.target),GetUnitY(this.target))+GetUnitFlyHeight(this.target)-this.z
      set a=Atan2(y,x)*bj_RADTODEG
      set aoa=Atan2(z,SquareRoot(x*x+y*y))
      //call BJDebugMsg("missile: target found")
    else
      set a=GetUnitFacing(this.u)
      set aoa=this.G
      //call BJDebugMsg("missile: no target")
    endif
    if .a!=-1. then
      set a=.a
    endif
    set this.x=this.x + Cos(a*bj_DEGTORAD)*this.speed*period
    set this.y=this.y + Sin(a*bj_DEGTORAD)*this.speed*period
    set this.z=this.z + Sin(aoa)*this.speed*period

    set Gz=GetZ(this.x,this.y)
    if (this.x>MAX_X) or (this.y>MAX_Y) or (this.x<MIN_X) or (this.y<MIN_Y) or (this.z<Gz) then
      call ExecuteFunc(this.funcimpact)
      //call BJDebugMsg("missile: out of map")
      return true
    endif

    call SetUnitX(this.u,this.x)
    call SetUnitY(this.u,this.y)
    call SetUnitFlyHeight(this.u,this.z-Gz,0.)
    if this.fx!=null then
      call SetUnitAnimationByIndex(this.u,R2I(aoa*50+.5)+90) //aoa*100+.5
    endif
    if this.a!=-1. then
      call SetUnitFacing(this.u,a)
    endif

    if this.range>0. then
      //set conunit=this.u
      if this.collision() then
        //call BJDebugMsg("missile: collision")
        //call ExecuteFunc(this.funchit)
        //return true
        return this.terminate
      endif
    endif

    return false
  endmethod

  method fade takes nothing returns boolean
    set this.alpha=this.alpha-R2I((255*period)/fadeduration)
    if (this.alpha<=0) then
      call SetUnitVertexColor(this.u,this.red,this.green,this.blue,0)
      return true
    endif
    call SetUnitVertexColor(this.u,this.red,this.green,this.blue,this.alpha)
    return false
  endmethod

  method onDestroy takes nothing returns nothing
    set placeholdmobile=this
    call ExecuteFunc(.funcdeath)
    call DestroyBool(this.conhit)
    call DestroyEffect(this.fx)
    call DestroyGroup(this.g)
    call KillUnitA(this.u)
  endmethod

endstruct



struct wave extends mobile
  unit u
  unit target
  real tx
  real ty
  real speed=0
  real x
  real y
  real z
  real range
  real timed=-1.
  effect fx
  group g

  string funchit="DoNothing"
  boolexpr conhit=BOOLEXPR_FALSE
  string funcimpact="DoNothing"
  string funcgen="DoNothing"
  real gen=-1.
  real geno=-1.


  static method Create takes player p, real x, real y, real z, real a returns wave
    local wave s=wave.create()
    set s.u=CreateUnit(p,RAW_DUMMY,x,y,a)
    call SetUnitX(s.u,x)
    call SetUnitY(s.u,y)
    call SetUnitAnimationByIndex(s.u,90)
    call UnitAddAbility(s.u,RAW_FLYHACK)
    call UnitRemoveAbility(s.u,RAW_FLYHACK)
    call SetUnitFlyHeight(s.u,z,0.)
    set s.x=x
    set s.y=y
    set s.z=z
    set s.tx=x
    set s.ty=y
    set s.target=null
    set s.fx=null
    set s.g=CreateGroup()
    return s
  endmethod

  method addfx takes string model, string part returns nothing
    if this.fx!=null then
      call DestroyEffect(this.fx)
    endif
    set this.fx=AddSpecialEffectTarget(model,this.u,part)
  endmethod

  private method collision takes nothing returns boolean
    local boolean r=false
    local unit picked
    local group g=CreateGroup()

    call GroupEnumUnitsInRange(g,this.x,this.y,this.range,this.conhit)
    call GroupRemoveUnit(g,this.u)
    loop
        set picked=FirstOfGroup(g)
        exitwhen picked==null
        if not IsUnitInGroup(picked,this.g) and not IsUnitHidden(picked) then
          set r=true
          set placeholdunit=picked
          call ExecuteFunc(this.funchit)
        endif
        call GroupRemoveUnit(g,picked)
    endloop
    call DestroyGroup(g)
    set g=null
    set picked=null
    return r
  endmethod

  method anim takes nothing returns boolean
    local real x=0
    local real y=0
    local real a=0

    set placeholdmobile=this
    set conunit=.u

    if this.timed!=-1. then
      set this.timed=this.timed-period
      if this.timed<=0 then
        call ExecuteFunc(this.funcimpact)
        return true
      endif
    endif

    if this.gen!=-1. then
      set this.gen=this.gen-period
      if this.gen<=0 then
        call ExecuteFunc(this.funcgen)
        if this.terminate then
          return true
        endif
        set this.gen=this.geno
      endif
    endif

    if this.target!=null and IsAlive(this.target) then
      set x=GetUnitX(this.target)-this.x
      set y=GetUnitY(this.target)-this.y
      set a=Atan2(y,x)*bj_RADTODEG
      //call BJDebugMsg("missile: target found")
    else
      set x=this.tx-this.x
      set y=this.ty-this.y
      set this.tx=this.tx+x
      set this.ty=this.ty+y
      set a=Atan2(y,x)*bj_RADTODEG
      //call BJDebugMsg("missile: no target")
    endif
   
if .speed>0. then
    set this.x=this.x + Cos(a*bj_DEGTORAD)*this.speed*period
    set this.y=this.y + Sin(a*bj_DEGTORAD)*this.speed*period

    if (this.x>MAX_X) or (this.y>MAX_Y) or (this.x<MIN_X) or (this.y<MIN_Y) then
      call ExecuteFunc(this.funcimpact)
      //call BJDebugMsg("missile: out of map")
      return true
    endif

    call SetUnitX(this.u,this.x)
    call SetUnitY(this.u,this.y)
    call SetUnitFacing(this.u,a)
endif
   
    if this.range>0. then
      if this.collision() then
        return this.terminate
      endif
    endif

    return false
  endmethod

  method fade takes nothing returns boolean
    set this.alpha=this.alpha-R2I((255*period)/fadeduration)
    if (this.alpha<=0) then
      call SetUnitVertexColor(this.u,this.red,this.green,this.blue,0)
      return true
    endif
    call SetUnitVertexColor(this.u,this.red,this.green,this.blue,this.alpha)
    return false
  endmethod

   method onDestroy takes nothing returns nothing
     call DestroyBool(this.conhit)
     call DestroyEffect(this.fx)
     call DestroyGroup(this.g)
     call KillUnitA(this.u)
   endmethod

endstruct








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

function SpellGibDeath takes nothing returns nothing
  local mover m=placeholdmobile
  set m.terminate=true
  call KillUnitA(m.u)
endfunction

function SpellGibImpact takes nothing returns nothing
  local mover m=placeholdmobile
  call CreateBloodsplat(GetUnitX(m.u),GetUnitY(m.u),GetRandomReal(1.6,1.8))
  set m.timed=1.2
  set m.funcimpact="DoNothing"
  call SetUnitVertexColor(m.u,255,255,255,0)
endfunction

function CreateGib takes real x, real y, real z, real a, real v returns nothing
  local mover s
  local unit c
  local real array V
  local real aoa=.3
  local real spread=150.
  local integer n=10
  local blur t

  set V[5]=a
  set V[1]=v

  loop
      exitwhen n<=0
      set a=V[5]+GetRandomReal(-spread,spread)
      set v=V[1]*GetRandomReal(0.66,1.)
      set c=CreateUnit(Player(15),RAW_DUMMY,x,y,a)
      set s=mover.Create(c)
      call s.addfx(MODEL_BONES,"origin")
      set a=a*bj_DEGTORAD
      set s.z=s.z+z
      set s.vx=Cos(a)*v
      set s.vy=Sin(a)*v
      set s.vz=Sin(aoa+GetRandomReal(-spread,spread*2)*0.05)*v
      set s.G=-15
      set s.funcimpact="SpellGibImpact"
      //set s.funchit="SpellShardHit"
      //set s.conhit=Condition(function IsEnemy)
      set s.funcdeath="SpellGibDeath"
      call SetUnitAnimationByIndex(s.u,90)
      call addmobile(s)
      //set s.range=0.
      //set s.aux1=1
      set n=n-1
  endloop
  call AddSound(c,SOUND_GIBS)
  set c=null
 
  set t=blur.Create(RAW_DUMMY,x,y,z+15,GetRandomReal(0,360),0)
  set t.fadeduration=1
  call t.addfx("Model\\GibSplash.mdl","origin")
  call addmobile(t)
  call SetUnitScale(t.u,6,0,0)
endfunction

function CreateBeep takes unit a, unit b returns nothing
  local integer id=GetUnitTypeId(b)
  if IsUnitFogged(b,GetOwningPlayer(a)) and not IsWall(b) then
    call AddSound2D(GetOwningPlayer(a),"Sound\\hit.mp3")
  endif
  if id=='hwtw' or id=='hgtw' then //id=='ncg3'
    call UnitColorByHP(b)
  endif
endfunction

function DrugAilments takes player p returns nothing
  local integer e=GetPlayerId(p)
  local integer dep=player_drug[e]
  local integer i=GetRandomInt(1,3)
  local Hero h
 
  if dep>500 then
    set h=player_PlayerHero[e]
 
    if i==1 then //headache
      set i=GetRandomInt(0,100+R2I(dep*.01))
      if i>85 then
        call msg(p,"|c00FF0000Drug related:|r You've got a headache","")
        call SpellDummy(p,GetUnitX(h.u),GetUnitY(h.u),0,'ANmr',"mindrot",1,h.u,.5)
      endif
    elseif i==2 then //sleep
      set i=GetRandomInt(0,100+R2I(dep*.01))
      if i>110 then
        call msg(p,"|c00FF0000Drug related:|r You've fell into sleep","")
        call SpellDummy(p,GetUnitX(h.u),GetUnitY(h.u),0,'ACsl',"sleep",1,h.u,.5)
      endif
    elseif i==3 then //pain
      set i=GetRandomInt(0,100+R2I(dep*.01))
      if i>100 then
        call msg(p,"|c00FF0000Drug related:|r You suddenly feel pain","")
        call SpellDummy(p,GetUnitX(h.u),GetUnitY(h.u),0,'Aslo',"slow",2,h.u,.5)
        call UnitRemoveAbility(h.u,'Bbsk') //stimpack
      endif
    endif
  endif
endfunction
//------------------------------------------------------------




function SpellBarrageImpact takes nothing returns nothing
  local mover m=placeholdmobile
  local real x=GetUnitX(m.u)
  local real y=GetUnitY(m.u)
  local group g=CreateGroup()
  local boolexpr filter
  local real factor
  local unit c
  local blur s
  local vector a=vector.createFrom(x,y,GetZ(x,y)+GetUnitFlyHeight(m.u))
  local vector b=vector.create()
 
  set filter=Condition(function IsAll)

  call GroupEnumUnitsInRange(g,x,y,250,filter)
  call DestroyBoolExpr(filter)
  set filter=null
  call GroupRemoveUnit(g,m.u)

  loop
      set c=FirstOfGroup(g)
      exitwhen c==null
      call GroupRemoveUnit(g,c)
      set b.x=GetUnitX(c)
      set b.y=GetUnitY(c)
      set b.z=GetZ(GetUnitX(c),GetUnitY(c))+GetUnitFlyHeight(c)
      set factor=1
      if GetUnitAbilityLevel(c,'AId4')>0 then
          set factor=.75
      endif
      call UnitDamageTarget(m.u,c,DamageArea(vector.distance(a,b),300,250)*factor,false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC,null)
      // Blood
      if not IsUnitType(c,UNIT_TYPE_MECHANICAL) then
        if not IsAlive(c) then
          call CreateGib(GetUnitX(c),GetUnitY(c),GetUnitFlyHeight(c),-GetUnitFacing(c),300)
          call KillUnitA(c)
        else
          call DestroyEffect(AddSpecialEffectTarget(MODEL_BLOOD,c,"chest"))
          call CreateBloodsplat(GetUnitX(c),GetUnitY(c),GetRandomReal(0.9,1.2))
        endif
      endif
      call CreateBeep(m.u,c)
  endloop
  call DestroyGroup(g)
  set g=null
  call a.destroy()
  call b.destroy()
 
  call EnumDestructablesInCircle(x,y,250,function TreeKill)
  call EnumDestructablesInCircle(x,y,500,function TreeShake)
 
  set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+12,GetRandomReal(0,360),0)
  set s.fadeduration=20
  //if GetUnitFlyHeight(s.u)>40 then
  //  call s.addfx(MODEL_EXPLO_AIR,"origin")
  //else
    //call s.addfx(MODEL_EXPLO_GROUND,"origin")
    call s.addfx("Model\\EXground2.mdl","origin")
  //endif
  call AddSound(s.u,SOUND_EXPLO())
  call AddSoundStereo(s.u,"sound\\explosion_L.mp3","sound\\explosion_R.mp3")
  call addmobile(s)
  call SetUnitScale(s.u,1.25,0,0)
  call DestroyEffect(s.fx)
  set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+12,GetRandomReal(0,360),0)
  call s.addfx(MODEL_EXPLO_FLARE,"origin")
  call SetUnitScale(s.u,2.5,0,0)
  call DestroyEffect(s.fx)

  call KillUnitA(m.u)
  set m.terminate=true
endfunction

function SpellBarrageGen takes nothing returns nothing
  local missile m=placeholdmobile
  local mover s
  local real spread=GetRandomReal(0,500.)
  local real a=GetRandomReal(0,360)
  local real x=m.x+Cos(a*bj_DEGTORAD)*spread
  local real y=m.y+Sin(a*bj_DEGTORAD)*spread

  set s=mover.Create(CreateUnit(GetOwningPlayer(m.u),RAW_DUMMY,x,y,10))
  set s.z=GetZ(s.x,s.y)+2000
  call SetUnitAnimationByIndex(s.u,0)
  call SetUnitScale(s.u,2,0,0)
  call s.addfx(MODEL_ROCKET2,"origin")
  //set s.vz=-2000.
  set s.G=-300.
  set s.horizontal=false
  set s.funcimpact="SpellBarrageImpact"
  call addmobile(s)
endfunction

function SpellBarrage takes nothing returns nothing
  local location l=GetSpellTargetLoc()
  local real x=GetLocationX(l)
  local real y=GetLocationY(l)
  local unit u=GetSpellAbilityUnit()
  local Hero h=GetUnitUserData(u)
  local missile m
  local string s=""
 
  call RemoveLocation(l)
  set l=null

  set m=missile.Create(GetOwningPlayer(u),x,y,50,0)
  if IsPlayerAlly(GetLocalPlayer(),GetOwningPlayer(u)) then
    set s=MODEL_AOE
    call PingMinimapEx(x,y,14,255,43,178,false)
  endif
  call m.addfx(s,"origin")
  set m.speed=0.
  set m.range=0.
  set m.timed=12.
  set m.gen=4
  set m.geno=0.5
  set m.aux1=GetUnitFacing(u)
  set m.funcgen="SpellBarrageGen"
  call addmobile(m)
  call SetUnitScale(m.u,4,0,0)
  call SetUnitVertexColor(m.u,255,43,178,255)
  set m.green=43
  set m.blue=178

  //call AddSound(m.u,"Sound\\Flyby.mp3")
  //call AddSound2D(GetLocalPlayer(),"Sound\\Flyby.mp3")

  if IsUnitInForce(u,player_Force[0]) then
    set s=COLOR_TEAM1
  else
    set s=COLOR_TEAM2
  endif
  set s=s+GetPlayerName(GetOwningPlayer(u))+COLOR_END
  call msg_timed(GetLocalPlayer(),6,s+" calls for an artillery barrage !",SOUND_MSG)
 
  call PingIcon(GetPlayerId(GetOwningPlayer(u)),MODEL_ICON_BOMB)
 
  set u=null
endfunction





function SpellAirStrikeImpact takes nothing returns nothing
  local mover m=placeholdmobile
  local real x=GetUnitX(m.u)
  local real y=GetUnitY(m.u)
  local group g=CreateGroup()
  local boolexpr filter
  local unit c
  local blur s
  local vector a=vector.createFrom(x,y,GetZ(x,y)+GetUnitFlyHeight(m.u))
  local vector b=vector.create()
 
  set filter=Condition(function IsAll)

  call GroupEnumUnitsInRange(g,x,y,312,filter)
  call DestroyBoolExpr(filter)
  set filter=null
  call GroupRemoveUnit(g,m.u)

  loop
      set c=FirstOfGroup(g)
      exitwhen c==null
      call GroupRemoveUnit(g,c)
      set b.x=GetUnitX(c)
      set b.y=GetUnitY(c)
      set b.z=GetZ(GetUnitX(c),GetUnitY(c))+GetUnitFlyHeight(c)
      call UnitDamageTarget(m.u,c,DamageArea(vector.distance(a,b),362,600),false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC,null)
      // Blood
      if not IsUnitType(c,UNIT_TYPE_MECHANICAL) then
        if not IsAlive(c) then
          call CreateGib(GetUnitX(c),GetUnitY(c),GetUnitFlyHeight(c),-GetUnitFacing(c),300)
          call KillUnitA(c)
        else
          call UnitBurn(m.u,c)
          call DestroyEffect(AddSpecialEffectTarget(MODEL_BLOOD,c,"chest"))
          call CreateBloodsplat(GetUnitX(c),GetUnitY(c),GetRandomReal(0.9,1.2))
        endif
      endif
      call CreateBeep(m.u,c)
  endloop
  call DestroyGroup(g)
  set g=null
  call a.destroy()
  call b.destroy()
 
  call EnumDestructablesInCircle(x,y,250,function TreeKill)
  call EnumDestructablesInCircle(x,y,500,function TreeShake)
 
  set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+12,GetRandomReal(0,360),0)
  set s.fadeduration=3
  //if GetUnitFlyHeight(s.u)>40 then
  //  call s.addfx(MODEL_EXPLO_AIR,"origin")
  //else
    call s.addfx(MODEL_EXPLO_GROUND,"origin")
  //endif
  call AddSound(s.u,SOUND_EXPLO())
  call AddSoundStereo(s.u,"sound\\explosion_L.mp3","sound\\explosion_R.mp3")
  call addmobile(s)
  call SetUnitScale(s.u,2.5,0,0)
  call DestroyEffect(s.fx)
  set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+12,GetRandomReal(0,360),0)
  call s.addfx(MODEL_EXPLO_FLARE,"origin")
  call SetUnitScale(s.u,3.5,0,0)
  call DestroyEffect(s.fx)

  call KillUnitA(m.u)
  set m.terminate=true
endfunction

function SpellAirStrikeGen takes nothing returns nothing
  local missile m=placeholdmobile
  local mover s
  local real spread=72.
  local real c=((m.timed-1)/0.25)*180
  local real x=m.x+Cos(m.aux1*bj_DEGTORAD)*c+GetRandomReal(-spread,spread)
  local real y=m.y+Sin(m.aux1*bj_DEGTORAD)*c+GetRandomReal(-spread,spread)

  set s=mover.Create(CreateUnit(GetOwningPlayer(m.u),RAW_DUMMY,x,y,10))
  set s.z=GetZ(s.x,s.y)+2000
  call SetUnitAnimationByIndex(s.u,0)
  call SetUnitScale(s.u,2,0,0)
  call s.addfx(MODEL_AIRSTRIKE,"origin")
  set s.vz=-1000.
  set s.G=0.
  set s.horizontal=false
  set s.funcimpact="SpellAirStrikeImpact"
  call addmobile(s)
  call AddSound(s.u,"Sound\\Whistle.mp3")
endfunction

function SpellAirStrike takes nothing returns nothing
  local location l=GetSpellTargetLoc()
  local real x=GetLocationX(l)
  local real y=GetLocationY(l)
  local unit u=GetSpellAbilityUnit()
  local Hero h=GetUnitUserData(u)
  local missile m
  local string s=""
 
  call RemoveLocation(l)
  set l=null

  set m=missile.Create(GetOwningPlayer(u),x,y,50,0)
  if IsPlayerAlly(GetLocalPlayer(),GetOwningPlayer(u)) then
    set s=MODEL_AOE
    call PingMinimapEx(x,y,6,255,96,16,false)
  endif
  call m.addfx(s,"origin")
  set m.speed=0.
  set m.range=0.
  set m.timed=5.
  set m.gen=3
  set m.geno=0.25
  set m.aux1=GetUnitFacing(u)
  set m.funcgen="SpellAirStrikeGen"
  call addmobile(m)
  call SetUnitScale(m.u,5.5,0,0)
  call SetUnitVertexColor(m.u,255,96,16,255)
  set m.green=96
  set m.blue=16

  //call AddSound(m.u,"Sound\\Flyby.mp3")
  call AddSound2D(GetLocalPlayer(),"Sound\\Flyby.mp3")

  if IsUnitInForce(u,player_Force[0]) then
    set s=COLOR_TEAM1
  else
    set s=COLOR_TEAM2
  endif
  set s=s+GetPlayerName(GetOwningPlayer(u))+COLOR_END
  call msg_timed(GetLocalPlayer(),6,s+" calls for an airstrike !",SOUND_MSG)
 
  call PingIcon(GetPlayerId(GetOwningPlayer(u)),MODEL_ICON_BOMB)
 
  set u=null
endfunction



function SpellLSDDeath takes nothing returns nothing
  local missile m=placeholdmobile
  local Hero h=GetUnitUserData(m.target)
  local integer p=GetPlayerId(GetOwningPlayer(m.u))

  if GetLocalPlayer()==GetOwningPlayer(m.u) then
      call CinematicFadeWithUI(filter_red[p],filter_green[p],filter_blue[p],filter_red[p],filter_green[p],filter_blue[p],10,"ReplaceableTextures\\CameraMasks\\DreamFilter_Mask.blp",15,100)
  endif
 
  call UnitRemoveAbility(h.u,'A001')
  call UnitRemoveAbility(h.u,'A00O')

  //call StopSound(h.s_berserk,true,true)
  //call KillSoundWhenDone(h.s_berserk)
  set h.lsd_rotate=0
  set h.lsd_time=0
  set h.lsd=0
endfunction

function SpellLSDGen takes nothing returns nothing
  local missile m=placeholdmobile
  local Hero h=GetUnitUserData(m.target)
  local unit c
  local real spread=GetRandomReal(200,750)
  local real a=GetRandomReal(0,360)
  local real x=m.x+CosBJ(a)*spread
  local real y=m.y+SinBJ(a)*spread
  local integer i=15
  local integer p=GetPlayerId(GetOwningPlayer(m.u))
  local sound snd
  local blur s
  local wave w
  local string fx
  local real red=filter_red[p]
  local real green=filter_green[p]
  local real blue=filter_blue[p]
 
  if not IsAlive(h.u) then
    set m.terminate=true
    return
  endif
 
  set m.geno=GetRandomReal(m.aux1,m.aux2)
  set h.lsd_rotate=GetRandomReal(-90,270)
  set h.lsd_time=m.geno+1
 
  if m.aux3==0 then
    set red=GetRandomReal(0,100)
    set green=GetRandomReal(0,100)
    set blue=GetRandomReal(0,100)
    set m.aux3=1
    set i=100
  endif
  if m.aux3!=0 then
    set filter_red[p]=GetRandomReal(0,100)
    set filter_green[p]=GetRandomReal(0,100)
    set filter_blue[p]=GetRandomReal(0,100)
    if GetLocalPlayer()==GetOwningPlayer(m.u) then
      call CinematicFadeWithUI(red,green,blue,filter_red[p],filter_green[p],filter_blue[p],m.geno,"ReplaceableTextures\\CameraMasks\\DreamFilter_Mask.blp",i,15)
    endif
  endif
 
  set i=GetRandomInt(1,6)
  if i==1 then
 
    set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+GetRandomReal(-90,128),GetRandomReal(0,360),0)
    set s.fadeduration=3
    set fx=""
    if GetLocalPlayer()==GetOwningPlayer(m.u) then
      if GetUnitFlyHeight(s.u)>40 then
        set fx=MODEL_EXPLO_AIR
      else
        set fx=MODEL_EXPLO_GROUND
     endif
    endif
    call s.addfx(fx,"origin")
    call spell_addmobile(s)
    call SetUnitScale(s.u,2,0,0)
    call DestroyEffect(s.fx)
    set fx=""
    if GetLocalPlayer()==GetOwningPlayer(m.u) then
      set fx=MODEL_EXPLO_FLARE
    endif
    call s.addfx(fx,"origin")
    call DestroyEffect(s.fx)
 
    set snd=CreateSound(SOUND_EXPLO(),false,true,false,10,10,"")
    call SetSoundPitch(snd,GetRandomReal(0.4,0.9))
    //set i=0
    //if GetLocalPlayer()==GetOwningPlayer(m.u) then
      set i=128
    //endif
    call SetSoundVolume(snd,i)
    call SetSoundDistances(snd,600,10000)
    call SetSoundDistanceCutoff(snd,3000)
    call AttachSoundToUnit(snd,s.u)
    if GetLocalPlayer()==GetOwningPlayer(m.u) then
      call StartSound(snd)
    endif
    call KillSoundWhenDone(snd)
    set snd=null
   
  elseif i==2 then
 
    set snd=CreateSound(SOUND_GUN,false,true,false,10,10,"")
    call SetSoundPitch(snd,GetRandomReal(0.4,1.25))
    //set i=0
    //if GetLocalPlayer()==GetOwningPlayer(m.u) then
      set i=128
    //endif
    call SetSoundVolume(snd,i)
    call SetSoundDistances(snd,600,10000)
    call SetSoundDistanceCutoff(snd,3000)
    call AttachSoundToUnit(snd,m.u)
    if GetLocalPlayer()==GetOwningPlayer(m.u) then
      call StartSound(snd)
    endif
    call KillSoundWhenDone(snd)
    set snd=null
   
  elseif i>=3 then
 
    set red=0.4
    set blue=0.9
    set i=GetRandomInt(0,13)
    if i==0 then
      set fx=SOUND_GIBS
    elseif i==1 then
      set fx="Sound\\Ambient\\Ashenvale\\FreakyForest"+I2S(GetRandomInt(1,4))+".wav"
      set blue=0.8
    elseif i==2 then
      set fx="Sound\\drug.wav"
      set red=0.8
      set blue=1
    elseif i==3 then
      set fx="Buildings\\Naga\\TempleOfTides\\TempleOfTidesWhat1.wav"
    elseif i==4 then
      set fx="Buildings\\Undead\\GraveYard\\GraveYardWhat1.wav"
    elseif i==5 then
      set fx="Buildings\\Undead\\HauntedMine\\UndeadMiningWhat1.wav"
    elseif i==6 then
      set fx="Buildings\\Undead\\TempleOfTheDamned\\TempleOfTheDamnedWhat.wav"
    elseif i==7 then
      set fx="Buildings\\Undead\\Necropolis\\NecropolisWhat.wav"
    elseif i==8 then
      set fx="Buildings\\Undead\\Crypt\\CryptWhat.wav"
    elseif i==9 then
      set fx="Buildings\\Undead\\GargoyleSpire\\GargoyleSpireWhat1.wav"
    elseif i>9 then
      set w=wave.Create(GetOwningPlayer(m.u),x,y,50.,0)
      set c=CreateUnit(GetOwningPlayer(m.u),'hrif',x,y,GetRandomReal(0,360))
      call RemoveUnit(w.u)
      set w.u=c
      set c=null
      //set fx=""
      set i=0
      if GetLocalPlayer()==GetOwningPlayer(m.u) then
      //  set fx="Model\\Marine.mdl"
        set i=255
      endif
      //call w.addfx(fx,"origin")
      call SetUnitVertexColor(w.u,255,255,255,i)
      set w.speed=0.//522.
      set w.range=0.
      set w.timed=GetRandomReal(2.,4.)
      set w.alpha=0
      //call SetUnitScale(w.u,1.4,0,0)
      //set w.tx=x+Cos(GetUnitFacing(w.u)*bj_DEGTORAD)*100
      //set w.ty=y+Sin(GetUnitFacing(w.u)*bj_DEGTORAD)*100
      call addmobile(w)
      //call SetUnitAnimationByIndex(w.u,7)
      //call SetUnitAnimation(w.u,"walk")
    endif
    call Preload(fx) //cojavim
 
    set snd=CreateSound(fx,false,true,false,10,10,"")
    call SetSoundPitch(snd,GetRandomReal(red,blue))
    //set i=0
    //if GetLocalPlayer()==GetOwningPlayer(m.u) then
      set i=128
    //endif
    call SetSoundVolume(snd,i)
    call SetSoundDistances(snd,600,10000)
    call SetSoundDistanceCutoff(snd,3000)
    call AttachSoundToUnit(snd,m.u)
    if GetLocalPlayer()==GetOwningPlayer(m.u) then
      call StartSound(snd)
    endif
    call KillSoundWhenDone(snd)
    set snd=null
   
  endif
 
endfunction

function SpellLSD takes unit u, real timed, real react, real int1, real int2 returns nothing
  local Hero h=GetUnitUserData(u)
  local real x=GetUnitX(u)
  local real y=GetUnitY(u)
  local missile m

  if h==0 then
    call UnitAddAbility(u,'A001')
    call UnitAddAbility(u,'A00O')
  endif
 
  if h.lsd!=0 then
    set h.lsd.timed=h.lsd.timed+(timed*.5)
  else
    call UnitAddAbility(u,'A001')
    call UnitAddAbility(u,'A00O')
 
    set m=missile.Create(GetOwningPlayer(u),x,y,GetUnitFlyHeight(u)+90,0)
    set m.target=u
    set m.speed=1000.
    set m.range=0.
    set m.timed=timed
    set m.conhit=BOOLEXPR_FALSE
    set m.gen=react
    set m.geno=GetRandomReal(int1,int2)
    set m.funcgen="SpellLSDGen"
    set m.funcdeath="SpellLSDDeath"
    //set m.funcimpact="SpellLSDDeath"
    call addmobile(m)
    set m.aux1=int1
    set m.aux2=int2
    set m.alpha=0
   
    set h.lsd=m
  endif
 
  //set h.s_berserk=CreateSound("Sound\\berserk.wav",true,true,false,10,10,"")
  //call SetSoundPitch(h.s_berserk,1)
  //call SetSoundVolume(h.s_berserk,100)
  //call SetSoundDistances(h.s_berserk,600,10000)
  //call SetSoundDistanceCutoff(h.s_berserk,3000)
  //call AttachSoundToUnit(h.s_berserk,u)
  //call StartSound(h.s_berserk)
  //call KillSoundWhenDone(h.s_berserk)
endfunction




























function SpellMortarDeath takes nothing returns nothing
  local mover m=placeholdmobile
  local real x=GetUnitX(m.u)
  local real y=GetUnitY(m.u)
  local group g=CreateGroup()
  local boolexpr filter
  local unit c
  local blur s
  local real d=0
  local real factor
  local vector a=vector.createFrom(x,y,GetZ(x,y)+GetUnitFlyHeight(m.u))
  local vector b=vector.create()
 
  set filter=Condition(function IsAll)

  call GroupEnumUnitsInRange(g,x,y,400,filter)
  call DestroyBoolExpr(filter)
  set filter=null
  call GroupRemoveUnit(g,m.u)
 
  loop
      set c=FirstOfGroup(g)
      exitwhen c==null
      call GroupRemoveUnit(g,c)
      set b.x=GetUnitX(c)
      set b.y=GetUnitY(c)
      set b.z=GetZ(GetUnitX(c),GetUnitY(c))+GetUnitFlyHeight(c)
      set d=DamageArea(vector.distance(a,b),300,40)+25
      set factor=1
      if GetUnitAbilityLevel(c,'AId4')>0 then
          set factor=.75
      endif
      call UnitDamageTarget(m.u,c,d*factor,false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC,null)
      // Blood
      if not IsUnitType(c,UNIT_TYPE_MECHANICAL) then
        if not IsAlive(c) then
          call CreateGib(GetUnitX(c),GetUnitY(c),GetUnitFlyHeight(c),-GetUnitFacing(c),400)
          call KillUnitA(c)
        else
          //call UnitBurn(c)
          call DestroyEffect(AddSpecialEffectTarget(MODEL_BLOOD,c,"chest"))
          call CreateBloodsplat(GetUnitX(c),GetUnitY(c),GetRandomReal(0.9,1.2))
          call SpellDummy(GetOwningPlayer(m.u),x,y,0,'Aslo',"slow",2-GetUnitAbilityLevel(c,'AId4'),c,.5) //hit recovery
        endif
      endif
      call CreateBeep(m.u,c)
  endloop
  call DestroyGroup(g)
  set g=null
  call a.destroy()
  call b.destroy()
 
  call EnumDestructablesInCircle(x,y,200,function TreeKill)
  call EnumDestructablesInCircle(x,y,600,function TreeShake)
 
  set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+12,GetRandomReal(0,360),0)
  set s.fadeduration=3
  call s.addfx("model\\rocket.mdl","origin")
  call AddSound(s.u,"Sound\\explosion_blast.mp3")
  call AddSoundStereo(s.u,"sound\\explosion_L.mp3","sound\\explosion_R.mp3")
  call addmobile(s)
  call SetUnitScale(s.u,1.5,0,0)
  call DestroyEffect(s.fx)
  set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+12,GetRandomReal(0,360),0)
  call s.addfx(MODEL_EXPLO_FLARE,"origin")
  call SetUnitScale(s.u,4.,0,0)
  call DestroyEffect(s.fx)

  call KillUnitA(m.u)
  set m.terminate=true
endfunction

function SpellMortarImpact takes nothing returns nothing
  local mover m=placeholdmobile
  set m.terminate=true
endfunction

function SpellMortarGen takes nothing returns nothing
  local missile m=placeholdmobile
  local real x=m.aux1
  local real y=m.aux2
  local real z=m.aux3
  local real a=Atan2BJ(y,x)
  local real aoa
  local unit c
  local mover s
  local real array V
  local real G=1600
  local integer q=IMaxBJ(0,GetTerrainCliffLevel(x,y)-GetTerrainCliffLevel(m.x,m.y))
 
  if not IsAbleToShot(m.target) then
    set m.terminate=true
    return
  endif
 
  set V[2]=1500+q*100 //RANGE
  set V[0]=RMaxBJ(RMinBJ(900,SquareRoot(x*x+y*y)),600) //MIN RANGE
  set V[1]=SquareRoot(V[2]*G)-GetRandomReal(0,100) //Max speed
  set aoa=(bj_PI/2)-(Asin(((V[0]-150+q*80)*G)/(V[1]*V[1]))/0.5)
  set x=m.x
  set y=m.y
 
  set c=CreateUnit(GetOwningPlayer(m.u),RAW_DUMMY,x,y,a)
  set s=mover.Create(c)
  call s.addfx("model\\rocket.mdl","origin")
  //set a=a*bj_DEGTORAD
  set s.x=x
  set s.y=y
  set s.z=GetZ(x,y)+spell_z+GetRandomReal(6,27)
  set a=a+GetRandomReal(-10,10)
  set s.vx=Cos(aoa)*CosBJ(a)*V[1]  //Cos(a)*v
  set s.vy=Cos(aoa)*SinBJ(a)*V[1]  //Sin(a)*v
  set s.vz=Sin(aoa)*V[1]           //Sin(aoa)*v
  set s.G=-G*period
  set s.funcimpact="SpellMortarImpact"
  set s.funcdeath="SpellMortarDeath"
  set s.zangle=true

  call SetUnitScale(s.u,1.5,0,0)
  //call SetUnitTimeScale(s.u,.1)
  call SetUnitAnimationByIndex(s.u,90)
  //call SetUnitVertexColor(s.u,128,64,64,255)
  call UnitAddAbility(s.u,RAW_ABIL_NADEGLOW)
  call addmobile(s)
  set s.target=null

  call AddSound(s.u,"Abilities\\Spells\\Human\\FlakCannons\\FlakCannon.wav")
  //call echo("mortar shell")
 
  set c=null
endfunction




function SpellMortar takes nothing returns nothing
  local unit u=GetSpellAbilityUnit()
  local location l=GetSpellTargetLoc()
  local Hero h=GetUnitUserData(u)
  local unit c=h.target
  local real x=GetUnitX(u)
  local real y=GetUnitY(u)
  local real z=GetLocationZ(l)-GetZ(GetUnitX(u),GetUnitY(u))
  local missile m
 
  set m=missile.Create(GetOwningPlayer(u),x,y,GetUnitFlyHeight(u)+150,0)
  set m.target=u
  set m.speed=1000.
  set m.range=0.
  set m.timed=1.06
  set m.conhit=BOOLEXPR_FALSE
  set m.gen=0.
  set m.geno=0.2
  set m.funcgen="SpellMortarGen"
  call addmobile(m)
  set m.aux1=GetLocationX(l)-x
  set m.aux2=GetLocationY(l)-y
  set m.aux3=z
 
  call PingIcon(GetPlayerId(GetOwningPlayer(u)),MODEL_ICON_BOMB)
 
  call RemoveLocation(l)
  set l=null
  set c=null
  set u=null
endfunction




function SpellMorphine takes nothing returns nothing
  local unit u=GetSpellAbilityUnit()
  local unit c
  local Hero h//=GetUnitUserData(u)
  local Hero m
  local integer q=0
  local real x=GetUnitX(u)
  local real y=GetUnitY(u)
  local group g=CreateGroup()
  local boolexpr filter

  set conunit=u
  set filter=Condition(function IsRespawnable)
  call GroupEnumUnitsInRange(g,x,y,500,filter)
  call GroupRemoveUnit(g,u)
  call DestroyBoolExpr(filter)
  set filter=null

  set c=FirstOfGroup(g)//GroupPickRandomUnit(g)
  call DestroyGroup(g)
  set g=null
 
  if c!=null then
    //call echo("Morphine: "+GetHeroProperName(c)+" hp: "+R2S(GetWidgetLife(c)))
    set m=GetUnitUserData(c)
   
    loop
        exitwhen q==FORCES
        if IsPlayerInForce(GetOwningPlayer(c),player_Force[q]) then
          set game_Count[q]=game_Count[q]+1
        endif
        set q=q+1
    endloop
   
    set h=Hero.Create(CreateUnit(GetOwningPlayer(c),GetUnitTypeId(c),GetUnitX(c),GetUnitY(c),GetUnitFacing(c)))
    set player_Cam[GetPlayerId(GetOwningPlayer(c))]=null
    //set player_N=player_N+1
    set player_Heroes[m.nn]=h
    set player_Cam[GetPlayerId(GetOwningPlayer(c))]=h.u
    set player_drug[GetPlayerId(GetOwningPlayer(c))]=player_drug[GetPlayerId(GetOwningPlayer(c))]+1000
    //call DrugAilments(GetOwningPlayer(c))
    call RemoveItem(UnitItemInSlot(h.u,0))
    call RemoveItem(UnitItemInSlot(h.u,1))
    call RemoveItem(UnitItemInSlot(h.u,2))
    call UnitAddItem(h.u,UnitItemInSlot(c,0))
    call UnitAddItem(h.u,UnitItemInSlot(c,1))
    call UnitAddItem(h.u,UnitItemInSlot(c,2))
    call UnitAddItem(h.u,UnitItemInSlot(c,3))
    call UnitAddItem(h.u,UnitItemInSlot(c,4))
    call UnitAddItem(h.u,UnitItemInSlot(c,5))
    set h.i_weapon=UnitItemInSlot(h.u,0)//m.i_weapon
    set h.i_ammo=UnitItemInSlot(h.u,1)//m.i_ammo
    set h.weapon=m.weapon
    set h.revived=true
    call SetWidgetLife(h.u,GetUnitState(h.u,UNIT_STATE_MAX_LIFE)*.33)
    call m.destroy()
    call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Items\\AIsm\\AIsmTarget.mdl",GetUnitX(h.u),GetUnitY(h.u)))
    call UnitAddAbility(h.u,'Arll')
    call UnitAddAbility(h.u,RAW_ABIL_ATTACK)
    call UnitRemoveAbility(h.u,'Bvul')
    call UnitAddItem(h.u,CreateItem('rres',0,0))
   
    if GetLocalPlayer()==GetOwningPlayer(h.u) then
      call ClearSelection()
      call SelectUnit(h.u,true)
    endif
    call msg(GetOwningPlayer(h.u),STRING_NOTICE+"You have been revived!",SOUND_MSG)
   
    call AddSound(h.u,"Sound\\drug.mp3")
   
    call ExecuteFunc("LabelRemainingExec")
  else
    call msg(GetOwningPlayer(u),STRING_NOTICE+"You have to be nearer to ally corpse!",SOUND_MSG)
    call UnitRemoveAbility(u,'A007')
    call UnitAddAbility(u,'A007')
    call TriggerSleepAction(0)
    call SetUnitState(u,UNIT_STATE_MANA,GetUnitState(u,UNIT_STATE_MANA)+100)
  endif
 
  set c=null
  set u=null
endfunction





function SpellSmokeDeath takes nothing returns nothing
  local mover m=placeholdmobile
  local real x=GetUnitX(m.u)
  local real y=GetUnitY(m.u)
  local blur s
 
  local destructable d1=CreateDestructable('YTlb',x+64,y+64,0,0,0)
  local destructable d2=CreateDestructable('YTlb',x-64,y+64,0,0,0)
  local destructable d3=CreateDestructable('YTlb',x-64,y-64,0,0,0)
  local destructable d4=CreateDestructable('YTlb',x+64,y-64,0,0,0)

  set s=blur.Create('u001',x,y,0,GetRandomReal(0,360),0)
  set s.timed=30
  set s.fadeduration=3
  call AddSound(s.u,"sound\\smoke.mp3")
  call addmobile(s)
  call SetUnitScale(s.u,3,0,0)
  call s.addfx("Model\\Smoke.mdl","origin")
  call UnitAddAbility(s.u,'ANpi')
  //if mod==3 then
    call UnitAddAbility(s.u,'A013')
  //endif
  call SetUnitOwner(s.u,GetOwningPlayer(m.u),false)

  call KillUnitA(m.u)
 
  loop
      exitwhen not IsAlive(s.u)
      call TriggerSleepAction(0)
  endloop
  call RemoveDestructable(d1)
  call RemoveDestructable(d2)
  call RemoveDestructable(d3)
  call RemoveDestructable(d4)
  set d1=null
  set d2=null
  set d3=null
  set d4=null
endfunction

function SpellSmokeImpact takes nothing returns nothing
  local mover m=placeholdmobile
  local vector v
  local vector v1
  local vector v2
  local real l
  local real b=.7

  set v=vector.createFrom(m.vx,m.vy,m.vz)
  set v1=vector.getTerrainNormal(m.x,m.y,50)
  set v2=v.project(v1)

  call v2.scale(-2)
  call v.add(v2)
  call v.scale(b)

  set m.vx=v.x
  set m.vy=v.y
  set m.vz=v.z

  call v1.destroy()
  call v2.destroy()

    set l=v.lengthSquare()
    if l>250 then
      if not IsTerrainPathable(m.x,m.y,PATHING_TYPE_FLOATABILITY) and GetUnitFlyHeight(m.u)<30 then
        call DestroyEffect(AddSpecialEffect(MODEL_WATER_SPLASH,m.x,m.y))
        set m.vz=0
        call AddSound(m.u,"Sound\\Step\\inwater.wav")
      else
        call DestroyEffect(AddSpecialEffect(MODEL_DUST_SPLASH,m.x,m.y))
        call AddSound(m.u,SOUND_BOUNCE)
        set m.vz=m.vz+10
      endif
      set m.range=92.
    else
      //set m.z=m.z+1
      //set m.vz=m.vz+4
      //set m.vertical=false
    endif
  call v.destroy()
endfunction

function SpellSmokeHit takes nothing returns nothing
  local mover m=placeholdmobile
  if IsWall(placeholdunit) and IsAnotherPlayer(placeholdunit,m.u) then
    set m.x=m.x-m.vx*period
    set m.y=m.y-m.vy*period
    set m.vx=-m.vx*.1
    set m.vy=-m.vy*.1
    set m.vz=m.vz*.5
  endif
  set placeholdunit=null
endfunction

function SpellSmoke takes nothing returns nothing
  local unit u=GetSpellAbilityUnit()
  local location l=GetSpellTargetLoc()
  local real x=GetLocationX(l)-GetUnitX(u)
  local real y=GetLocationY(l)-GetUnitY(u)
  local real a=Atan2BJ(y,x)
  local real aoa
  local unit c
  local mover s
  local real array V
  local real G=1800

  call RemoveLocation(l)
  set l=null
 
  set V[2]=1200 //RANGE
  set V[0]=RMinBJ(V[2],SquareRoot(x*x+y*y))
  set V[1]=SquareRoot(V[2]*G) //Max speed
  set aoa=(bj_PI/2)-(Asin((V[0]*G)/(V[1]*V[1]))/1.2)
  set x=GetUnitX(u)
  set y=GetUnitY(u)
 
  set c=CreateUnit(GetOwningPlayer(u),RAW_DUMMY,x,y,a)
  set s=mover.Create(c)
  call s.addfx(MODEL_ALCHEMY,"origin")
  set s.x=x
  set s.y=y
  set s.z=GetZ(x,y)+32
  set s.vx=Cos(aoa)*CosBJ(a)*V[1]
  set s.vy=Cos(aoa)*SinBJ(a)*V[1]
  set s.vz=Sin(aoa)*V[1]
  set s.G=-G*period
  set s.funcimpact="SpellNadeImpact" //SpellSmokeImpact
  set s.funchit="SpellSmokeHit"
  set s.funcdeath="SpellSmokeDeath"

  call SetUnitScale(s.u,.5,0,0)
  call SetUnitTimeScale(s.u,.1)
  call SetUnitAnimationByIndex(s.u,90)
  call SetUnitVertexColor(s.u,0,255,255,255)
  call UnitAddAbility(s.u,RAW_ABIL_NADEGLOW)
  call addmobile(s)
  set s.range=32.
  set s.aux1=10
  set s.timed=5

  call PingIcon(GetPlayerId(GetOwningPlayer(u)),MODEL_ICON_SMOKE)
 
  set c=null
  set u=null
endfunction


function SpellLSDNadeDeath takes nothing returns nothing
  local mover m=placeholdmobile
  local real x=GetUnitX(m.u)
  local real y=GetUnitY(m.u)
  local group g=CreateGroup()
  local boolexpr filter
  local unit c
  local blur s
  local real d
  local ray r
  local integer rspawn=9
  local real rx
  local real ry
  local real pal
 
  set filter=Condition(function IsAll)

  call GroupEnumUnitsInRange(g,x,y,600,filter)
  call DestroyBoolExpr(filter)
  set filter=null
  call GroupRemoveUnit(g,m.u)

  loop
      set c=FirstOfGroup(g)
      exitwhen c==null
      call GroupRemoveUnit(g,c)
      //if not IsUnitType(c,UNIT_TYPE_MECHANICAL) then
      if IsUnitType(c,UNIT_TYPE_HERO) then
        if m.target!=c then
          set d=18
        else
          set d=20
        endif
      //call SpellLSD(c,d,1,0.5,2)
        call SpellLSD(c,d,1,.3,.7)
        set player_drug[GetPlayerId(GetOwningPlayer(c))]=player_drug[GetPlayerId(GetOwningPlayer(c))]+R2I(d*15)
        //call DrugAilments(GetOwningPlayer(c))
        call CreateBeep(m.u,c)
      endif
  endloop
  call DestroyGroup(g)
  set g=null
 

  set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+12,GetRandomReal(0,360),0)
  call s.addfx(MODEL_EXPLO_FLARE,"origin")
  call SetUnitScale(s.u,6,0,0)
  call DestroyEffect(s.fx)
  call AddSound(s.u,SOUND_EXPLO())
  call AddSound(s.u,"Abilities\\Spells\\Other\\AcidBomb\\AlchemistAcidBurnMissileDeath1.wav")
  call AddSoundStereo(s.u,"sound\\explosion_L.mp3","sound\\explosion_R.mp3")
  call addmobile(s)

  loop
      exitwhen rspawn<=0
      set rx=x+GetRandomReal(-400,400)
      set ry=y+GetRandomReal(-400,400)
      set r=ray.Create("SPLK",x,y,m.z,rx,ry,GetZ(rx,ry)+GetRandomReal(0,300)) //"CLPB"
      set r.timed=0.3
      set r.fadeduration=0.25
      set r.random2=175
      call addmobile(r)
      set pal=2.
      set r.r=GetRandomReal(0,1)
      set pal=pal-r.r
      set r.g=GetRandomReal(0,1)
      set pal=pal-r.g
      set r.b=pal
      call SetLightningColor(r.lx,r.r,r.g,r.b,r.a)
      set rspawn=rspawn-1
  endloop
 
  call KillUnitA(m.u)
endfunction

function SpellLSDNade takes nothing returns nothing
  local unit u=GetSpellAbilityUnit()
  local location l=GetSpellTargetLoc()
  local real x=GetLocationX(l)-GetUnitX(u)
  local real y=GetLocationY(l)-GetUnitY(u)
  local real a=Atan2BJ(y,x)
  local real aoa
  local unit c
  local mover s
  local real array V
  local real G=1800

  call RemoveLocation(l)
  set l=null
 
  set V[2]=1200 //RANGE
  set V[0]=RMinBJ(V[2],SquareRoot(x*x+y*y))
  set V[1]=SquareRoot(V[2]*G) //Max speed
  set aoa=(bj_PI/2)-(Asin((V[0]*G)/(V[1]*V[1]))/1.2)
  set x=GetUnitX(u)
  set y=GetUnitY(u)
 
  set c=CreateUnit(GetOwningPlayer(u),RAW_DUMMY,x,y,a)
  set s=mover.Create(c)
  call s.addfx(MODEL_ALCHEMY,"origin")
  set s.x=x
  set s.y=y
  set s.z=GetZ(x,y)+32
  set s.vx=Cos(aoa)*CosBJ(a)*V[1]
  set s.vy=Cos(aoa)*SinBJ(a)*V[1]
  set s.vz=Sin(aoa)*V[1]
  set s.G=-G*period
  set s.funcimpact="SpellNadeImpact"
  set s.funchit="SpellNadeHit"
  set s.funcdeath="SpellLSDNadeDeath"

  call SetUnitScale(s.u,.5,0,0)
  call SetUnitTimeScale(s.u,.1)
  call SetUnitAnimationByIndex(s.u,90)
  call SetUnitVertexColor(s.u,200,225,0,255)
  call UnitAddAbility(s.u,RAW_ABIL_NADEGLOW)
  call addmobile(s)
  set s.range=48.
  set s.aux1=10
  set s.timed=3.5
  set s.target=null

  call PingIcon(GetPlayerId(GetOwningPlayer(u)),MODEL_ICON_LSD)
 
  set c=null
  set u=null
endfunction








function SpellNadeDeath takes nothing returns nothing
  local mover m=placeholdmobile
  local real x=GetUnitX(m.u)
  local real y=GetUnitY(m.u)
  local group g=CreateGroup()
  local boolexpr filter
  local unit c
  local blur s
  local real d=0
  local vector a=vector.createFrom(x,y,GetZ(x,y)+GetUnitFlyHeight(m.u))
  local vector b=vector.create()
  local real factor=1
 
  //set conunit=m.u
  set filter=Condition(function IsAll)

  call GroupEnumUnitsInRange(g,x,y,500,filter)
  call DestroyBoolExpr(filter)
  set filter=null
  call GroupRemoveUnit(g,m.u)

  loop
      set c=FirstOfGroup(g)
      exitwhen c==null
      call GroupRemoveUnit(g,c)
      set b.x=GetUnitX(c)
      set b.y=GetUnitY(c)
      set b.z=GetZ(GetUnitX(c),GetUnitY(c))+GetUnitFlyHeight(c)
      if m.target!=c then
        set d=DamageArea(vector.distance(a,b),500,260)
      else
        set d=260
      endif
      if GetUnitAbilityLevel(c,'AId4')>0 then
          set factor=.6 //156
      endif
      call UnitDamageTarget(m.u,c,10+d*factor,false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC,null)
      // Blood
      if not IsUnitType(c,UNIT_TYPE_MECHANICAL) then
        if not IsAlive(c) then
          call CreateGib(GetUnitX(c),GetUnitY(c),GetUnitFlyHeight(c),-GetUnitFacing(c),600)
          call KillUnitA(c)
        else
          //call UnitBurn(c)
          call DestroyEffect(AddSpecialEffectTarget(MODEL_BLOOD,c,"chest"))
          call CreateBloodsplat(GetUnitX(c),GetUnitY(c),GetRandomReal(0.9,1.2))
        endif
      endif
      call CreateBeep(m.u,c)
  endloop
  call DestroyGroup(g)
  set g=null
  call a.destroy()
  call b.destroy()
 
  call EnumDestructablesInCircle(x,y,300,function TreeKill)
  call EnumDestructablesInCircle(x,y,500,function TreeShake)
 
  set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+12,GetRandomReal(0,360),0)
  set s.fadeduration=3
  if GetUnitFlyHeight(s.u)>40 then
    call s.addfx(MODEL_EXPLO_AIR,"origin")
  else
    call s.addfx(MODEL_EXPLO_GROUND,"origin")
  endif
  call AddSound(s.u,SOUND_EXPLO())
  call AddSoundStereo(s.u,"sound\\explosion_L.mp3","sound\\explosion_R.mp3")
  //call AddSoundFogStereo(s.u,"sound\\explosion_L.mp3",true)
  //call AddSoundFogStereo(s.u,"sound\\explosion_R.mp3",false)
  call addmobile(s)
  call SetUnitScale(s.u,2,0,0)
  call DestroyEffect(s.fx)
  set s=blur.Create(RAW_DUMMY,x,y,GetUnitFlyHeight(m.u)+12,GetRandomReal(0,360),0)
  call s.addfx(MODEL_EXPLO_FLARE,"origin")
  call SetUnitScale(s.u,5,0,0)
  call DestroyEffect(s.fx)

  call KillUnitA(m.u)
endfunction

function SpellNadeHit takes nothing returns nothing
  local mover m=placeholdmobile
  if IsWall(placeholdunit) and IsAnotherPlayer(placeholdunit,m.u) then
    set m.x=m.x-m.vx*period
    set m.y=m.y-m.vy*period
    set m.vx=-m.vx*.1
    set m.vy=-m.vy*.1
    set m.vz=m.vz*.5
  elseif IsUnitEnemy(placeholdunit,GetOwningPlayer(m.u)) and IsAlive(placeholdunit) then
    set m.target=placeholdunit
    set m.terminate=true
  endif
  set placeholdunit=null
endfunction

function SpellNadeImpact takes nothing returns nothing
  local mover m=placeholdmobile
  local vector v
  local vector v1
  local vector v2
  local real l
  local real b=.6

  set v=vector.createFrom(m.vx,m.vy,m.vz)
  set v1=vector.getTerrainNormal(m.x,m.y,50)
  set v2=v.project(v1)

  call v2.scale(-2)
  call v.add(v2)
  call v.scale(b)

  set m.vx=v.x
  set m.vy=v.y
  set m.vz=v.z
  //set m.x=m.x+v2.x*period*3
  //set m.y=m.y+v2.y*period*3
  //set m.z=m.z+v2.z*period*3

  call v1.destroy()
  call v2.destroy()

  if m.aux1>0. then
    set l=v.lengthSquare()
    if l>128 then
      if not IsTerrainPathable(m.x,m.y,PATHING_TYPE_FLOATABILITY) and GetUnitFlyHeight(m.u)<30 then
        call DestroyEffect(AddSpecialEffect(MODEL_WATER_SPLASH,m.x,m.y))
        set m.vz=0
        call AddSound(m.u,"Sound\\Step\\inwater.wav")
      else
        call DestroyEffect(AddSpecialEffect(MODEL_DUST_SPLASH,m.x,m.y))
        call AddSound(m.u,SOUND_BOUNCE)
        set m.vz=m.vz+m.vz*.15
        set m.z=m.z+2
      endif
      set m.range=92.
    else
      set m.vertical=false
    endif
  else
    //set m.vx=m.vx*.8
    //set m.vy=m.vy*.8
    set m.vertical=false
    if m.aux2>0. then
      set m.horizontal=false
      set m.range=m.aux2
    endif
    call SetUnitX(m.u,m.x)
    call SetUnitY(m.u,m.y)
  endif
  set m.aux1=m.aux1-1
  call v.destroy()
endfunction

function SpellNade takes nothing returns nothing
  local unit u=GetSpellAbilityUnit()
  //local integer p=GetPlayerId(GetOwningPlayer(h))
  local location l=GetSpellTargetLoc()
  local real x=GetLocationX(l)-GetUnitX(u)
  local real y=GetLocationY(l)-GetUnitY(u)
  local real a=Atan2BJ(y,x)
  local real aoa
  local unit c//=CreateProjectile(GetOwningPlayer(h),"Nade.mdl",GetUnitX(h),GetUnitY(h),a)
  local mover s
  local real array V
  local real G=1800

  call RemoveLocation(l)
  set l=null
 
  set V[2]=1200 //RANGE
  set V[0]=RMinBJ(V[2],SquareRoot(x