1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Travel to distant realms and encounter scenes unknown to the common folk. The Greatest of Adventures is upon us with the 8th Cinematic Contest. Join in on a fun ride.
    Dismiss Notice
  5. The 18th Icon Contest is ON! Choose any ingame unit and give him/her Hero abilities. Good luck to all.
    Dismiss Notice
  6. The Secrets of Warcraft 3 have revealed interesting works. The RESULTS for Abelhawk's Mini-Mapping Contest #15 have come out!
    Dismiss Notice
  7. Contestants are to create a scene set in the Stone Age. Come and see what you can come up with. We wish you the best of luck!
    Dismiss Notice
  8. Colour outside the lines! Techtree Contest #13 is a go. The contest is optionally paired.
    Dismiss Notice
  9. Night Rider gained several songs for his journey. The poll for the 12th Music Contest has started. Check it out!
    Dismiss Notice
  10. Greetings cerebrates, our Swarm needs new spawners that will have numerous children. Join the HIVE's 31st Modeling Contest - Spawners and Spawned! The contest is optionally paired.
    Dismiss Notice
  11. 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

SpellpackRepack1.5.w3x
Variables
MainScript
MainFunctions
HandleCountTester
Info
Readme
FAQ
Import
Log
OldVersionLog
RepackedVersionLog
Other Stuff
NFO
Revive Stuff
Spells
Boomerang
Crush
Electric Field
Fire Bombs
Dark Torture
Frost Sphere
Bloody Run
Mystic Net
Implosion
Critical Jump
Paralyzing Field
Burrowstrike
Holy Shock
Jade Shield
Berserk Rage
Brain Soak
Aggressive Infection
Thunder Clash
Whippy Rope
Backdoor
//TESH.scrollpos=0
//TESH.alwaysfold=0
Name Type Is Array Initial Value
i integer No
//TESH.scrollpos=0
//TESH.alwaysfold=0
//                              ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
//                             Û                Û
//                             Û                Û
//                              ßßßßßÛ    Ûßßßßß
//                                   Û    Û
//                                   Û    Û  ÜÜÜÜÜÜ        ÜÜÜÜÜÜÜ  
//                                   Û    Û  Û     Û      Û       Û
//                                   Û    Û  Û  Ü   Û    Û   Ûßßßßßß
//                                   Û    Û  Û  ÛÛ   Û   Û   Û
//                                   Û    Û  Û  Û Û   Û  Û   Û   ÜÜÜ
//                                   Û    Û  Û  Û  Û  Û  Û   Û  Û  Û
//                                   Û    Û  Û  ßßß   Û  Û   ÛÜÜÛ  Û
//                                   Û    Û  Û       Û    Û       Û
//                                    ßßßß   ßßßßßßßß      ßßßßßßß  

//                               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//                               ³        Clan TDG @ Azeroth ¸      ³
//                               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

//   Screen Solution: 1280x1024                                          Visit www.jx3.net/TDG!

//  ++++++++++++++++++++++++++++++++++++++++++  INFO   ++++++++++++++++++++++++++++++++++++++++
//  Type........................................ : .....................................Random
//  Language.................................... : ......................................vJass
//  Coder....................................... : ......................................Hanky
//  MUI......................................... : ........................................Yes

//  ++++++++++++++++++++++++++++++++++++++++++ CREDITS ++++++++++++++++++++++++++++++++++++++++
//  Thanks for the JassGenNewPack: .............pipedream
//                                 .............xttocs
//                                 .............Pitzermike
//                                 .............Vexorian
//                                 .............MindWorx
//                                 .............Scio
//                                 .............Starcraftfreak
//                                 .............FyreDaug
//                                 .............KDEWolf

//  ++++++++++++++++++++++++++++++++++++++++++  NOTES  ++++++++++++++++++++++++++++++++++++++++
//  Greetz fly out to:       NgO . BuranX . JonNny . Darkt3mpl3r . WaRadius . Fireeye
//                     TDG . WC3C . HIVE . Toadcop . xxdingo93xx . Dynasti . TheBlooddancer
//                                                Paladon

//================================================================================================
//Loop - Costum Motion
//================================================================================================
//A very useful system for looping structs. If you want to know more about this small system
//then check out our website. ("www.ngo.clan.su")
//! textmacro CostumMotion takes type,run,end,periodic
  static timer loopExe=CreateTimer()
  static integer size =0
  static $type$ array runStruct[maxIndex]
  boolean active
  boolean paused
 
  static method loopRun takes nothing returns nothing
    local integer index=0
   
    loop
      exitwhen index==$type$.size
     
      if not $type$.runStruct[index].paused then
        if $type$.runStruct[index].active then
          call $type$.runStruct[index].$run$()
          set index=index+1
        else
          call $type$.runStruct[index].$end$()
          set $type$.size=$type$.size-1
          set $type$.runStruct[index]=$type$.runStruct[$type$.size]
        endif
      else
        set index=index+1
      endif
    endloop
   
    if $type$.size==0 then
      call PauseTimer($type$.loopExe)
    endif
  endmethod
 
  static method addMotion takes $type$ data returns integer
    if $type$.size==0 then
      call TimerStart($type$.loopExe,$periodic$,true,function $type$.loopRun)
    endif
 
    set $type$.runStruct[$type$.size]       =data
    set $type$.runStruct[$type$.size].active=true
    set $type$.runStruct[$type$.size].paused=false
    set $type$.size                         =$type$.size+1
   
    return $type$.size
  endmethod
//! endtextmacro

//================================================================================================
//Hashtable Index System
//================================================================================================
library HIS
  globals
    //Config Part
    private constant integer size=8190
    private constant integer pos =0
    //Hashtable Var
    private hashtable tempcache=InitHashtable()
    //Important SystemVars
    private integer array inUse[size]
    private integer array last [size]
    private integer indexsize=0
    private integer lastsize =0
  endglobals
 
  //System Code
  function AddHandleIndex takes handle h returns nothing
    local integer id=GetHandleId(h)
    local integer qi
 
    if HaveSavedInteger(tempcache,id,pos) then
      set qi=LoadInteger(tempcache,id,pos)
      set inUse[qi]=inUse[qi]+1
    elseif lastsize>0 then
      set lastsize             =lastsize-1
      set inUse[last[lastsize]]=1
      call SaveInteger(tempcache,id,pos,last[lastsize])
    else
      set inUse[indexsize]=1
      call SaveInteger(tempcache,id,pos,indexsize)
      set indexsize=indexsize+1
    endif
  endfunction
 
  function GetHandleIndex takes handle h returns integer
    debug if not HaveSavedInteger(tempcache,GetHandleId(h),pos) then
    debug call BJDebugMsg("Error: No index attached to handle [#100]")
    debug endif
    return LoadInteger(tempcache,GetHandleId(h),pos)
  endfunction
 
  function ClearHandleIndex takes handle h returns nothing
    local integer id=GetHandleId(h)
    local integer qi=LoadInteger(tempcache,id,pos)
   
    debug if HaveSavedInteger(tempcache,id,pos) then
      set inUse[qi]=inUse[qi]-1
      if inUse[qi]==0 then
        set last[lastsize]=qi
        set lastsize      =lastsize+1
        call FlushChildHashtable(tempcache,id)
      endif
    debug else
    debug call BJDebugMsg("Error: No index attached to handle [#101]")
    debug endif
  endfunction
endlibrary

//================================================================================================
//Functions - Standart Functions
//================================================================================================
library MainFunctions initializer init
 
  globals
    constant real deg2rad                  =0.017453  //Set the degree to radians value
    constant real rad2deg                  =57.2957795//Set the radians to degree value
    constant integer maxIndex              =8190      //Set the maximal index number
    constant real PreX                     =700.      //Preload X
    constant real PreY                     =700.      //Preload Y
 
    public group loopG                     =null
    public item getWalkable                =null
    public location loc                    =null
    public boolexpr filter                 =null
    constant integer invulnerable_id       ='Avul'
    constant integer purge_buff_id         ='Bprg'
    public constant integer getWalkable_id ='sehr'
    public constant integer flyHack        ='Amrf'
  endglobals

  function GetProVal takes real value returns real
    if value<0. then
      return value*-1
    endif
    return value
  endfunction

  //Little helpful functions
  function ClearTextMessagesForPlayer takes player p returns nothing
    if (GetLocalPlayer()==p) then
      call ClearTextMessages()
    endif
  endfunction
 
  function UnitAddFly takes unit u returns nothing
    call UnitAddAbility(u,flyHack)
    call UnitRemoveAbility(u,flyHack)
  endfunction

  function A2PXY takes real x,real y,real xt,real yt returns real
    return ModuloReal(rad2deg*Atan2(yt-y,xt-x),360.)
  endfunction

  function D2PXY takes real x,real y,real xt,real yt returns real
    local real dx=xt-x
    local real dy=yt-y
    return SquareRoot(dx*dx+dy*dy)
  endfunction

  function IsPointWalkable takes real x,real y returns boolean
    call SetItemPosition(getWalkable,x,y)
    call SetItemVisible(getWalkable,false)
    return GetItemX(getWalkable)==x and GetItemY(getWalkable)==y
  endfunction
 
  function GetPointWalkableX takes real x,real y returns real
    call SetItemPosition(getWalkable,x,y)
    call SetItemVisible(getWalkable,false)
    return GetItemX(getWalkable)
  endfunction
 
  function GetPointWalkableY takes real x,real y returns real
    call SetItemPosition(getWalkable,x,y)
    call SetItemVisible(getWalkable,false)
    return GetItemY(getWalkable)
  endfunction

  function DebugFilter takes nothing returns boolean
     return true
  endfunction

  function GetUnitsInRange takes real radius,real x,real y returns group
    call GroupEnumUnitsInRange(loopG,x,y,radius,filter)
    return loopG
  endfunction
 
  function GetClonedGroup takes group g returns group
    set bj_groupAddGroupDest = loopG
    call ForGroup(g, function GroupAddGroupEnum)
    return loopG
  endfunction

  function RangedReal takes real v,real min,real max returns real
    if v<min then
    //  return min
    elseif v>max then
    //  return max
    endif

    return v
  endfunction
 
  function GetZ takes real x,real y returns real
    call MoveLocation(loc,x,y)
    return GetLocationZ(loc)
  endfunction
 
  //Credits to JonNny for the Parabula
  function GetFlyParabula takes real maxheight , real zs , real zt , real q returns real
    return (maxheight * Sin(q*bj_PI))+ q * (zt-zs)
  endfunction
 
  //Generic unit filter
  function IsUnitNotImmun takes unit c,unit u returns boolean
     if IsUnitEnemy(u,GetOwningPlayer(c)) then
     if GetUnitState(u,UNIT_STATE_LIFE)>0. then
     if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
     if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
       return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
     endif
     endif
     endif
     endif
   
    return false
  endfunction
 
  function IsUnitNotBuffImmune takes unit u returns boolean
    if IsUnitType(u,UNIT_TYPE_RESISTANT)==false then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
      return GetUnitAbilityLevel(u,purge_buff_id)<=0
    endif
    endif
    endif
    endif
   
    return false
  endfunction
 
  function TerrainDeformationRippleXY takes real duration, boolean limitNeg, real x,real y, real startRadius, real endRadius, real depth, real wavePeriod, real waveWidth returns terraindeformation
    local real spaceWave
    local real timeWave
    local real radiusRatio

    if (endRadius <= 0 or waveWidth <= 0 or wavePeriod <= 0) then
        return null
    endif

    set timeWave = 2.0 * duration / wavePeriod
    set spaceWave = 2.0 * endRadius / waveWidth
    set radiusRatio = startRadius / endRadius

    set bj_lastCreatedTerrainDeformation = TerrainDeformRipple(x,y, endRadius, depth, R2I(duration * 1000), 1, spaceWave, timeWave, radiusRatio, limitNeg)
    return bj_lastCreatedTerrainDeformation
  endfunction
 
  //Clearing Handles
  function AB_DestroyTrigger takes trigger trig returns nothing
    if trig!=null then
      call TriggerClearActions(trig)
      call TriggerClearConditions(trig)
      call DestroyTrigger(trig)
    endif
  endfunction

  function AB_DestroyTimer takes timer t returns nothing
    if t!=null then
       call PauseTimer(t)
       call DestroyTimer(t)
    endif
  endfunction

  function AB_DestroyGroup takes group g returns nothing
    if g!=null then
       call GroupClear(g)
       call DestroyGroup(g)
    endif
  endfunction

  function AB_DialogDestroy takes dialog log returns nothing
    if log!=null then
       call DialogClear(log)
       call DialogDestroy(log)
    endif
  endfunction

  function AB_DestroyMultiboard takes multiboard lb returns nothing
    if lb!=null then
       call MultiboardClear(lb)
       call DestroyMultiboard(lb)
    endif
  endfunction

  //Initialization of the varibales
  private function init takes nothing returns nothing
    set getWalkable=CreateItem(getWalkable_id,0,0)
    set loc        =Location(0,0)
    set loopG      =CreateGroup()
    set filter     =Filter(function DebugFilter)
    call SetItemVisible(getWalkable,false)
  endfunction
endlibrary

//Count function for rects in a area
library CountDestructable requires MainFunctions
  globals
     private rect dat_prove=Rect(0,0,0,0)
  endglobals

  private function EnumCountDestructables takes nothing returns nothing
    if GetDestructableLife(GetEnumDestructable())>0 then
        set bj_forLoopAIndex=bj_forLoopAIndex+1
    endif
  endfunction

  function CountDestructableInRangeOfXY takes real x,real y,real range returns integer
    call SetRect(dat_prove,x-range,y-range,x+range,y+range)
    set bj_forLoopAIndex=0
    call EnumDestructablesInRect(dat_prove,MainFunctions_filter,function EnumCountDestructables)
    return bj_forLoopAIndex
  endfunction
endlibrary

//================================================================================================
//Loop - Buff Check (Debug for some spells)
//================================================================================================
//This is just made for this spellpack. If you have questions about this system just ask me.
library BuffCheck requires MainFunctions
  private struct BuffCheckData
    integer buffid
    real time
    real max
    unit u
   
    method check takes nothing returns nothing
      set .time=.time+0.5
      set .active=.time<=.max and GetUnitAbilityLevel(.u,.buffid)>0
    endmethod
   
    method endcheck takes nothing returns nothing
      call UnitRemoveAbility(.u,.buffid)
      set .u=null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("BuffCheckData","check","endcheck","0.5")
  endstruct
 
  function DestroyBuffAfterTime takes unit u,integer buffid,real maxtime returns nothing
    local BuffCheckData bc
 
    if GetUnitAbilityLevel(u,buffid)>0 then
      call UnitRemoveAbility(u,buffid)
    else
      set bc=BuffCheckData.create()
      set bc.u     =u
      set bc.buffid=buffid
      set bc.time  =0.
      set bc.max   =maxtime
     
      call BuffCheckData.addMotion(bc)
    endif
  endfunction
endlibrary

//================================================================================================
//Loop - Buff Effects
//================================================================================================
//This is just made for this spellpack. If you have questions about this system just ask me.
//! textmacro BuffEffect takes abilityId,periodic,prefix
  private struct $prefix$BuffData
    static timer loopExe=CreateTimer()
    static integer size =0
    static integer array executer          [maxIndex]
    static $prefix$BuffData array runStruct[maxIndex]
   
    unit victim
   
    real duration
    real time
   
    static method BuffCheck takes nothing returns nothing
      local integer index=0
      local integer id
     
      loop
        exitwhen index==$prefix$BuffData.size
       
        set id=$prefix$BuffData.executer[index]
        set $prefix$BuffData.runStruct[id].time=$prefix$BuffData.runStruct[id].time+$periodic$
        if $prefix$BuffData.runStruct[id].time>=$prefix$BuffData.runStruct[id].duration then
          call UnitRemoveAbility($prefix$BuffData.runStruct[id].victim,$abilityId$)
          call ClearHandleIndex($prefix$BuffData.runStruct[id].victim)
          set $prefix$BuffData.runStruct[id].victim=null
          call $prefix$BuffData.runStruct[id].destroy()
          set $prefix$BuffData.size=$prefix$BuffData.size-1
          set $prefix$BuffData.executer[index]=$prefix$BuffData.executer[$prefix$BuffData.size]
        elseif not IsUnitNotBuffImmune($prefix$BuffData.runStruct[id].victim) then
          call UnitRemoveAbility($prefix$BuffData.runStruct[id].victim,$abilityId$)
          call ClearHandleIndex($prefix$BuffData.runStruct[id].victim)
          set $prefix$BuffData.runStruct[id].victim=null
          call $prefix$BuffData.runStruct[id].destroy()
          set $prefix$BuffData.size=$prefix$BuffData.size-1
          set $prefix$BuffData.executer[index]=$prefix$BuffData.executer[$prefix$BuffData.size]
        else
          set index=index+1
        endif
      endloop
     
      if $prefix$BuffData.size==0 then
        call PauseTimer($prefix$BuffData.loopExe)
      endif
    endmethod
  endstruct
 
  private function UnitAdd$prefix$Buff takes unit victim,real duration,integer lvl returns nothing
    local integer index
 
    if $prefix$BuffData.size==0 then
      call TimerStart($prefix$BuffData.loopExe,$periodic$,true,function $prefix$BuffData.BuffCheck)
    endif
    if GetUnitAbilityLevel(victim,$abilityId$)>0 then
      set index=GetHandleIndex(victim)
      call UnitRemoveAbility(victim,$abilityId$)
    else
      call AddHandleIndex(victim)
      set index                                           =GetHandleIndex(victim)
      set $prefix$BuffData.runStruct[index]               =$prefix$BuffData.create()
      set $prefix$BuffData.executer[$prefix$BuffData.size]=index
      set $prefix$BuffData.size                           =$prefix$BuffData.size+1
    endif
   
    set $prefix$BuffData.runStruct[index].victim   =victim
    set $prefix$BuffData.runStruct[index].duration =duration
    set $prefix$BuffData.runStruct[index].time     =0.
   
    call UnitAddAbility(victim,$abilityId$)
    call SetUnitAbilityLevel(victim,$abilityId$,lvl)
  endfunction
//! endtextmacro

//================================================================================================
//Loop - Motion System
//================================================================================================
//This is a easy motion system which make some basic motions.
//It's helpful if you don't want to write some stuff again and
//again.
library MotionDatabase initializer init requires MainFunctions
  globals
     private constant real MinimalChaseRange=10.
     
     public unit tm        //Temp Missle
     public unit tc        //Temp Caster
     public unit tv        //Temp Victim
     public integer tdata  //Temp Data
     
     private rect MaxArea                   =null
     public real periodic                   =0.03
  endglobals

  struct JumpDatabase
    unit u
   
    real distance
    real maxdistance
    real angle
    real speed
   
    real x
    real y
    real mx
    real my
    real array z[3]
   
    method motion takes nothing returns nothing
       local real curv
       local real x
       local real y
       local real z
       
       set .distance=.distance+.speed
       
       if .distance>.maxdistance then
         call SetUnitFlyHeight(.u,GetUnitDefaultFlyHeight(.u),0)
         set .active=false
       else
         set x=.x+.mx
         set y=.y+.my
         set z=GetZ(x,y)
         set curv=GetFlyParabula(.z[1],.z[0],.z[2],.distance/.maxdistance) + (.z[0]-z)

         if RectContainsCoords(MaxArea,x,y) then
           call SetUnitPosition(.u,x,y)
           set .x=x
           set .y=y
         endif
         call SetUnitFlyHeight(.u,curv,0)
       endif
    endmethod
   
    method endmotion takes nothing returns nothing
       set .u=null
       call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("JumpDatabase","motion","endmotion","periodic")
  endstruct
 
  struct ChaseDatabase
     unit u
     unit target
     unit attacker
     
     real speed
     real z
     real Rz
     
     string endfunc
     integer data
     integer loopMember
     
     method motion takes nothing returns nothing
        local real Ux             =GetUnitX(.u)
        local real Uy             =GetUnitY(.u)
        local real Tx             =GetUnitX(.target)
        local real Ty             =GetUnitY(.target)
        local real distance       =D2PXY(Ux,Uy,Tx,Ty)
        local real angle
       
        if distance>MinimalChaseRange then
          set angle=Atan2(Ty-Uy,Tx-Ux)
          set Ux=Ux+.speed*Cos(angle)
          set Uy=Uy+.speed*Sin(angle)
         
          call SetUnitPosition(.u,Ux,Uy)
          call SetUnitFlyHeight(.u,.z,.Rz)          
        else
          set .active=false
        endif
     endmethod
     
     method endmotion takes nothing returns nothing
       set tv   =.target
       set tm   =.u
       set tc   =.attacker
       set tdata=.data
       call ExecuteFunc(.endfunc)
       
       set .u       =null
       set .target  =null
       set .attacker=null
       call .destroy()
     endmethod
     
     //! runtextmacro CostumMotion("ChaseDatabase","motion","endmotion","periodic")
  endstruct
 
  struct CollisionDatabase
     unit u
     unit attacker
 
     real speed
     real angle
     real z
     real Rz
     real range
     real distance
     real x
     real y
     
     string endfunc
     integer data
     integer loopMember
     
     
     method motion takes nothing returns nothing
        local unit a
        local group g
        local integer c
       
        set .distance=.distance-.speed
       
        if .distance>0. then
          set .x=.x+.speed*Cos(.angle)
          set .y=.y+.speed*Sin(.angle)
          call SetUnitPosition(.u,.x,.y)
          call SetUnitFlyHeight(.u,.z,.Rz)  
         
          set g=GetUnitsInRange(.range,.x,.y)
          set c=0
          loop
            set a=FirstOfGroup(g)
            exitwhen a==null
            call GroupRemoveUnit(g,a)
           
            if IsUnitNotImmun(.attacker,a) and a!=.u then
              set c=c+1
            endif
          endloop
          call GroupClear(g)
          set g=null
         
          set .active=c<=0
        else
          set .active=false
        endif
     endmethod
     
     method endmotion takes nothing returns nothing
        set tc   =.attacker
        set tm   =.u
        set tdata=.data
        call ExecuteFunc(.endfunc)
       
        set .u       =null
        set .attacker=null
        call .destroy()
     endmethod
     
     //! runtextmacro CostumMotion("CollisionDatabase","motion","endmotion","periodic")
  endstruct
 
  function LaunchMissileAtPointEx takes unit u,real x1,real y1,real bZ,real maxZ,real x2,real y2,real endz,real speed returns nothing
    local JumpDatabase JD  =JumpDatabase.create()

    set JD.u            =u    
    set JD.z[0]         =GetZ(x1,y1)+bZ
    set JD.z[1]         =maxZ
    set JD.z[2]         =GetZ(x2,y2)+endz
    set JD.x            =x1
    set JD.y            =y1
    set JD.speed        =speed
    set JD.distance     =0.
    set JD.maxdistance  =D2PXY(x1,y1,x2,y2)
    set JD.angle        =Atan2(y2-y1,x2-x1)
    set JD.mx           =speed*Cos(JD.angle)
    set JD.my           =speed*Sin(JD.angle)
   
    call UnitAddFly(u)
    call SetUnitX(u,x1)
    call SetUnitY(u,y1)
    call JumpDatabase.addMotion(JD)
  endfunction
 
  function LaunchNormalChaseMissileAtPointEx takes unit attacker,unit missile,real x1,real y1,real z,unit victim,real speed,real Zrate,string colfunc,integer data returns nothing
    local ChaseDatabase CD  =ChaseDatabase.create()

    set CD.u         =missile    
    set CD.z         =z
    set CD.attacker  =attacker
    set CD.target    =victim
    set CD.speed     =speed
    set CD.endfunc   =colfunc
    set CD.Rz        =Zrate
    set CD.data      =data
   
    call UnitAddFly(missile)
    call SetUnitX(missile,x1)
    call SetUnitY(missile,y1)
    call ChaseDatabase.addMotion(CD)
  endfunction
     
  function LaunchNormalCollisionMissileAtPointEx takes unit attacker,unit missile,real x1,real y1,real z,real x2,real y2,real speed,real range,string colfunc,integer data returns nothing
    local CollisionDatabase CD  =CollisionDatabase.create()
   
    set CD.u          =missile
    set CD.attacker   =attacker
    set CD.z          =z
    set CD.Rz         =0.
    set CD.x          =x1
    set CD.y          =y1
    set CD.range      =range
    set CD.speed      =speed
    set CD.endfunc    =colfunc
    set CD.distance   =D2PXY(x1,y1,x2,y2)
    set CD.angle      =Atan2(y2-y1,x2-x1)
    set CD.data       =data
   
    call UnitAddFly(missile)
    call SetUnitX(missile,x1)
    call SetUnitY(missile,y1)
    call CollisionDatabase.addMotion(CD)
  endfunction
 
  private function init takes nothing returns nothing
    set MaxArea=bj_mapInitialPlayableArea
  endfunction
endlibrary

//================================================================================================
//Timer - Timer Recycler
//================================================================================================
//This is a standart timer recycler. It's so fast like TimerUtils and some benchmark tests
//showed that this system seems to be sometimes faster than both TimerUtil versions.
//But try it out yourself.
library TimerRecycler requires MainFunctions,HIS
   globals
     private constant integer pos     =0
     
     private hashtable hs             =InitHashtable()
     private integer lastsize         =0
     private timer array last[maxIndex]
   endglobals
   
   //! textmacro NextTimer takes name,type,func
   function GetNextTimer$name$ takes $type$ dat returns timer
     local integer index
     local timer temp
     
     if lastsize>0 then
       set lastsize=lastsize-1
       set temp    =last[lastsize]
     else
       set temp    =CreateTimer()
     endif
     call AddHandleIndex(temp)
     call Save$func$(hs,GetHandleIndex(temp),pos,dat)
     return temp
   endfunction
   //! endtextmacro
   
   //! runtextmacro NextTimer("Int","integer","Integer")
   //! runtextmacro NextTimer("Agent","agent","AgentHandle")
   //! runtextmacro NextTimer("TextTag","texttag","TextTagHandle")
   //! runtextmacro NextTimer("Lightning","lightning","LightningHandle")
   
   //! textmacro GetType takes name,type,func
   function GetTimerData$name$ takes timer t returns $type$
     return Load$func$(hs,GetHandleIndex(t),pos)
   endfunction
   //! endtextmacro
   
   //! runtextmacro GetType("Int","integer","Integer")
   //! runtextmacro GetType("Unit","unit","UnitHandle")
   //! runtextmacro GetType("Effect","effect","EffectHandle")
   //! runtextmacro GetType("Lightning","lightning","LightningHandle")
   //! runtextmacro GetType("TextTag","texttag","TextTagHandle")
   
   function RecycleTimer takes timer t returns nothing
     local integer index=GetHandleIndex(t)
     call PauseTimer(t)
     call ClearHandleIndex(t)
     
     set last[lastsize]=t
     set lastsize      =lastsize+1
   endfunction
endlibrary

//================================================================================================
//Group - Group Recycler
//================================================================================================
//A standart group recycler.
library GroupRecycler requires MainFunctions,HIS
   globals
     private integer max              =0
     private integer cmax             =0
     
     private group array rGroup
     private integer array rInt[maxIndex]
   endglobals

   function GetNextGroup takes nothing returns group
     set cmax=cmax+1
     if max<cmax then
       set rGroup[cmax]=CreateGroup()
       set max         =cmax
     endif
     call AddHandleIndex(rGroup[cmax])
     set rInt[GetHandleIndex(rGroup[cmax])]=cmax
     return rGroup[cmax]
   endfunction
   
   function RecycleGroup takes group g returns nothing
     local integer index=GetHandleIndex(g)
     call ClearHandleIndex(g)
     set rGroup[rInt[index]]               =rGroup[cmax]
     set rInt[GetHandleIndex(rGroup[cmax])]=rInt[index]
     set rGroup[cmax]                      =g
     set cmax=cmax-1
   endfunction
endlibrary

//================================================================================================
//Timed - Handle Destroy
//================================================================================================
//Some small useful functions.
library TimedHandleDead requires MainFunctions,TimerRecycler
  function U2Death takes nothing returns nothing
    local timer t = GetExpiredTimer()
    call RemoveUnit(GetTimerDataUnit(t))
    call RecycleTimer(t)
    set t=null
  endfunction

  function U2Null takes unit u,real duration returns nothing
    local timer t = GetNextTimerAgent(u)
    call TimerStart(t,duration,false,function U2Death)
    set t = null
  endfunction

  function E2Death takes nothing returns nothing
    local timer t = GetExpiredTimer()
    call DestroyEffect(GetTimerDataEffect(t))
    call RecycleTimer(t)
    set t=null
  endfunction

  function E2Null takes effect e,real duration returns nothing
    local timer t = GetNextTimerAgent(e)
    call TimerStart(t,duration,false,function E2Death)
    set t = null
  endfunction

  function L2Death takes nothing returns nothing
    local timer t = GetExpiredTimer()
    call DestroyLightning(GetTimerDataLightning(t))
    call RecycleTimer(t)
    set t=null
  endfunction

  function L2Null takes lightning l,real duration returns nothing
    local timer t = GetNextTimerLightning(l)
    call TimerStart(t,duration,false,function L2Death)
    set t = null
  endfunction

  function TT2Death takes nothing returns nothing
    local timer t = GetExpiredTimer()
    call DestroyTextTag(GetTimerDataTextTag(t))
    call RecycleTimer(t)
    set t=null
  endfunction

  function TT2Null takes texttag tt,real duration returns nothing
    local timer t = GetNextTimerTextTag(tt)
    call TimerStart(t,duration,false,function L2Death)
    set t = null
  endfunction
endlibrary

//================================================================================================
//Passiv - Damage Skill
//================================================================================================
//This system will be useful for skills like my Crush or Holy Shock spell. For more
//informations just ask me.
library DamageSkill initializer init requires MainFunctions,TimerRecycler
  globals
    private boolexpr array ExecuteFunction[maxIndex]
    private unit array Attacker[maxIndex]
    private unit array Attacked[maxIndex]
 
    private trigger DamageDetect=null
    private trigger EventExecute=null
    private group InUseCache    =null
    private group RegisterCache =null
   
    public unit attacker=null
    public unit attacked=null
    public real damage  =0.
  endglobals
 
  function TriggerAddDamageEvent takes unit a,unit b,code func returns nothing
    local integer id
 
    if not IsUnitInGroup(a,RegisterCache) then
      call TriggerRegisterUnitEvent(DamageDetect,a,EVENT_UNIT_DAMAGED)
      call GroupAddUnit(RegisterCache,a)
    endif
    if not IsUnitInGroup(b,InUseCache) then
       call AddHandleIndex(b)
       set id=GetHandleIndex(b)
      call GroupAddUnit(InUseCache,b)
    else
       set id=GetHandleIndex(b)
      call DestroyBoolExpr(ExecuteFunction[id])
    endif
   
    set ExecuteFunction[id]=Filter(func)
    set Attacker[id]       =b
    set Attacked[id]       =a
  endfunction
 
  private function CheckRegister takes nothing returns boolean
    return IsUnitInGroup(GetEventDamageSource(),InUseCache)
  endfunction
 
  private function GetDamage takes nothing returns nothing
    local integer id         =GetHandleIndex(GetEventDamageSource())
    local triggercondition tc
 
    set attacker=Attacker[id]
    set attacked=Attacked[id]
    set damage  =GetEventDamage()
 
    set tc=TriggerAddCondition(EventExecute,ExecuteFunction[id])
    call TriggerEvaluate(EventExecute)
    call TriggerRemoveCondition(EventExecute,tc)
    call DestroyBoolExpr(ExecuteFunction[id])
    call GroupRemoveUnit(InUseCache,Attacker[id])
    call ClearHandleIndex(Attacker[id])
   
    set ExecuteFunction[id]=null
    set Attacker[id]       =null
    set Attacked[id]       =null
    set tc                 =null
  endfunction
 
  private function init takes nothing returns nothing
    set InUseCache    =CreateGroup()
    set RegisterCache =CreateGroup()
    set DamageDetect  =CreateTrigger()
    set EventExecute  =CreateTrigger()
    call TriggerAddAction(DamageDetect,function GetDamage)
    call TriggerAddCondition(DamageDetect,Condition(function CheckRegister))
  endfunction
endlibrary
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
  local timer t=CreateTimer()
  call DisplayTimedTextToPlayer(Player(0),0,0,60,I2S(H2I(t)-minIndex))
  call DestroyTimer(t)
  set t=null
endfunction

//===========================================================================
function InitTrig_HandleCountTester takes nothing returns nothing
    set gg_trg_HandleCountTester = CreateTrigger(  )
    call TriggerRegisterPlayerEvent( gg_trg_HandleCountTester, Player(0),EVENT_PLAYER_END_CINEMATIC )
    call TriggerAddAction( gg_trg_HandleCountTester, function Trig_Untitled_Trigger_001_Actions )
endfunction

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
                                   ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
                                  Û                Û              
                                  Û                Û
                                   ßßßßßÛ    Ûßßßßß
                                        Û    Û
                                        Û    Û  ÜÜÜÜÜÜ        ÜÜÜÜÜÜÜ  
                                        Û    Û  Û     Û      Û       Û
                                        Û    Û  Û  Ü   Û    Û   Ûßßßßßß
                                        Û    Û  Û  ÛÛ   Û   Û   Û
                                        Û    Û  Û  Û Û   Û  Û   Û   ÜÜÜ
                                        Û    Û  Û  Û  Û  Û  Û   Û  Û  Û
                                        Û    Û  Û  ßßß   Û  Û   ÛÜÜÛ  Û
                                        Û    Û  Û       Û    Û       Û
                                         ßßßß   ßßßßßßßß      ßßßßßßß  

                                    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
                                    ³       Clan TDG @ Azeroth ¸       ³
                                    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ


Thanks to all who wrote me PMs and gave me feedback. I decided to repack the whole script to make the spells faster and better.
Soon I will add new spells to this spellpack. Your feedback is wanted please give me ideas so that I can go on making a good spellpack.

  I like to thank the whole NgO clan. Special thanks to:
    - Darkt3mpl3r for your good spell ideas, your spellmap terrain and improvement ideas on my spells and for his tooptips...
    - JonNny big thank to you otherwise I would have still a bugged crush and boomerang your testing made them bugfree...
    - Flame_Phoenix for reporting me those buff bugs and some other small bugs
    - WaRadius for being taliban (ya know what I mean) and for his paralyzing field mdl
    - Fireeye for reporting me forgotten bj functions
    - Flame_phoenix for reporting me several spell bugs
    - joel79 for gaving me the idea to continue/repack this spellback
    - johannesr for reporting a bug of the bloody run spell
    - thanks to Paladon for reporting me the caching bug
    - pbnjamma for feedback
    - MoK_Exalted for feedback
    - Vexorian/PitzerMike for the uberkewl JassGenNewPack
    - Hiveworkshop.com for hosting my spellpack
   
                                                       
Contact:

  HP:   "www.jx3.net/TDG"
  ICQ:  "397-122-064"
  Bnet: "tdg.hanky"
      *Gate: Azeroth
           *Channel: "Clan Tdg"
  MSN:  "CryptHanky@live.de"
  AIM:  "CryptHanky@aol.com"
 
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
Question:  'Is there any tutorial how I can import the spells?

Answer:    Yes there is a tutorial at "http://ngo.clan.su/forum/7-12-1".
               
               
//TESH.scrollpos=0
//TESH.alwaysfold=0
'Advice:

  Its nearly all time the same. You just have to import everything what have the name of the spell and nearly all time you have to
  import the dummy. Also remember not just to copy and paste the dummy unit in the unit editor, also copy the dummy.mdl! Problems
  like "Why the spell don'
t work after a while?" are easy to explain and to fix. This spells will work fine on leakfree maps but they
  will maybe cause problems at maps that leak. Because of that sometime I will make a version which use the gamecache so that you can
  leak so much you want and the spells still will work. That version will be only aviable at our clan homepage. ("
www.ngo.clan.su")

 
'What you need for which spell:

 '-Boomerang:
   > Spell ("
Ability Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 '-Crush:
   > Spell Effect ("
Ability Editor")
   > Spell ("
Ability Editor")
   > 2 Buffs ("
Buff Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > Mainscript
   > SpellScript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 '-Electric Field:
   > Spell Effect ("
Ability Editor")
   > Spell ("
Ability Editor")
   > Buff ("
Buff Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 '-Fire Bombs:
   > Spell Effect ("
Ability Editor")
   > Spell ("
Ability Editor")
   > Buff ("
Buff Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 '-Dark Torture:
   > Spell Effect ("
Ability Editor")
   > Spell ("
Ability Editor")
   > 5 Buffs ("
Buff Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 '-Frost Sphere:
   > Spell Effect ("
Ability Editor")
   > Spell ("
Ability Editor")
   > Buff ("
Buff Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 '-Bloody Run:
   > Spell Effect ("
Ability Editor")
   > Spell ("
Ability Editor")
   > Buff ("
Buff Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 'Mystic Net:
   > Spell Effect ("
Ability Editor")
   > Spell ("
Ability Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 'Critical Jump:
   > Spell Effect ("
Ability Editor")
   > Buff Caster ("
Ability Editor")
   > Spell ("
Ability Editor")
   > Buff ("
Buff Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 'Paralyzing Field:
   > Spell Effect ("
Ability Editor")
   > Spell ("
Ability Editor")
   > Dummy Missile ("
Unit Editor")
   > dummy.mdx
   > FinalField.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 'Burrowstrike:
   > Spell Effect ("
Ability Editor")
   > Spell ("
Ability Editor")
   > Spell Effect ("
Ability Editor"")
   > Dummy Missile ("Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 'Holy Shock
   > Spell ("Ability Editor")
   > Dummy Missile ("Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 '
Jade Shield
   > Spell ("Ability Editor")
   > Dummy Missile ("Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
 'Berserker Rush
   > Spell Effect ("Ability Editor")
   > Spell ("Ability Editor")
   > Spell Effect ("Ability Editor"")
   > Dummy Missile ("Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
  '
Brain Soak
   > Spell Effect ("Ability Editor")
   > Spell ("Ability Editor")
   > Dummy Missile ("Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
  'Aggressive Infection
   > Spell Effect ("Ability Editor")
   > Spell ("Ability Editor")
   > Dummy Missile ("Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)

  '
Thunder Clash
   > Spell Effect ("Ability Editor")
   > Spell ("Ability Editor")
   > Dummy Missile ("Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
   
  'Whippy Rope
   > Spell ("Ability Editor")
   > Dummy Missile ("Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)

  '
Backdoor
   > 2 Spell Effects ("Ability Editor")
   > 2 Spells ("Ability Editor")
   > Dummy Missile ("Unit Editor")
   > dummy.mdx
   > Mainscript
   > Spellscript
   > JassGenNewPack 5b (JassHelper 0.9.F.1)
//TESH.scrollpos=0
//TESH.alwaysfold=0
'Version 1.0:

'
Boomerang:
You throw two boomerangs at the selected area. Every boomerang missile make just one time damage. So if you hit a unit with both boomerangs the unit will get two times damage!
Level 1 - 60 damage per missile
Level 2 - 90 damage per missile
Level 3 - 120 damage per missile
Level 4 - 150 damage permissile
Level 5 - 180 damage per missile

'Crush:
Your unit have the chance to push a enemy unit away.
Level 1 - Chance of crushing 15%
Level 2 - Chance of crushing 20%
Level 3 - Chance of crushing 25%
Level 4 - Chance of crushing 30%
Level 5 - Chance of crushing 35%

'
Electrical Field:
Your unit throw some electro - bombs at the selected area.
Level 1 - 45 damage per bomb
Level 2 - 60 damage per bomb
Level 3 - 75 damage per bomb
Level 4 - 90 damage per bomb
Level 5 - 105 damage per bomb

'Frost Sphere:
Create a frost sphere which move to the selected point. During the time where the frost sphere is moving it shot some little ice missiles which make some damage on the enemy unit!
Level 1 - 95 damage per missile
Level 2 - 185 damage per missile
Level 3 - 275 damage per missile

'
Critical Jump:
Your unit jump at the selected area and give all enemy units who are in the near damage.
Level 1 - 125 damage
Level 2 - 200 damage
Level 3 - 275 damage
Level 4 - 350 damage
Level 5 - 425 damage

'Fire Bombs:
Your unit throw some fire bombs at the selected area. If a enemy unit is the near of a explosion the unit get damage.
Level 1 - 45 damage per missile
Level 2 - 90 damage per missile
Level 3 - 135 damage per missile
Level 4 - 180 damage per missile
Level 5 - 225 damage per missile

'
Bloody Run:
Your unit will run so fast to the selected point that all units who are in the near of your unit get damage.
Level 1 - 75 damage per unit.
Level 2 - 125 damage per unit.
Level 3 - 175 damage per unit.
Level 4 - 225 damage per unit.
Level 5 - 275 damage per unit.

//---------------------------------------------------------------------------------------------------------------
'Update to Version: 1.2
-added a new spell
-cleaned script up

New Spell:
______________________________________
'
Dark Torture:
Make the targeted unit bigger and bigger and because of the hard deformation of the body the unit get every second some damage.
Level 1 - 30 damage per second
Level 2 - 40 damage per second
Level 3 - 50 damage per second
Level 4 - 60 damage per second
Level 5 - 70 damage per second
//---------------------------------------------------------------------------------------------------------------
'Update to Version 1.2a
-fixed bug from boomerang
-fixed bug from bloody run
-fixed bug from crush

//---------------------------------------------------------------------------------------------------------------
'
Update to Version 1.2b
-fixed buff bug

//---------------------------------------------------------------------------------------------------------------
'Update to Version 1.3
-fixed bug from dark torture
-added a spell

New Spell:
__________________________________________________ ____________
'
Mystic Net:
Shoot a rope at the selected direction and when the rope hit a unit the unit will be dragged to your unit also the enemy unit get some damage for the impact at the ground.
Level 1 - 80 damage
Level 2 - 140 damage
Level 3 - 200 damage
Level 4 - 260 damage
Level 5 - 320 damage

//---------------------------------------------------------------------------------------------------------------
'Update to Version 1.4
-added a spell
-removed some little bugs

NewSpell:
__________________________________________________ ____________
'
Implosion:
Create a implosion in the targeted unit so the unit get every second some damage and after the some seconds the unit implode and damage all ally units in the near.
Level 1 - 20 damage per second, 50 implode damage
Level 2 - 40 damage per second, 100 implode damage
Level 3 - 60 damage per second, 150 implode damage
Level 4 - 80 damage per second, 200 implode damage
Level 5 - 100 damage per second, 250 implode damage

__________________________________________________ ____________

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
'Version 1.0 Repacked:

- repacked the whole script from all spells and from the mainscript
- better performance
- better to modificate
- cleared all known bugs

'
Version 1.0a Repacked:

- bugs fixed
- bjs removed
- leak fixed

'Version 1.1 Repacked:

- added burrowstrike
- added paralyzing field
- added tutorials and help

'
Version 1.1a Repacked:

- added Holy Shock
- added other cache system what need Gamecache (for infos watch at "Cache Help")

'Version 1.2 Repacked:

- added Berserker Rush
- added Jade Shield
- modified Holy Shock
- fixed a bug

'
Version 1.2a Repacked:

- fixed Bloody Run bug

'Version 1.2b Repacked:

- added new index system
- added constant to critical jump

'
Version 1.2c Repacked:

- fixed all known bugs

'Version 1.3 Repacked:

- some script repacked
- added Timer Recycling
- better performance
- fixed all known bugs
- added Brain Soak
- added Thunder Clash
- added Aggressive Infection

'
Version 1.4 Repacked:

- removed the indexing system
- again improved performance
- new jump parabola (thanks to JonNny)
- fixed all known bugs
- added group recycler
- added Whippy Rope
- added Backdoor
- added to every spell a adjustable filter

'Version 1.4a Repacked

- buff fixes
- motion loop improved
- bug fixes
- cleaner code

'
Version 1.5 Repacked

- fixes because of 1.24
- added HandleIndexer
- modified TimerRecycler
NFO
  Events
    Map initialization
  Conditions
  Actions
    Custom script: call BJDebugMsg("|cff8000ffVisit ''www.jx3.net/TDG''!|r")
    Visibility - Disable fog of war
    Visibility - Disable black mask
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Revive_Stuff_Actions takes nothing returns nothing
    local unit u      =GetTriggerUnit()
    local real x      =GetUnitX(u)
    local real y      =GetUnitY(u)
    call TriggerSleepAction( 10.00 )
    if IsUnitType(u, UNIT_TYPE_HERO)==true then
        call ReviveHero(u, x,y, true )
    else
        call CreateUnit(Player(1),GetUnitTypeId(u),x,y,GetUnitFacing(u))
    endif
    set u  =null
endfunction

//===========================================================================
function InitTrig_Revive_Stuff takes nothing returns nothing
    set gg_trg_Revive_Stuff = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEvent(gg_trg_Revive_Stuff, Player(0),EVENT_PLAYER_UNIT_DEATH, MainFunctions_filter)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Revive_Stuff, Player(1),EVENT_PLAYER_UNIT_DEATH, MainFunctions_filter)
    call TriggerAddAction( gg_trg_Revive_Stuff, function Trig_Revive_Stuff_Actions )
endfunction

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Boomerang by OrkOfMordor aka Hanky aka MDZ-OrkOfMordor

scope Boomerang initializer init
   //===================================================================================================================
   //Constants
  globals
     private constant integer SpellId          ='A000'  //Ability Rawcode: Boomerang
     private constant integer DummyId          ='e000'  //Unit Rawcode: Dummy
     private constant string MissileEffectMdl  ="Abilities\\Weapons\\ShadowHunterMissile\\ShadowHunterMissile.mdl"  //The model of the missile
     private constant string DamageEffectMdl   ="Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"  //The damage model
     private constant string DamageAttachPoint ="chest" //The attach point of DamageEffectMdl
     private constant string MissileAttachPoint="chest" //The attach point of MissileEffectMdl
     private constant real MissileSpeed        =15.00   //The missile speed
     private constant real Range               =90.00   //The collision range of the missiles
     private constant real periodic            =0.03    //The periodic motion time
  endglobals

  private constant function Damage takes integer lvl returns real
    //Damage the victim units gets
    return (30.*lvl)+30.
  endfunction

  private constant function TurnSpeed takes real ctmp returns real
    //Turn Speed of the missiles
    return (1.1*ctmp)+2
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================

  //Conditions
  private function Boomerang_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SpellId
  endfunction
 
  //Actions
  private struct BoomerangDatas
    real dmg
    real distance
    unit caster
    real ctmp
    real dtmp
    real angle
    real x
    real y
    unit missile
    group rdyg
    effect gfx
    boolean back
    real side
   
    method motion takes nothing returns nothing
      local group g             =GetUnitsInRange(Range,.x,.y)
      local unit a
      local real x              =0
      local real y              =0
      local real angle
      local real distance
     
      call GroupRemoveUnit(g,.missile)
      loop
        set a=FirstOfGroup(g)
        exitwhen a==null
        call GroupRemoveUnit(g,a)

        if UnitFilter(.caster,a) and not IsUnitInGroup(a,.rdyg) then
          call GroupAddUnit(.rdyg,a)
          call UnitDamageTarget(.caster,a,.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
          call DestroyEffect(AddSpecialEffectTarget(DamageEffectMdl,a,DamageAttachPoint))
        endif        
      endloop

      if .dtmp<=.distance and .ctmp<=180 then
        set angle=.angle*deg2rad
        set .x=.x+MissileSpeed*Cos(angle)
        set .y=.y+MissileSpeed*Sin(angle)
       
        call SetUnitPosition(.missile,.x,.y)
        call SetUnitFacing(.missile,.angle)        
        set .dtmp=.dtmp+MissileSpeed
      elseif .ctmp<=180 then
        set .ctmp=TurnSpeed(.ctmp)
        set angle=(.angle+.ctmp*.side)*deg2rad
        set .x   =.x+MissileSpeed*Cos(angle)
        set .y   =.y+MissileSpeed*Sin(angle)
       
        call SetUnitPosition(.missile,.x,.y)
        call SetUnitFacing(.missile,.angle)
      else
        set x       =GetUnitX(.caster)
        set y       =GetUnitY(.caster)
        set angle   =Atan2(y-.y,x-.x)
        set .angle  =angle*rad2deg
        set distance=D2PXY(.x,.y,x,y)
        set .x      =.x+MissileSpeed*Cos(angle)
        set .y      =.y+MissileSpeed*Sin(angle)
       
        call SetUnitPosition(.missile,.x,.y)
        call SetUnitFacing(.missile,.angle)
       
        set .active=distance>Range
      endif
     
      set g=null
    endmethod
   
    method endmotion takes nothing returns nothing
       call DestroyEffect(.gfx)
       call RemoveUnit(.missile)
       call GroupClear(.rdyg)
       call RecycleGroup(.rdyg)
       
       set .caster     =null
       set .missile    =null
       set .rdyg       =null
       set .gfx        =null
   
       call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("BoomerangDatas","motion","endmotion","periodic")
  endstruct
 
  private function Boomerang_Actions takes nothing returns nothing
    local BoomerangDatas dat1 =BoomerangDatas.create()
    local BoomerangDatas dat2 =BoomerangDatas.create()
    local unit u              =GetTriggerUnit()
    local real x              =GetUnitX(u)
    local real y              =GetUnitY(u)
    local real lx             =GetSpellTargetX()
    local real ly             =GetSpellTargetY()
    local real angle          =A2PXY(x,y,lx,ly)
    local real distance       =D2PXY(x,y,lx,ly)*75/100
   
    //Data 1
    set dat1.dmg     =Damage(GetUnitAbilityLevel(u,SpellId))
    set dat1.distance=distance
    set dat1.caster  =u
    set dat1.ctmp    =0.
    set dat1.dtmp    =0.
    set dat1.angle   =angle+25
    set dat1.x       =x
    set dat1.y       =y
    set dat1.missile =CreateUnit(Player(14),DummyId,x,y,angle+15)
    set dat1.gfx     =AddSpecialEffectTarget(MissileEffectMdl,dat1.missile,MissileAttachPoint)
    set dat1.rdyg    =GetNextGroup()
    set dat1.back    =false
    set dat1.side    =-1.
    call SetUnitX(dat1.missile,x)
    call SetUnitY(dat1.missile,y)
    call BoomerangDatas.addMotion(dat1)
   
    //Data 2
    set dat2.dmg     =Damage(GetUnitAbilityLevel(u,SpellId))
    set dat2.distance=distance
    set dat2.caster  =u
    set dat2.ctmp    =0.
    set dat2.dtmp    =0.
    set dat2.angle   =angle-25
    set dat2.x       =x
    set dat2.y       =y
    set dat2.missile =CreateUnit(Player(14),DummyId,x,y,angle-15)
    set dat2.gfx     =AddSpecialEffectTarget(MissileEffectMdl,dat2.missile,MissileAttachPoint)
    set dat2.rdyg    =GetNextGroup()
    set dat2.back    =false
    set dat2.side    =1.
    call SetUnitX(dat2.missile,x)
    call SetUnitY(dat2.missile,y)
    call BoomerangDatas.addMotion(dat2)

    set u  =null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0

    set gg_trg_Boomerang = CreateTrigger()
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Boomerang, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Boomerang, Condition( function Boomerang_Conditions ) )
    call TriggerAddAction( gg_trg_Boomerang, function Boomerang_Actions )
   
    //Preload
    call Preload(MissileEffectMdl)
    call Preload(DamageEffectMdl)
  endfunction
endscope
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Crush by OrkOfMordor aka Hanky aka MDZ-OrkOfMordor

scope Crush initializer init
   //===================================================================================================================
   //Constants
  globals
     private constant integer SpellId  ='A001'  //Ability Rawcode: Crush
     private constant integer BuffAddId='A019'  //Ability Rawcode: Crush - Effect
     private constant integer DummyId  ='e000'  //Unit Rawcode: Dummy
     private constant real MotionSpeed =10.00   //The speed of the knockback for the target
     private constant real MaxPushTime =0.50    //The maximal knockback time
     private constant string PushMdl   ="Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"  //The damage model
     private constant string PushAtt   ="origin"//The attach point of PushMdl
     private constant real periodic    =0.03    //The periodic motion time
     
     private rect MaxArea              =null    //The maximal movearea of the missiles
  endglobals

  private constant function Chance takes integer lvl returns real
    //The chance of a knockback
    return 10.+(5.*lvl)
  endfunction
 
  private constant function BuffDuration takes integer lvl returns real
    //The duration of the stun buff
    return 1.
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get the knockback
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================

  //Conditions
  private function Crush_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(GetAttacker(),SpellId) > 0
  endfunction

  //Actions
  //! runtextmacro BuffEffect("BuffAddId","0.5","")
 
  private struct CrushDatas
    real tt
    unit attacked
    real angle
   
    method motion takes nothing returns nothing
      local real x        =GetUnitX(.attacked)+MotionSpeed*Cos(.angle)
      local real y        =GetUnitY(.attacked)+MotionSpeed*Sin(.angle)

      if RectContainsCoords(MaxArea,x,y) and IsPointWalkable(x,y) then
        call SetUnitX(.attacked,x)
        call SetUnitY(.attacked,y)
      endif
     
      call DestroyEffect(AddSpecialEffectTarget(PushMdl,.attacked,PushAtt))
      set .tt=periodic+.tt

      if .tt>MaxPushTime then
        set .active=false
      endif
    endmethod
   
    method endmotion takes nothing returns nothing
       set .attacked=null    

       call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("CrushDatas","motion","endmotion","periodic")
  endstruct

  private function CrushBegin takes nothing returns boolean
    local CrushDatas dat=CrushDatas.create()
    local integer lvl   =GetUnitAbilityLevel(DamageSkill_attacked,SpellId)

    call UnitAddBuff(DamageSkill_attacked,BuffDuration(lvl),lvl)

    set dat.tt      =0.
    set dat.attacked=DamageSkill_attacked
    set dat.angle   =Atan2(GetUnitY(DamageSkill_attacked)-GetUnitY(DamageSkill_attacker),GetUnitX(DamageSkill_attacked)-GetUnitX(DamageSkill_attacker))
    call CrushDatas.addMotion(dat)
   
    return true
  endfunction

  private function Crush_Actions takes nothing returns nothing
    local real rndm    =GetRandomReal(0,100)
    local unit a       =GetAttacker()
    local unit u       =GetTriggerUnit()
    if Chance(GetUnitAbilityLevel(a,SpellId))>=rndm and UnitFilter(a,u) then
       call TriggerAddDamageEvent(u,a,function CrushBegin)
    endif
    set a=null
    set u=null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0
    local unit upre
   
    set gg_trg_Crush = CreateTrigger(  )
    set MaxArea = bj_mapInitialPlayableArea    
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Crush, Player(i),EVENT_PLAYER_UNIT_ATTACKED, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Crush,Condition(function Crush_Conditions))
    call TriggerAddAction( gg_trg_Crush, function Crush_Actions )
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,BuffAddId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(PushMdl)
  endfunction
endscope
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Electrical Field made by OrkOfMordor aka Hanky aka MDZ-OrkOfMordor

scope ElectricFlield initializer init
   //===================================================================================================================
   //Constants
  globals
     private constant integer SpellId           ='A004'  //Ability Rawcode: Electric Field
     private constant integer BuffSpellId       ='A002'  //Ability Rawcode: Electric Field - Explosion
     private constant integer MaxMissiles       =6       //The amount of the missiles
     private constant real MaxTime              =2.00    //The maximal time of the throw
     private constant real MaxRange             =250.00  //The maximal area where the missiles can be thrown
     private constant integer DummyId           ='e000'  //Unit Rawcode: Dummy
     private constant string MissileMdl         ="Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"  //The missile model
     private constant string ExplosionMdlA      ="Abilities\\Weapons\\Bolt\\BoltImpact.mdl"
     private constant string ExplosionMdlB      ="Abilities\\Spells\\Other\\Silence\\SilenceAreaBirth.mdl"
     private constant string MissileAttachPoint ="origin"//The attach point of MissileMdl
     private constant real MissileDamageRange   =120.00  //The range of the damage
  endglobals  

  private function EF_MissileFlyHeight takes nothing returns real
   //Random fly height of the missiles
   return GetRandomReal(500,700)
  endfunction

  private constant function EF_Damage takes integer lvl returns real
    //Damage of the explosion
    return (15.*lvl)+30.
  endfunction
 
  private constant function EF_BuffDuration takes integer lvl returns real
    //The duration of the slow buff
    return 3.
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if IsUnitType(u,UNIT_TYPE_FLYING)==false then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================

  //Conditions
  private function Electric_Field_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SpellId
  endfunction
 
  //Actions
  //! runtextmacro BuffEffect("BuffSpellId","0.5","")
 
  private struct ElectroBombs
    unit caster
    unit missile
    effect gfx
   
    integer lvl
    real dur
    real dmg
   
    method onDestroy takes nothing returns nothing
        call DestroyEffect(.gfx)
        set .missile=null
        set .caster =null
        set .gfx    =null
    endmethod
  endstruct

  private function ElectroFlieldExpl takes nothing returns nothing
    local timer t            =GetExpiredTimer()
    local ElectroBombs dat   =GetTimerDataInt(t)
    local real x             =GetUnitX(dat.missile)
    local real y             =GetUnitY(dat.missile)
    local unit a
    local group g

    set g=GetUnitsInRange(MissileDamageRange,GetUnitX(dat.missile),GetUnitY(dat.missile))
    loop
      set a=FirstOfGroup(g)
      exitwhen a==null
      call GroupRemoveUnit(g,a)
     
      if UnitFilter(dat.caster,a) then
        call UnitAddBuff(a,dat.dur,dat.lvl)
        call UnitDamageTarget(dat.caster,a,dat.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
      endif
    endloop
   
    call DestroyEffect(AddSpecialEffect(ExplosionMdlA,x,y))
    call DestroyEffect(AddSpecialEffect(ExplosionMdlB,x,y))
    call U2Null(dat.missile,0.5)
   
    call dat.destroy()
    call RecycleTimer(t)
    set g=null
    set t=null
  endfunction

  private function Electric_Field_Actions takes nothing returns nothing
    local timer t
    local real randomA       =0
    local real randomB       =0
    local real randomY       =0
    local real randomX       =0
    local integer int        =1
    local ElectroBombs dat
    local unit u             =GetTriggerUnit()

    local integer lvl        =GetUnitAbilityLevel(u,SpellId)
    local real x             =GetUnitX(u)
    local real y             =GetUnitY(u)
    local real Rx            =GetSpellTargetX()
    local real Ry            =GetSpellTargetY()
    local real dmg           =EF_Damage(lvl)
    local real dur           =EF_BuffDuration(lvl)
    local player p           =GetOwningPlayer(u)


    loop
       exitwhen int>MaxMissiles
            set randomA   =GetRandomReal(0,360)
            set randomB   =GetRandomReal(0,MaxRange)

            set randomX   =Rx+randomB*Cos(randomA*deg2rad)
            set randomY   =Ry+randomB*Sin(randomA*deg2rad)

            set dat        =ElectroBombs.create()
            set dat.caster =u
            set dat.missile=CreateUnit(p,DummyId,x,y,0)
            set dat.lvl    =lvl
            set dat.dur    =dur
            set dat.gfx    =AddSpecialEffectTarget(MissileMdl,dat.missile,MissileAttachPoint)
            set dat.dmg    =dmg
            set t          =GetNextTimerInt(dat)
           
            call LaunchMissileAtPointEx(dat.missile,x,y,45,EF_MissileFlyHeight(),randomX,randomY,0.,D2PXY(x,y,randomX,randomY)/MaxTime*MotionDatabase_periodic)
            call TimerStart(t,MaxTime,false,function ElectroFlieldExpl)
           
       set int=int+1
    endloop

    set u       =null
    set p       =null
    set t       =null
  endfunction

//===========================================================================
  private function init takes nothing returns nothing
    local integer i=0
    local unit upre

    set gg_trg_Electric_Field = CreateTrigger(  )
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Electric_Field, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Electric_Field, Condition( function Electric_Field_Conditions ) )
    call TriggerAddAction( gg_trg_Electric_Field, function Electric_Field_Actions )

    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,BuffSpellId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(MissileMdl)
  endfunction
endscope
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Fire Bombs by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope FireBombs initializer init
   //===================================================================================================================
   //Constants
  globals
     private constant integer SpellId          ='A007'  //Ability Rawcode: Fire Bombs
     private constant integer MaxMissiles      =7       //The amount of the missiles
     private constant integer DummyId          ='e000'  //Unit Rawcode: Dummy
     private constant integer SpellBuffId      ='A017'  //Ability Rawcode: Fire Bombs - Effect
     private constant real MaxRange            =250.00  //The maximal area where the missiles can be thrown
     private constant real MissileDamageRange  =120.00  //The range of the damage
     private constant real MaxTime             =2.00    //The maximal time of the throw
     private constant string ExplMdl           ="Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"  //The explosion model
     private constant string MissileMdl        ="Abilities\\Weapons\\BatTrollMissile\\BatTrollMissile.mdl" //The missile model
     private constant string MissileAttachPoint="origin"//The attach point of MissileMdl
     private constant real periodic            =0.25    //The periodic motion time
     
     private integer array BuffData[maxIndex]           //Important attached datas
  endglobals

  private function FB_MissileFlyHeight takes nothing returns real
    //Random fly height of the missiles
    return GetRandomReal(500,700)
  endfunction

  private constant function FB_Damage takes integer lvl returns real
    //Damage of the explosion
    return 50.*lvl
  endfunction
 
  private constant function FB_Buff_Duration takes integer lvl returns real
    //The duration of the burn buff
    return 3.*lvl
  endfunction
 
  private constant function FB_Buff_Damage takes integer lvl returns real
    //Damage per time for all burning units
    return 5.*lvl
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_FLYING)==false then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================

  //Conditions
  private function Fire_Bombs_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SpellId
  endfunction

  //Actions
  private struct FireBombsBuff
    unit caster
    unit victim  
   
    real dmg
    real time
    real duration
   
    method check takes nothing returns nothing
      set .time=.time+periodic
      call UnitDamageTarget(.caster,.victim,.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
     
      if not IsUnitNotBuffImmune(.victim) or .time>.duration then
        call UnitRemoveAbility(.victim,SpellBuffId)
        set .active=false
      endif
    endmethod
   
    method endcheck takes nothing returns nothing
      call ClearHandleIndex(.victim)
      set .caster=null
      set .victim=null
   
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("FireBombsBuff","check","endcheck","periodic")
  endstruct

  private struct FireBombs
    unit caster
    unit missile
    effect gfx
   
    real dmg    
    integer lvl
   
    method onDestroy takes nothing returns nothing
      call DestroyEffect(.gfx)
      call RemoveUnit(.missile)
   
      set .caster =null
      set .missile=null
      set .gfx    =null
    endmethod
  endstruct

  private function FireBombsExpl takes nothing returns nothing
    local timer t            =GetExpiredTimer()
    local FireBombs dat      =GetTimerDataInt(t)
    local FireBombsBuff datB
    local integer id
    local unit a
    local group g

    call DestroyEffect(AddSpecialEffect(ExplMdl,GetUnitX(dat.missile),GetUnitY(dat.missile)))
    call DestroyEffect(dat.gfx)
   
    set g=GetUnitsInRange(MissileDamageRange,GetUnitX(dat.missile),GetUnitY(dat.missile))
    loop
      set a=FirstOfGroup(g)
      exitwhen a==null
      call GroupRemoveUnit(g,a)
     
      if UnitFilter(dat.caster,a) then
         if GetUnitAbilityLevel(a,SpellBuffId)>0 then
           call UnitRemoveAbility(a,SpellBuffId)
           set id  =GetHandleIndex(a)
           set datB=BuffData[id]
         else
           call AddHandleIndex(a)
           set id  =GetHandleIndex(a)
           set datB=FireBombsBuff.create()
           call FireBombsBuff.addMotion(datB)
         endif
     
         call UnitDamageTarget(dat.caster,a,dat.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
         
         call UnitAddAbility(a,SpellBuffId)
         call SetUnitAbilityLevel(a,SpellBuffId,dat.lvl)
         
         set datB.caster              =dat.caster
         set datB.victim              =a
         set datB.dmg                 =FB_Buff_Damage(dat.lvl)*periodic
         set datB.time                =0.
         set datB.duration            =FB_Buff_Duration(dat.lvl)
         set BuffData[id]             =datB
      endif
    endloop
   
    call dat.destroy()
    call RecycleTimer(t)
    set g=null
    set t=null
  endfunction

  private function Fire_Bombs_Actions takes nothing returns nothing
    local timer t
    local real randomA       =0
    local real randomB       =0
    local real randomY       =0
    local real randomX       =0
    local integer int        =1
    local FireBombs dat
    local unit u             =GetTriggerUnit()

    local real x             =GetUnitX(u)
    local real y             =GetUnitY(u)
    local real Rx            =GetSpellTargetX()
    local real Ry            =GetSpellTargetY()
    local integer lvl        =GetUnitAbilityLevel(u,SpellId)
    local player p           =Player(14)


    loop
       exitwhen int>MaxMissiles        
            set randomA    =GetRandomReal(0,360)
            set randomB    =GetRandomReal(0,MaxRange)

            set randomX    =Rx+randomB*Cos(randomA*deg2rad)
            set randomY    =Ry+randomB*Sin(randomA*deg2rad)

            set dat        =FireBombs.create()
            set dat.caster =u
            set dat.missile=CreateUnit(p,DummyId,x,y,0)
            set dat.gfx    =AddSpecialEffectTarget(MissileMdl,dat.missile,MissileAttachPoint)
            set dat.lvl    =lvl
            set dat.dmg    =FB_Damage(lvl)
            set t          =GetNextTimerInt(dat)
           
            call LaunchMissileAtPointEx(dat.missile,x,y,45,FB_MissileFlyHeight(),randomX,randomY,0.,D2PXY(x,y,randomX,randomY)/MaxTime*MotionDatabase_periodic)
            call TimerStart(t,MaxTime,false,function FireBombsExpl)
       
       set int=int+1
    endloop

    set u      =null
    set p      =null
    set t      =null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0  
    local unit upre
 
    set gg_trg_Fire_Bombs = CreateTrigger(  )
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Fire_Bombs, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, Filter(function DebugFilter))

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Fire_Bombs, Condition( function Fire_Bombs_Conditions ) )
    call TriggerAddAction( gg_trg_Fire_Bombs, function Fire_Bombs_Actions )
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,SpellBuffId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(ExplMdl)
    call Preload(MissileMdl)
  endfunction
endscope
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Dark Torture by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope DarkTorture initializer init
   //===================================================================================================================
   //Constants
  globals
     private constant integer SpellId     ='A00D'  //Ability Rawcode: Dark Torture
     private constant integer BuffSpellId ='A018'  //Ability Rawcode: Dark Torture - Effect
     private constant integer MaxLights   =12      //The lightning amount around the unit
     private constant real highper        =15.00   //The height per lightning
     private constant string LightningType="AFOD"  //Lightning Rawcode
     private constant integer DummyId     ='e000'  //Unit Rawcode: Dummy
     private constant real gfxangle       =0.      //The endeffect angle
     private constant string ABgfx        ="Abilities\\Weapons\\VengeanceMissile\\VengeanceMissile.mdl"  //Model for the small red lightballs
     private constant string ABattach     ="origin"//The attach point of ABgfx
     private constant real ABscale        =2.      //The scale of the model ABgfx
     private constant string damageGFX    ="Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"  //The damage model
     private constant string damageATTACH ="origin"//The attach point of damageGFX
     private constant string deathGFX     ="Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl"  //The model when the target die
     private constant string deathATTACH  ="origin"//The attach point of deathGFX
     private constant string targetGFX    ="Abilities\\Spells\\Orc\\Voodoo\\VoodooAura.mdl"  //The model at target during the spell
     private constant string targetATTACH ="origin"//The attach point of targetGFX
     private constant real motionSpeed    =3.00    //The angle motion speed
     private constant real lightningZ     =45.00   //The lightning start height
     private constant real maxDistance    =1000.00 //The maximal range of the spell
     private constant real periodic       =0.03    //The periodic motion time
     
     // This you shouldn't change
     private integer array BuffData[maxIndex]       //Important attached datas
     private trigger endcast              =null    //This trigger is for the channal effect (better you don't change this)
  endglobals

  private constant function DamagePerLevel takes integer lvl returns real
     //Damage the target every second
     return 20.+10.*lvl
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================
 
  //Conditions
  private function Dark_Torture_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==SpellId
  endfunction
 
  //Actions
  private struct LightningDatas
    lightning lgt
    real angle1
    real angle2
    real high
    real x1
    real y1
    real z1
    real x2
    real y2
    real z2
   
    method onDestroy takes nothing returns nothing
      call DestroyLightning(.lgt)    
      set .lgt=null
    endmethod
  endstruct

  private struct DarkTortureDatas
    LightningDatas array lgtdat[MaxLights]
    unit caster
    unit target
    unit gfxdummyA
    unit gfxdummyB
    real counter
    real dmg
    effect gfxA
    effect gfxB
    lightning lgt
    effect gfxTarget
   
    method motion takes nothing returns nothing
      local integer index          =0
      local real x                 =GetUnitX(.target)
      local real y                 =GetUnitY(.target)
      local real ux                =GetUnitX(.caster)
      local real uy                =GetUnitY(.caster)
      local real scale             =(100-GetUnitState(.target,UNIT_STATE_LIFE)*100/GetUnitState(.target,UNIT_STATE_MAX_LIFE))+100

      loop
        exitwhen index>=MaxLights
         set .lgtdat[index].angle1=.lgtdat[index].angle1+motionSpeed
         set .lgtdat[index].angle2=.lgtdat[index].angle2+motionSpeed
         set .lgtdat[index].x1=x+(scale/2)*Cos(.lgtdat[index].angle1*deg2rad)
         set .lgtdat[index].y1=y+(scale/2)*Sin(.lgtdat[index].angle1*deg2rad)
         set .lgtdat[index].x2=x+(scale/2)*Cos(.lgtdat[index].angle2*deg2rad)
         set .lgtdat[index].y2=y+(scale/2)*Sin(.lgtdat[index].angle2*deg2rad)
         call MoveLightningEx(.lgtdat[index].lgt,true,.lgtdat[index].x1,.lgtdat[index].y1,.lgtdat[index].z1+GetZ(.lgtdat[index].x1,.lgtdat[index].y1),.lgtdat[index].x2,.lgtdat[index].y2,.lgtdat[index].z2+GetZ(.lgtdat[index].x2,.lgtdat[index].y2))
        set index=index+1
      endloop

      set scale=scale*0.01
      set .counter=.counter+periodic
      call MoveLightningEx(.lgt,true,ux,uy,GetUnitFlyHeight(.caster)+lightningZ+GetZ(x,y),x,y,GetUnitFlyHeight(.target)+lightningZ+GetZ(x,y))
      call SetUnitScale(.target,scale,scale,scale)
      if .counter>=1 then
         call DestroyEffect(AddSpecialEffectTarget(damageGFX,.target,damageATTACH))
         call UnitDamageTarget(.caster,.target,.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
         set .counter=0
      endif

      call SetUnitPosition(.gfxdummyA,.lgtdat[0].x1,.lgtdat[0].y1)
      call SetUnitPosition(.gfxdummyB,.lgtdat[MaxLights-1].x2,.lgtdat[MaxLights-1].y2)

      set .active=GetUnitState(.target,UNIT_STATE_LIFE)>0. and D2PXY(x,y,ux,uy)<=maxDistance and UnitFilter(.caster,.target)
    endmethod
   
    method endmotion takes nothing returns nothing
      local integer index=0
      local unit a    

      call ClearHandleIndex(.caster)
      if GetUnitState(.target,UNIT_STATE_LIFE)<=0. then
       set a=CreateUnit(Player(14),DummyId,GetUnitX(.target),GetUnitY(.target),gfxangle)
       call DestroyEffect(AddSpecialEffectTarget(deathGFX,a,deathATTACH))
       call UnitAddFly(a)
       call SetUnitFlyHeight(a,GetUnitFlyHeight(.target),0)
       call U2Null(a,0.75)
       set a=null
           
      else
       call UnitRemoveAbility(.target,BuffSpellId)
      endif
   
      call SetUnitScale(.target,1,1,1)
      loop
        exitwhen index>=MaxLights
        call .lgtdat[index].destroy()
        set index=index+1
      endloop
     
      set .caster=null
      set .target=null
      call DestroyEffect(.gfxA)
      call DestroyEffect(.gfxB)
      call DestroyEffect(.gfxTarget)
      call DestroyLightning(.lgt)
      call U2Null(.gfxdummyA,0.5)
      call U2Null(.gfxdummyB,0.5)
      set .gfxdummyA=null
      set .gfxdummyB=null
      set .gfxA=null
      set .gfxB=null
      set .gfxTarget=null
      set .lgt=null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("DarkTortureDatas","motion","endmotion","periodic")
  endstruct

  private function Dark_Torture_Actions takes nothing returns nothing
    local unit u                 =GetTriggerUnit()
    local unit target            =GetSpellTargetUnit()
    local DarkTortureDatas dat   =DarkTortureDatas.create()
    local real x                 =GetUnitX(target)
    local real y                 =GetUnitY(target)
    local real z                 =GetUnitFlyHeight(target)
    local integer index          =0
    local integer lvl            =GetUnitAbilityLevel(u,SpellId)
    local real sa                =360/(MaxLights/2)
    local real scale             =((100-GetUnitState(target,UNIT_STATE_LIFE)*100/GetUnitState(target,UNIT_STATE_MAX_LIFE))+100)*0.01

    call UnitAddAbility(target,BuffSpellId)
    call SetUnitAbilityLevel(target,BuffSpellId,lvl)

    loop
      exitwhen index>=MaxLights
       set dat.lgtdat[index]=LightningDatas.create()
       set dat.lgtdat[index].angle1=sa*index
       set dat.lgtdat[index].angle2=sa*(index+1)
       set dat.lgtdat[index].x1=x+(scale/2)*Cos(dat.lgtdat[index].angle1*deg2rad)
       set dat.lgtdat[index].y1=y+(scale/2)*Sin(dat.lgtdat[index].angle1*deg2rad)
       set dat.lgtdat[index].x2=x+(scale/2)*Cos(dat.lgtdat[index].angle2*deg2rad)
       set dat.lgtdat[index].y2=y+(scale/2)*Sin(dat.lgtdat[index].angle2*deg2rad)
       set dat.lgtdat[index].z1=highper*index+z
       set dat.lgtdat[index].z2=highper*(index+1)+z
       set dat.lgtdat[index].lgt=AddLightningEx(LightningType,true,dat.lgtdat[index].x1,dat.lgtdat[index].y1,dat.lgtdat[index].z1+GetZ(dat.lgtdat[index].x1,dat.lgtdat[index].y1),dat.lgtdat[index].x2,dat.lgtdat[index].y2,dat.lgtdat[index].z2+GetZ(dat.lgtdat[index].x2,dat.lgtdat[index].y2))
      set index=index+1
    endloop

    call SetUnitScale(target,scale,scale,scale)

    set dat.gfxdummyA=CreateUnit(Player(14),DummyId,dat.lgtdat[0].x1,dat.lgtdat[0].y1,gfxangle)
    call UnitAddFly(dat.gfxdummyA)
    call SetUnitFlyHeight(dat.gfxdummyA,dat.lgtdat[0].z1,0)
    call SetUnitScale(dat.gfxdummyA,ABscale,ABscale,ABscale)
    set dat.gfxA=AddSpecialEffectTarget(ABgfx,dat.gfxdummyA,ABattach)

    set dat.gfxdummyB=CreateUnit(Player(14),DummyId,dat.lgtdat[MaxLights-1].x2,dat.lgtdat[MaxLights-1].y2,gfxangle)
    call UnitAddFly(dat.gfxdummyB)
    call SetUnitFlyHeight(dat.gfxdummyB,dat.lgtdat[MaxLights-1].z2,0)
    call SetUnitScale(dat.gfxdummyB,ABscale,ABscale,ABscale)
    set dat.gfxB=AddSpecialEffectTarget(ABgfx,dat.gfxdummyB,ABattach)

    set dat.lgt=AddLightningEx(LightningType,true,GetUnitX(u),GetUnitY(u),GetUnitFlyHeight(u)+lightningZ,x,y,z+lightningZ)
    set dat.gfxTarget=AddSpecialEffectTarget(targetGFX,target,targetATTACH)

    set dat.dmg=DamagePerLevel(lvl)
    set dat.caster=u
    set dat.target=target
    set dat.counter=0

    call AddHandleIndex(u)
    set BuffData[GetHandleIndex(u)]=dat
    call DarkTortureDatas.addMotion(dat)
   
    set target=null
    set u     =null
  endfunction

  private function Dark_Torture_Endcast takes nothing returns nothing
    local DarkTortureDatas dat   =BuffData[GetHandleIndex(GetTriggerUnit())]

    call SetUnitScale(dat.target,1,1,1)
    call UnitRemoveAbility(dat.target,BuffSpellId)
   
    set dat.active=false
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local boolexpr b=Condition( function Dark_Torture_Conditions )
    local integer i =0
    local unit upre
    local player p
 
    set gg_trg_Dark_Torture=CreateTrigger()
    call TriggerAddCondition( gg_trg_Dark_Torture, b )
    call TriggerAddAction( gg_trg_Dark_Torture, function Dark_Torture_Actions )

    set endcast=CreateTrigger()
    call TriggerAddCondition( endcast, b )
    call TriggerAddAction( endcast, function Dark_Torture_Endcast )
   
    loop
      set p=Player(i)
      call TriggerRegisterPlayerUnitEvent(gg_trg_Dark_Torture, p,EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)
      call TriggerRegisterPlayerUnitEvent(endcast, p,EVENT_PLAYER_UNIT_SPELL_ENDCAST, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,BuffSpellId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(ABgfx)
    call Preload(damageGFX)
    call Preload(deathGFX)
    call Preload(targetGFX)
   
    set p=null
    set b=null
  endfunction
endscope
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Frost Sphere by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope FrostSphere initializer init
   //===================================================================================================================
   //Constants
  globals
     private constant integer SpellId           ='A005'  //Ability Rawcode: Frost Sphere
     private constant integer BuffSpellId       ='A016'  //Ability Rawcode: Frost Sphere - Effect
     private constant real PerSecondCreate      =0.25    //The creation time of small frost missiles
     private constant integer DummyId           ='e000'  //Unit Rawcode: Dummy
     private constant real SphereSpeed          =10.00   //The speed of the sphere
     private constant real MissileSpeed         =15.00   //The speed of the small missiles
     private constant real TurnSpeed            =45.00   //The angle speed for the missile creation
     private constant real MissileDistance      =1000.00 //The maximal small missile distance
     private constant real MaxSphereDistance    =2000.00 //The maximal sphere distance
     private constant string MissileMdl         ="Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl"  //The model of the sphere
     private constant string MissileAttachPoint ="chest" //The attach point of the MissileMdl
     private constant string SMissileMdl        ="Abilities\\Weapons\\LichMissile\\LichMissile.mdl"  //The model of the small missiles
     private constant string ExplMissileMdl     ="Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"  //The model when the small missiles explode
     private constant string ExplSphereMdl      ="Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl"  //The model when the sphere explode
     private constant string SMissileAttachPoint="chest" //The attach point of the SMissleMdl
     private constant real periodic             =0.03    //The periodic motion time
     
     private rect MaxArea                       =null    //The maximal movearea of the missiles
     private constant string MissileExplFunc    ="FS_MissileHit"  //The missile explode function (better you don't change this)
     private effect array missilegfx                     //The array where the missile model get saved in
  endglobals

  private constant function FS_MissileDamage takes integer lvl returns real
     //The damage the units get when they collide with the missiles
     return 90.*lvl+5.
  endfunction
 
  private constant function FS_BuffDuration takes integer lvl returns real
     //The duration of the freeze buff
     return 1.
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================

  //Conditions
  private function Frost_Sphere_Conditions takes nothing returns boolean
      return GetSpellAbilityId()==SpellId
  endfunction

  //Actions
  //! runtextmacro BuffEffect("BuffSpellId","0.5","")
 
  function FS_MissileHit takes nothing returns nothing
     local unit caster  =MotionDatabase_tc
     local unit missile =MotionDatabase_tm
     local unit a

     local integer lvl  =GetUnitAbilityLevel(caster,SpellId)
     local real x       =GetUnitX(missile)
     local real y       =GetUnitY(missile)
     local real dmg     =FS_MissileDamage(lvl)
     local real dur     =FS_BuffDuration(lvl)

     local group g      =GetUnitsInRange(120,x,y)
     local effect gfx   =missilegfx[MotionDatabase_tdata]

     
     call GroupRemoveUnit(g,missile)
     loop
       set a=FirstOfGroup(g)
       exitwhen a==null
       call GroupRemoveUnit(g,a)
       
       if UnitFilter(caster,a) and missile!=a then
          call UnitAddBuff(a,dur,lvl)
          call UnitDamageTarget(caster,a,dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
        endif
     endloop
     
     
     call E2Null(AddSpecialEffect(ExplMissileMdl,x,y),1)
     call ClearHandleIndex(missile)
     call DestroyEffect(gfx)
     
     call RemoveUnit(missile)
     set missile=null
     set caster =null
     set gfx    =null
     set g      =null
  endfunction

  private struct FrostSphereDatas
    unit sphere
    unit caster
    effect gfx
   
    real circ
    real tdis
    real ttim
   
    real x
    real y
    real mx
    real my
   
    method motion takes nothing returns nothing
      local unit missile  =null
      local real mx       =0.
      local real my       =0.
      local integer id

      set .x=.x+.mx
      set .y=.y+.my
      set .tdis=SphereSpeed+.tdis
     
      call SetUnitX(.sphere,.x)
      call SetUnitY(.sphere,.y)

      if .ttim>PerSecondCreate and .tdis<=MaxSphereDistance then
           set .ttim=0.
           call DestroyEffect(.gfx)
           set .gfx=AddSpecialEffectTarget(MissileMdl,.sphere,MissileAttachPoint)
           set .circ=.circ+TurnSpeed

           set mx     =.x+MissileDistance*Cos(.circ*deg2rad)
           set my     =.y+MissileDistance*Sin(.circ*deg2rad)
 
           set missile=CreateUnit(GetOwningPlayer(.caster),DummyId,.x,.y,.circ)
           call AddHandleIndex(missile)
           set id            =GetHandleIndex(missile)
           set missilegfx[id]=AddSpecialEffectTarget(SMissileMdl,missile,SMissileAttachPoint)

           call LaunchNormalCollisionMissileAtPointEx(.caster,missile,.x,.y,0,mx,my,MissileSpeed,90,MissileExplFunc,id)
       elseif .ttim<=PerSecondCreate then
           set .ttim=.ttim+periodic
       endif

      if .tdis>MaxSphereDistance or not RectContainsCoords(MaxArea,.x,.y) then
        set .active=false
      endif
    endmethod
   
    method endmotion takes nothing returns nothing    
        call DestroyEffect(AddSpecialEffect(ExplSphereMdl,.x,.y))
        call DestroyEffect(AddSpecialEffect(MissileMdl,.x,.y))
        call DestroyEffect(.gfx)
        call RemoveUnit(.sphere)
       
        set .sphere=null
        set .caster=null
        set .gfx   =null
        call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("FrostSphereDatas","motion","endmotion","periodic")
  endstruct


  private function Frost_Sphere_Actions takes nothing returns nothing
    local FrostSphereDatas dat=FrostSphereDatas.create()
    local unit u              =GetTriggerUnit()
    local real x              =GetUnitX(u)
    local real y              =GetUnitY(u)
    local real lx             =GetSpellTargetX()
    local real ly             =GetSpellTargetY()
    local real angle          =Atan2(ly-y,lx-x)
   
    set dat.sphere=CreateUnit(Player(14),DummyId,x,y,angle*rad2deg)
    call SetUnitX(dat.sphere,x)
    call SetUnitY(dat.sphere,y)  
 
    set dat.gfx   =AddSpecialEffectTarget(MissileMdl,dat.sphere,MissileAttachPoint)
    set dat.caster=u
    set dat.circ  =0.
    set dat.tdis  =0.
    set dat.ttim  =0.
   
    set dat.x=x
    set dat.y=y
    set dat.mx=SphereSpeed*Cos(angle)
    set dat.my=SphereSpeed*Sin(angle)

    call FrostSphereDatas.addMotion(dat)
    set u  =null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0
    local unit upre
   
    set gg_trg_Frost_Sphere = CreateTrigger(  )
    set MaxArea             = bj_mapInitialPlayableArea    
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Frost_Sphere, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Frost_Sphere, Condition( function Frost_Sphere_Conditions ) )
    call TriggerAddAction( gg_trg_Frost_Sphere, function Frost_Sphere_Actions )
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,BuffSpellId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(MissileMdl)
    call Preload(SMissileMdl)
    call Preload(ExplMissileMdl)
    call Preload(ExplSphereMdl)
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Bloody Run by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope BloodyRun initializer init
   //===================================================================================================================
   //Constants
   globals
     private constant integer SpellId    ='A00C'  //Ability Rawcode: Bloody Run
     private constant integer BuffSpellId='A00E'  //Ability Rawcode: Blood Run - Effect (Caster)
     private constant integer BuffId     ='B00A'  //Buff Rawcode: Blood Run
     private constant string BuffOrder   ="soulburn"//The dummy order string so that all abilities are disabled for the caster
     private constant string RunOrder    ="move"  //The order string fot the caster at the start
     private constant string StopOrder   ="stop"  //The order string for the caster when it reach the target
     private constant integer DummyId    ='e000'  //Unit Rawcode: Dummy
     private constant real Speed         =20.00   //Speed of the caster
     private constant real Range         =90.00   //The collision range of the caster
     private constant string dmgGFX      ="Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"  //The model when the caster collide with a unit
     private constant string dmgAtt      ="origin"  //The attach point of dmgGFX
     private constant string uGFX        ="Abilities\\Spells\\Items\\VampiricPotion\\VampPotionCaster.mdl"  //The model for the caster that it look more bloody
     private constant string uAtt        ="origin"  //The attach point of uGFX
     private constant real periodic      =0.03      //The periodic motion time
     
     private rect MaxArea                =null    //The maximal movearea of the missiles
   endglobals

   private constant function Damage takes integer lvl returns real
     //The damage every victim get
     return 25.+50.*lvl
   endfunction
   
   private function UnitFilter takes unit c,unit u returns boolean
     //The unit filter for the units who get damage
     if IsUnitEnemy(u,GetOwningPlayer(c)) then
     if GetUnitState(u,UNIT_STATE_LIFE)>0. then
     if IsUnitType(u,UNIT_TYPE_FLYING)==false then
     if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
     if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
     return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
     endif
     endif
     endif
     endif
     endif
   
     return false
   endfunction
  //End Constants
  //===================================================================================================================
   
   //Conditions
   private function Bloody_Run_Conditions takes nothing returns boolean
      return GetSpellAbilityId()==SpellId
   endfunction
   
   //Actions
   private struct BloodyRunDatas
      unit caster
      effect gfx
      group notDamage
     
      real distance
      real dmg
     
      method motion takes nothing returns nothing
        local real angle          =GetUnitFacing(.caster)*deg2rad
        local real x              =GetUnitX(.caster)+Speed*Cos(angle)
        local real y              =GetUnitY(.caster)+Speed*Sin(angle)
        local group g
        local unit a
       
        if CountDestructableInRangeOfXY(x,y,Range)>0 and not IsPointWalkable(x,y) then
          set .active=false
          return
        endif        
        if .distance>0. and GetUnitState(.caster,UNIT_STATE_LIFE)>0. and RectContainsCoords(MaxArea,x,y) then
          call SetUnitX(.caster,x)
          call SetUnitY(.caster,y)

          set g=GetUnitsInRange(Range,x,y)
          call GroupRemoveUnit(g,.caster)
          loop
            set a=FirstOfGroup(g)
            exitwhen a==null
            call GroupRemoveUnit(g,a)
           
            if not IsUnitInGroup(a,.notDamage) and IsUnitNotImmun(.caster,a) then
              call DestroyEffect(AddSpecialEffectTarget(dmgGFX,a,dmgAtt))
              call GroupAddUnit(.notDamage,a)
              call UnitDamageTarget(.caster,a,.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            endif
          endloop
         
          set .distance=.distance-Speed
          set g=null
        else
          set .active=false
        endif
      endmethod
     
      method endmotion takes nothing returns nothing  
          local real x=GetUnitX(.caster)
          local real y=GetUnitY(.caster)
     
          call SetUnitPathing(.caster,true)
          call IssueImmediateOrder(.caster,StopOrder)
          call SetUnitPosition(.caster,GetPointWalkableX(x,y),GetPointWalkableY(x,y))
          call SetUnitVertexColor(.caster,255,255,255,255)
          call DestroyBuffAfterTime(.caster,BuffId,2.)
          call DestroyEffect(.gfx)
          call GroupClear(.notDamage)
          call RecycleGroup(.notDamage)
         
          set .caster   =null
          set .gfx      =null
          set .notDamage=null
          call .destroy()
      endmethod
     
      //! runtextmacro CostumMotion("BloodyRunDatas","motion","endmotion","periodic")
   endstruct

   private function Bloody_Run_Actions takes nothing returns nothing
      local BloodyRunDatas dat  =BloodyRunDatas.create()
      local unit u              =GetTriggerUnit()
      local real ux             =GetUnitX(u)
      local real uy             =GetUnitY(u)
      local real tx             =GetSpellTargetX()
      local real ty             =GetSpellTargetY()
      local real distance       =D2PXY(ux,uy,tx,ty)
      local unit bx
     
      set dat.caster   =u
      set dat.distance =distance
      set dat.gfx      =AddSpecialEffectTarget(uGFX,u,uAtt)
      set dat.notDamage=GetNextGroup()
      set dat.dmg      =Damage(GetUnitAbilityLevel(u,SpellId))
     
      if (ux!=tx or uy!=ty) then
        set bx=CreateUnit(Player(14),DummyId,ux,uy,0)
        call UnitAddAbility(bx,BuffSpellId)
        call IssueTargetOrder(bx,BuffOrder,u)
        call U2Null(bx,0.5)
        set bx=null
      endif
     
      call SetUnitVertexColor(u,255,50,50,75)
      call SetUnitPathing(u,false)
      call IssuePointOrder(u,RunOrder,tx,ty)

      call BloodyRunDatas.addMotion(dat)
     
      set u         =null
   endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0  
    local player p

    set gg_trg_Bloody_Run = CreateTrigger(  )
    set MaxArea=bj_mapInitialPlayableArea
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Bloody_Run, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Bloody_Run, Condition( function Bloody_Run_Conditions ) )
    call TriggerAddAction( gg_trg_Bloody_Run, function Bloody_Run_Actions )
   
    //Preload
    call Preload(dmgGFX)
    call Preload(uGFX)
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Mystic Net by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope MysticNet initializer init
   //===================================================================================================================
   //Constants
  globals
    private constant integer SpellId          ='A00G'  //Ability Rawcode: Mystic Net
    private constant string LightningType     ="LEAS"  //Lightning Rawcode
    private constant integer BuffSpellId      ='A015'  //Ability Rawcode: Mystic Net - Effect
    private constant real MissileFlyHeight    =60.00   //The flyheight of the missile
    private constant real MaxMissileDistance  =750.00  //The maximal missile distance
    private constant real MissileSpeed        =20.00   //The speed of the missile
    private constant real TargetSpeed         =15.00   //The speed of the victim
    private constant real MissileCollision    =90.00   //The collision range of the missile
    private constant real StopTargetRange     =120.00  //The distance to the caster before it reach the ground again
    private constant real lightningZ          =45.00   //The height of the lightning
    private constant real DeformationRange    =200.00  //The hit ground deformation animation range
    private constant integer DummyId          ='e000'  //Unit Rawcode: Dummy
    private constant string MissileGFXPath    ="Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"  //The model of the missile
    private constant string MissileGFXAttach  ="origin"  //The attach point of MissileGFXPath
    private constant string MissGFXPath       ="Abilities\\Spells\\Orc\\Disenchant\\DisenchantSpecialArt.mdl"  //The model when the missile hit nothing
    private constant string MissGFXAttach     ="origin"  //The attach point of MissGFXPath
    private constant string HitGFXPath        ="Abilities\\Spells\\Human\\AerialShackles\\AerialShacklesTarget.mdl"  //The "net" model when a unit is caught
    private constant string HitGFXAttach      ="origin"  //The attach point of HitGFXPath
    private constant string GroundHitGFXPath  ="Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"  //The model when the target reach the ground again
    private constant string GroundNetGFXPath  ="Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl"  //The second model when the target reach the ground again
    private constant string ReactHitGFXPath   ="Abilities\\Spells\\NightElf\\BattleRoar\\RoarCaster.mdl"  //The model when the caster hit a target
    private constant string ReactHitGFXAttach ="origin"  //The attach point of ReactHitGFXPath
    private constant string ReactMissGFXPath  ="Abilities\\Spells\\NightElf\\Taunt\\TauntCaster.mdl"  //The model when the caster miss a target
    private constant string ReactMissGFXAttach="origin"  //The attach point of ReactMissGFXPath
    private constant real periodic            =0.03      //The periodic motion time
   
    private rect MaxArea                      =null    //The maximal movearea of the missiles
  endglobals

  private constant function MaxFlyHeight takes real distance returns real
    //The maximal height of the target
    return distance*1.1
  endfunction
 
  private constant function BuffDuration takes integer lvl returns real
    //The duration of the stun buff
    return 3.
  endfunction

  private constant function DamagePerLevel takes integer lvl returns real
     //The damage the target get after the spell
     return 20.+60.*lvl
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get picked
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if IsUnitType(u,UNIT_TYPE_FLYING)==false then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================
 
  //Conditions
  function Mystic_Net_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==SpellId
  endfunction
 
  //Actions
  //! runtextmacro BuffEffect("BuffSpellId","0.5","")
 
  private struct MNdat_Hit
    unit target
    unit caster
    effect gfx
    lightning rope

    real dmg
    real distance
    real maxdistance
    real x
    real y
    real mx
    real my
    real array z[3]
 
    method motion takes nothing returns nothing
      local integer lvl
      local real z
      local real cx
      local real cy
      local real cz
      local real curv

      set .distance=.distance+TargetSpeed
      if .maxdistance>=.distance and GetUnitState(.caster,UNIT_STATE_LIFE)>0.00 then
         set cx=GetUnitX(.caster)
         set cy=GetUnitY(.caster)
         set cz=GetZ(cx,cy)
         set .x=.x+.mx
         set .y=.y+.my
         set z =GetZ(.x,.y)
         set curv=GetFlyParabula(.z[1],.z[0],.z[2],.distance/.maxdistance) + (.z[0]-z)

         call MoveLightningEx(.rope,true,cx,cy,cz+MissileFlyHeight,.x,.y,curv+lightningZ+z)
         call SetUnitPosition(.target,.x,.y)
         call SetUnitFlyHeight(.target,curv,0)
       else
         if IsUnitEnemy(.target,GetOwningPlayer(.caster)) then
           set lvl=GetUnitAbilityLevel(.caster,SpellId)
           call UnitAddBuff(.target,BuffDuration(lvl),lvl)
           call UnitDamageTarget(.caster,.target,.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
         endif
         
         call TerrainDeformationRippleXY(1,false,.x,.y,0,DeformationRange,90.,0.5,200.)
         call DestroyEffect(AddSpecialEffect(GroundHitGFXPath,.x,.y))
         call DestroyEffect(AddSpecialEffect(GroundNetGFXPath,.x,.y))
         call SetUnitPathing(.target,true)
         call SetUnitFlyHeight(.target,GetUnitDefaultFlyHeight(.target),300.)
       
         set .active=false
      endif
    endmethod
   
    method endmotion takes nothing returns nothing
      call DestroyEffect(.gfx)
      call DestroyLightning(.rope)
     
      set .target=null
      set .caster=null
      set .gfx   =null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("MNdat_Hit","motion","endmotion","periodic")
  endstruct
 
  private struct MNdat_Miss
    unit dummy
    effect gfx
    lightning rope

    real x
    real y
    real tx
    real ty
    real mx
    real my
    real mz
    real distance
 
    method motion takes nothing returns nothing    
      if .distance>0 then
        set .x=.x+.mx
        set .y=.y+.my
        set .distance=.distance-MissileSpeed
       
        call MoveLightningEx(.rope,true,.x,.y,.mz,.tx,.ty,.mz)
        call DestroyEffect(.gfx)
        set .gfx=AddSpecialEffectTarget(MissGFXPath,.dummy,MissGFXAttach)
      else
        set .active=false
      endif
    endmethod
   
    method endmotion takes nothing returns nothing
      call DestroyEffect(.gfx)
      call RemoveUnit(.dummy)
      call DestroyLightning(.rope)
   
      set .gfx     =null
      set .dummy   =null
      set .rope    =null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("MNdat_Miss","motion","endmotion","periodic")
  endstruct

  private struct MNdat_Throw
    real x
    real y
    real z
    real distance
    unit caster
    unit dummy
    effect gfx
    lightning rope
   
    method motion takes nothing returns nothing
      local MNdat_Miss Mdat
      local MNdat_Hit  Hdat
   
      local real x              =GetUnitX(.caster)
      local real y              =GetUnitY(.caster)
      local real tx
      local real ty
      local real z
      local real angle          =Atan2(.y-y,.x-x)
      local boolean hit         =false
      local unit t
      local unit a
      local group g


      set .x=.x+MissileSpeed*Cos(angle)
      set .y=.y+MissileSpeed*Sin(angle)
      set .distance=D2PXY(.x,.y,x,y)
      set z=GetZ(.x,.y)
     
      call MoveLightningEx(.rope,true,x,y,.z,.x,.y,.z)
      call UnitAddFly(.dummy)
      call SetUnitFlyHeight(.dummy,.z-z,0)
      call SetUnitX(.dummy,.x)
      call SetUnitY(.dummy,.y)
      call SetUnitFacing(.dummy,angle*rad2deg)

      set g=GetUnitsInRange(MissileCollision,.x,.y)
      call GroupRemoveUnit(g,.caster)
      call GroupRemoveUnit(g,.dummy)
      loop
        set a=FirstOfGroup(g)
        exitwhen a==null
        call GroupRemoveUnit(g,a)
       
        if UnitFilter(.caster,a) then
          set t=a
          set hit=true
        endif
      endloop

      if z>=.z or .distance>=MaxMissileDistance or not RectContainsCoords(MaxArea,.x,.y) or GetUnitState(.caster,UNIT_STATE_LIFE)<=0.00 or CountDestructableInRangeOfXY(.x,.y,MissileCollision)>0 then

         //Miss Init
         set Mdat      =MNdat_Miss.create()
 
         set Mdat.dummy  =.dummy
         set Mdat.gfx    =AddSpecialEffectTarget(MissGFXPath,.dummy,MissGFXAttach)
         set Mdat.rope   =.rope

         set Mdat.x       =x
         set Mdat.y       =y
         set Mdat.mx      =MissileSpeed*Cos(angle)
         set Mdat.my      =MissileSpeed*Sin(angle)
         set Mdat.tx      =.x
         set Mdat.ty      =.y
         set Mdat.mz      =.z
         set Mdat.distance=D2PXY(x,y,.x,.y)

         call DestroyEffect(AddSpecialEffectTarget(ReactMissGFXPath,.caster,ReactMissGFXAttach))
         call SetUnitFlyHeight(.dummy,.z-z,0)
         call SetUnitX(.dummy,.x)
         call SetUnitY(.dummy,.y)
         
         call MNdat_Miss.addMotion(Mdat)
         set .active=false
       elseif hit then
         //Hit Init        
         set Hdat            =MNdat_Hit.create()

         set Hdat.target     =t
         set Hdat.caster     =.caster
         set Hdat.distance   =0.
         set Hdat.rope       =.rope
         set Hdat.dmg        =DamagePerLevel(GetUnitAbilityLevel(.caster,SpellId))
         set Hdat.x          =GetUnitX(t)
         set Hdat.y          =GetUnitY(t)
         set tx              =x+StopTargetRange*Cos(angle)
         set ty              =y+StopTargetRange*Sin(angle)
         set angle           =Atan2(ty-Hdat.y,tx-Hdat.x)
         set Hdat.mx         =TargetSpeed*Cos(angle)
         set Hdat.my         =TargetSpeed*Sin(angle)
         set Hdat.maxdistance=D2PXY(Hdat.x,Hdat.y,tx,ty)
         set Hdat.z[0]       =GetUnitDefaultFlyHeight(t)+GetZ(Hdat.x,Hdat.y)
         set Hdat.z[1]       =MaxFlyHeight(Hdat.maxdistance)
         set Hdat.z[2]       =GetZ(tx,ty)
         set Hdat.gfx        =AddSpecialEffectTarget(HitGFXPath,t,HitGFXAttach)
         
         call UnitAddFly(t)
         call MNdat_Hit.addMotion(Hdat)
         call RemoveUnit(.dummy)
         call DestroyEffect(AddSpecialEffectTarget(ReactHitGFXPath,.caster,ReactHitGFXAttach))
         call SetUnitPathing(t,false)
         
         set .active=false
         set t=null
      endif
     
      set g=null
    endmethod
   
    method endmotion takes nothing returns nothing
      call DestroyEffect(.gfx)
   
      set .caster  =null
      set .dummy   =null
      set .gfx     =null
      set .rope    =null      
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("MNdat_Throw","motion","endmotion","periodic")
  endstruct

  private function Mystic_Net_Actions takes nothing returns nothing
    local real lx             =GetSpellTargetX()
    local real ly             =GetSpellTargetY()
    local MNdat_Throw dat     =MNdat_Throw.create()
    local real angle
    local real x
    local real y
    local real z
   
    set dat.caster  =GetTriggerUnit()
    set x           =GetUnitX(dat.caster)
    set y           =GetUnitY(dat.caster)
    set angle       =Atan2(ly-y,lx-x)
    set dat.x       =x+MissileSpeed*Cos(angle)
    set dat.y       =y+MissileSpeed*Sin(angle)
    set z           =GetZ(dat.x,dat.y)
    set dat.z       =GetUnitDefaultFlyHeight(dat.caster)+MissileFlyHeight+z
    set dat.distance=0.
    set dat.rope    =AddLightningEx(LightningType,true,dat.x,dat.y,dat.z,dat.x,dat.y,dat.z)
    set dat.dummy   =CreateUnit(Player(14),DummyId,dat.x,dat.y,angle*rad2deg)
    set dat.gfx     =AddSpecialEffectTarget(MissileGFXPath,dat.dummy,MissileGFXAttach)
   
    call UnitAddFly(dat.dummy)
    call SetUnitFlyHeight(dat.dummy,dat.z-z,0)
    call SetUnitX(dat.dummy,dat.x)
    call SetUnitY(dat.dummy,dat.y)

    call MNdat_Throw.addMotion(dat)
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0
    local unit upre

    set gg_trg_Mystic_Net = CreateTrigger(  )
    set MaxArea=bj_mapInitialPlayableArea
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Mystic_Net, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Mystic_Net, Condition( function Mystic_Net_Conditions ) )
    call TriggerAddAction( gg_trg_Mystic_Net, function Mystic_Net_Actions )
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,BuffSpellId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(MissileGFXPath)
    call Preload(MissGFXPath)
    call Preload(HitGFXPath)
    call Preload(GroundHitGFXPath)
    call Preload(ReactHitGFXPath)
    call Preload(ReactMissGFXPath)
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Implosion by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope Implosion initializer init
   //===================================================================================================================
   //Constants
  globals
     private constant integer SpellId        ='A00I'  //Ability Rawcode: Implosion
     private constant integer DummyId        ='e000'  //Unit Rawcode: Dummy
     private constant real MissileSpeed      =15.00   //The missile speed
     private constant real SplitMissileSpeed =10.00   //The missile speed of the small missiles
     private constant string HitFunction     ="Implosion_InitializationDamageEvent"  //The hit function (better you don't change this)
     private constant string EndFunction     ="Implosion_EndDamageEvent"  //The end function (better you don't change this)
     private constant string MissileGFX      ="Abilities\\Spells\\Undead\\DarkSummoning\\DarkSummonMissile.mdl"  //The model of the start missile
     private constant string MissileAttach   ="chest"  //The attach point of MissileGFX
     private constant real rateZ             =300.00  //The speed how fast the missile reach z
     private constant string TargetGFX       ="Abilities\\Spells\\Undead\\AntiMagicShell\\AntiMagicShell.mdl"  //The model for the victim
     private constant string TargetAttach    ="head"  //The attach point of TargetGFX
     private constant real range             =300.00  //The pick up range after the spell expired
     private constant string DamageGFX       ="Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"  //The model when it damage the target
     private constant string DamageAttach    ="origin"  //The attach point of DamageGFX
     private constant string EndMissileGFX   ="Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl"  //The model of the small missiles
     private constant string EndMissileAttach="chest"  //The attach point of EndMissileGFX
     private constant string EndEffectGFX    ="Abilities\\Spells\\Undead\\Possession\\PossessionMissile.mdl"  //Explosion Model of the small missiles
     private constant string EndEffectAttach ="origin"  //The attach point of the EndEffectGFX
     private constant integer MaxTarget      =6         //Maximal targets
     private constant real periodic          =0.03      //The periodic motion time
     
     private effect array missilegfx                    //The array where the missile model get saved in
  endglobals

  private constant function MaxTime takes integer lvl returns real
    //Maximal duration of the Implosion
    return lvl*4.
  endfunction

  private constant function DamagePerSecond takes integer lvl returns real
    //Damage the unit get per second
    return lvl*20.
  endfunction

  private constant function EndDamage takes integer lvl returns real
    //Damage that the targets get at the end
    return lvl*50.
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================
 
  //Conditions
  private function Implosion_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==SpellId
  endfunction
 
  //Actions
  private struct ImplosionDatas
    unit caster
    unit target
    effect gfx
    real dmg
    real ctime
    real mtime
    real counter
   
    method motion takes nothing returns nothing
      local real x
      local real y
      local integer index
      local integer id

      local unit u
      local unit a
      local group g

      set .counter=.counter+periodic
      set .ctime  =.ctime+periodic

      if .counter>1. then
         call DestroyEffect(AddSpecialEffectTarget(DamageGFX,.target,DamageAttach))
         call UnitDamageTarget(.caster,.target,.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
         set .counter=0
      endif

      if not IsUnitNotBuffImmune(.target) or .ctime>.mtime then
         call DestroyEffect(AddSpecialEffectTarget(EndEffectGFX,.target,EndEffectAttach))
         set index=0
         set g=GetUnitsInRange(range,GetUnitX(.target),GetUnitY(.target))
         call GroupRemoveUnit(g,.target)
         
         loop
           set a=FirstOfGroup(g)
           exitwhen a==null
           call GroupRemoveUnit(g,a)
           
           if UnitFilter(.caster,a) and index<MaxTarget then
             set x=GetUnitX(.target)
             set y=GetUnitY(.target)
             set u=CreateUnit(Player(14),DummyId,x,y,A2PXY(x,y,GetUnitX(a),GetUnitY(a)))
             call AddHandleIndex(u)
             set id=GetHandleIndex(u)
             set missilegfx[id]=AddSpecialEffectTarget(EndMissileGFX,u,EndMissileAttach)
             call LaunchNormalChaseMissileAtPointEx(.caster,u,x,y,GetUnitDefaultFlyHeight(a),a,SplitMissileSpeed,rateZ,EndFunction,id)
             set index=index+1
           endif
         endloop
         
         set .active=false
         set g=null
         set u=null
      endif
    endmethod
   
    method endmotion takes nothing returns nothing
      call DestroyEffect(.gfx)
     
       set .caster =null
       set .target =null
       set .gfx    =null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("ImplosionDatas","motion","endmotion","periodic")
  endstruct

  function Implosion_EndDamageEvent takes nothing returns nothing
    if IsUnitNotImmun(MotionDatabase_tc,MotionDatabase_tv) then
       call DestroyEffect(AddSpecialEffectTarget(DamageGFX,MotionDatabase_tv,DamageAttach))
       call UnitDamageTarget(MotionDatabase_tc,MotionDatabase_tv,EndDamage(GetUnitAbilityLevel(MotionDatabase_tc,SpellId)),true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
    endif

    call DestroyEffect(missilegfx[MotionDatabase_tdata])
    call ClearHandleIndex(MotionDatabase_tm)
    call U2Null(MotionDatabase_tm,0.5)
  endfunction

  function Implosion_InitializationDamageEvent takes nothing returns nothing
    local ImplosionDatas dat
    local integer lvl

    call ClearHandleIndex(MotionDatabase_tm)
    call DestroyEffect(missilegfx[MotionDatabase_tdata])
    call U2Null(MotionDatabase_tm,0.5)

    if UnitFilter(MotionDatabase_tc,MotionDatabase_tv) then
        set lvl        =GetUnitAbilityLevel(MotionDatabase_tc,SpellId)
   
        set dat        =ImplosionDatas.create()
        set dat.caster =MotionDatabase_tc
        set dat.target =MotionDatabase_tv
        set dat.gfx    =AddSpecialEffectTarget(TargetGFX,MotionDatabase_tv,TargetAttach)
        set dat.ctime  =0
        set dat.counter=1
        set dat.dmg    =DamagePerSecond(lvl)
        set dat.mtime  =MaxTime(lvl)

        call ImplosionDatas.addMotion(dat)
    endif
  endfunction

  private function Implosion_Actions takes nothing returns nothing
    local unit caster             =GetTriggerUnit()
    local unit target             =GetSpellTargetUnit()
    local real x                  =GetUnitX(caster)
    local real y                  =GetUnitY(caster)
    local real tx                 =GetUnitX(target)
    local real ty                 =GetUnitY(target)
    local unit missile            =CreateUnit(Player(14),DummyId,x,y,A2PXY(x,y,tx,ty))
    local integer id

    call AddHandleIndex(missile)
    set id            =GetHandleIndex(missile)
    set missilegfx[id]=AddSpecialEffectTarget(MissileGFX,missile,MissileAttach)
    call LaunchNormalChaseMissileAtPointEx(caster,missile,x,y,GetUnitDefaultFlyHeight(target),target,MissileSpeed,rateZ,HitFunction,id)

    set missile=null
    set caster=null
    set target=null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0
   
    set gg_trg_Implosion = CreateTrigger(  )    
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Implosion, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Implosion, Condition( function Implosion_Conditions ) )
    call TriggerAddAction( gg_trg_Implosion, function Implosion_Actions )
   
    //Preload
    call Preload(MissileGFX)
    call Preload(TargetGFX)
    call Preload(DamageGFX)
    call Preload(EndMissileGFX)
    call Preload(EndEffectGFX)
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Critical Jump by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope CriticalJump initializer init
   //===================================================================================================================
   //Constants
  globals
      private constant integer SpellId          ='A00Z'  //Ability Rawcode: Critical Jump
      private constant string EndEffect         ="Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"  //The model after the caster reach the ground
      private constant integer BuffSpellId      ='A01A'  //Ability Rawcode: Critical Jump - Effect
      private constant string CasterOrder       ="move"  //Order string of the order the caster get before the jump
      private constant integer CasterBuffSpellId='A00F'  //Ability Rawcode: Critical Jump - Effect (Caster)
      private constant integer CasterBuffId     ='B00B'  //Buff Rawcode: Critical Jump
      private constant string CasterBuffOrder   ="soulburn"//Order string for dummy to disable all abilities of the caster
      private constant integer DummyId          ='e000'  //Unit Rawcode: Dummy
      private constant real JumpSpeed           =15.00   //The jumpspeed of the caster
      private constant real Range               =250.00  //The damage range after the unit reached the ground
      private constant string ErrorMessage      ="|c00FF0000You can't jump to that point!|r"//The error message if you click at a not walkable area
     
      private trigger CriticalJumpCheck         =null    //Check if target area is walkable
  endglobals

  private constant function CJ_Damage takes integer lvl returns real
    //Damage all units get in the near when the caster reach the ground
    return 50.+(75.*lvl)
  endfunction
 
  private constant function CJ_BuffDuration takes integer lvl returns real
    //The duration of the stun buff
    return 1.25+0.25*lvl
  endfunction

  private constant function CJ_MaxFlyHeight takes real distance returns real
    //The maximal flyheight
    return distance*1.1
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if IsUnitType(u,UNIT_TYPE_FLYING)==false then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================

  //Conditions
  private function Critical_Jump_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==SpellId
  endfunction
 
  private function JumpCheck takes nothing returns nothing
    local location loc=GetSpellTargetLoc()
    local unit u
   
    if not IsPointWalkable(GetLocationX(loc),GetLocationY(loc)) then
      set u=GetTriggerUnit()
      call IssueImmediateOrder(u,"stop")
      call DisplayTextToPlayer(GetOwningPlayer(u),0.,0.,ErrorMessage)
      set u=null
    endif
   
    call RemoveLocation(loc)
    set loc=null
  endfunction
 
  //Actions
  //! runtextmacro BuffEffect("BuffSpellId","0.5","")
 
  private struct CriticalJumpDatas
    unit caster
   
    method onDestroy takes nothing returns nothing
      set .caster=null
    endmethod
  endstruct

  private function CriticalJumpEnd takes nothing returns nothing
    local timer t              =GetExpiredTimer()
    local CriticalJumpDatas dat=GetTimerDataInt(t)
    local integer lvl          =GetUnitAbilityLevel(dat.caster,SpellId)
    local real x               =GetUnitX(dat.caster)
    local real y               =GetUnitY(dat.caster)
    local real dmg             =CJ_Damage(lvl)
    local real dur             =CJ_BuffDuration(lvl)
    local group g              =GetUnitsInRange(Range,x,y)
    local unit a

    call GroupRemoveUnit(g,dat.caster)
    call DestroyEffect(AddSpecialEffect(EndEffect,x,y))
    call TerrainDeformationRippleXY(1,false,x,y,0,Range,90,0.5,200)

    loop
      set a=FirstOfGroup(g)
      exitwhen a==null
      call GroupRemoveUnit(g,a)
     
      if UnitFilter(dat.caster,a) then
        call UnitAddBuff(a,dur,lvl)

        call UnitDamageTarget(dat.caster,a,dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
      endif
    endloop

    call SetUnitFlyHeight(dat.caster,0,0)
    call DestroyBuffAfterTime(dat.caster,CasterBuffId,2.)

    call SetUnitAnimation(dat.caster,"attack")
    call SetUnitPathing(dat.caster,true)
   
    call dat.destroy()
    call RecycleTimer(t)
    set g=null
    set t=null
  endfunction

  private function Critical_Jump_Actions takes nothing returns nothing
    local timer t              
    local CriticalJumpDatas dat=CriticalJumpDatas.create()

    local real distance
    local real lx              =GetSpellTargetX()
    local real ly              =GetSpellTargetY()
    local real x
    local real y
    local unit bx
   
    set dat.caster=GetTriggerUnit()
    set x         =GetUnitX(dat.caster)
    set y         =GetUnitY(dat.caster)
    set distance  =D2PXY(x,y,lx,ly)

    if x!=lx or y!=ly then
      set bx=CreateUnit(Player(14),DummyId,x,y,0)
      call UnitAddAbility(bx,CasterBuffSpellId)
      call IssueTargetOrder(bx,CasterBuffOrder,dat.caster)
      call U2Null(bx,0.5)
      set bx=null
    endif

    call IssuePointOrder(dat.caster,CasterOrder,lx,ly)
    call SetUnitPathing(dat.caster,false)
    call LaunchMissileAtPointEx(dat.caster,x,y,0.,CJ_MaxFlyHeight(distance),lx,ly,0.,JumpSpeed)

    call SetUnitFacing(dat.caster,A2PXY(x,y,lx,ly))
   
    set t=GetNextTimerInt(dat)
    call TimerStart(t,distance/JumpSpeed*MotionDatabase_periodic,false,function CriticalJumpEnd)

    set t  =null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local boolexpr b=Condition( function Critical_Jump_Conditions )
    local integer i =0
    local player p
    local unit upre
 
    set gg_trg_Critical_Jump = CreateTrigger(  )
    set CriticalJumpCheck    = CreateTrigger(  )
    loop
      set p=Player(i)
      call TriggerRegisterPlayerUnitEvent(CriticalJumpCheck,p,EVENT_PLAYER_UNIT_SPELL_CAST, MainFunctions_filter)
      call TriggerRegisterPlayerUnitEvent(gg_trg_Critical_Jump,p,EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddAction( CriticalJumpCheck, function JumpCheck )
    call TriggerAddAction( gg_trg_Critical_Jump, function Critical_Jump_Actions )
    call TriggerAddCondition( CriticalJumpCheck, b )
    call TriggerAddCondition( gg_trg_Critical_Jump, b )
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,BuffSpellId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(EndEffect)
   
    set b   =null
    set p   =null
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Paralyzing Field by Darkt3mpl3r aka GiR- and coded by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope ParalyzingField initializer init
   //===================================================================================================================
   //Constants
  globals
    private constant integer SpellId          ='A00J'  //Ability Rawcode: Paralyzing Field
    private constant integer EffectId         ='A00A'  //Ability Rawcode: Paralyzing Field - Effect
    private constant integer BuffId           ='B00C'  //Ability Rawcode: Paralyzing Field
    private constant integer DummyId          ='e000'  //Unit Rawcode: Dummy
    private constant real InitFreeze          =3.0     //Duration of paralyzing
    private constant real OutFreeze           =0.5     //Duration of unparalyzing
   
    private constant string stop              ="stop"  //Order string of the target units
    private constant string FieldMdl          ="war3mapImported\\FinalField.mdx"  //Model of the field
    private constant string FieldMdlAttach    ="origin"//The attach point of the FieldMdl
    private constant real Checkperiodic       =0.25    //The periodic check of the freezing
    private constant real periodic            =0.03    //The periodic search for new units
   
    private integer array TargetBuffData[maxIndex]     //Important attached datas
    private integer array BuffData[maxIndex]           //Important attached datas
    private trigger endcast                   =null    //This trigger is for the channal effect (better you don't change this)
    private group frozenall                   =null    //This is the group with the frozen units (better you don't change this)
  endglobals
 
  private constant function PF_FieldMdlSize takes integer lvl returns real
    //The size of the FieldMdl
    return 1.3
  endfunction
 
  private constant function PF_Range takes integer lvl returns real
    //The size of the area where the paralyzing field be effective
    return 400.
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================
 
  //Conditions
  private function Paralyzing_Field_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==SpellId
  endfunction
 
  //Actions
  private struct FadeOut
    real default
    real speed
    real fade
    real time
    unit u
 
    method check takes nothing returns nothing
      if GetUnitState(.u,UNIT_STATE_LIFE)<=0.00 then
        call SetUnitTimeScale(.u,1.)
        call SetUnitMoveSpeed(.u,.default)
        call UnitRemoveAbility(.u,EffectId)
        call UnitRemoveAbility(.u,BuffId)
        set .active=false
       
        return
      endif
   
      if .time>OutFreeze then
        call SetUnitTimeScale(.u,1.)
        call SetUnitMoveSpeed(.u,.default)
        call UnitRemoveAbility(.u,EffectId)
        call UnitRemoveAbility(.u,BuffId)
     
        set .active=false
      else
        set .fade=.fade+.speed
       
        call SetUnitAbilityLevel(.u,EffectId,R2I(.fade*100/.default*0.1)+1)
        call SetUnitMoveSpeed(.u,.fade)
        call SetUnitTimeScale(.u,.fade*100/.default*0.01)
        set .time=.time+Checkperiodic
      endif
    endmethod
   
    method endcheck takes nothing returns nothing
      set .u      =null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("FadeOut","check","endcheck","Checkperiodic")
  endstruct
 
  private struct Paralyzed
    unit u
    group g
 
    integer motiontype
    real x
    real y
    real default
    real speed
    real fade
    real time
    real distance
   
    method check takes nothing returns nothing
      local real x
      local real y
     
      if GetUnitState(.u,UNIT_STATE_LIFE)<=0.00 then
        call GroupRemoveUnit(.g,.u)
        call GroupRemoveUnit(frozenall,.u)
        set .active=false
       
        return
      endif
   
      if .motiontype==1 then
        if .time>InitFreeze then
          set .motiontype=2
         
          call SetUnitMoveSpeed(.u,0.)
          call SetUnitTimeScale(.u,0.)
        else
          set .fade=.fade-.speed

          call SetUnitAbilityLevel(.u,EffectId,R2I(.fade*100/.default*0.1)+1)
          call SetUnitMoveSpeed(.u,.fade)
          call SetUnitTimeScale(.u,.fade*100/.default*0.01)
          set .time=.time+Checkperiodic
        endif
      elseif .motiontype==2 then
        set x=GetUnitX(.u)
        set y=GetUnitY(.u)
     
        if .distance>D2PXY(.x,.y,x,y) then
          call IssueImmediateOrder(.u,stop)
        else
          call GroupRemoveUnit(.g,.u)
          call GroupRemoveUnit(frozenall,.u)
          set .active=false
        endif
      endif
    endmethod
   
    method endcheck takes nothing returns nothing
      local FadeOut fo=FadeOut.create()
     
      set fo.default=.default
      set fo.speed  =.default/OutFreeze*Checkperiodic
      set fo.fade   =0.
      set fo.time   =0.
      set fo.u      =.u
     
      call ClearHandleIndex(.u)
      call FadeOut.addMotion(fo)
     
      set .u        =null
      set .g        =null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("Paralyzed","check","endcheck","Checkperiodic")
  endstruct
 
  private struct ParalyzingField
    unit u
    unit dummy
    real x
    real y
    group frozen
    effect mdl
    integer lvl
 
    method motion takes nothing returns nothing
      local Paralyzed p
      local group g=GetUnitsInRange(PF_Range(.lvl),.x,.y)
      local unit a
      local real def
     
      call GroupRemoveUnit(g,.u)
      loop
        set a=FirstOfGroup(g)
        exitwhen a==null
        call GroupRemoveUnit(g,a)
       
        if UnitFilter(.u,a) and not IsUnitInGroup(a,frozenall) then
          call UnitAddAbility(a,EffectId)
       
          set def         =GetUnitDefaultMoveSpeed(a)
          set p           =Paralyzed.create()
          set p.motiontype=1
         
          set p.u         =a
          set p.fade      =def
          set p.default   =def
         
          set p.time      =0.
          set p.speed     =def/InitFreeze*Checkperiodic
         
          set p.motiontype=1
          set p.distance  =PF_Range(.lvl)
          set p.x         =.x
          set p.y         =.y
          set p.g         =.frozen
          call Paralyzed.addMotion(p)
         
          call GroupAddUnit(.frozen,a)
          call GroupAddUnit(frozenall,a)
          call AddHandleIndex(a)
          set TargetBuffData[GetHandleIndex(a)]=p
        endif
      endloop
     
      set g=null
    endmethod

    method endmotion takes nothing returns nothing
      local Paralyzed p
      local unit a
     
      loop
        set a=FirstOfGroup(.frozen)
        exitwhen a==null
        call GroupRemoveUnit(.frozen,a)
        call GroupRemoveUnit(frozenall,a)
       
        set p=TargetBuffData[GetHandleIndex(a)]
        set p.active=false
      endloop
     
      call ClearHandleIndex(.u)
      call GroupClear(.frozen)
      call RecycleGroup(.frozen)
      call DestroyEffect(.mdl)
      call RemoveUnit(.dummy)
   
      set .u     =null
      set .dummy =null
      set .frozen=null
      set .mdl   =null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("ParalyzingField","motion","endmotion","periodic")
  endstruct
 
  private function EndParalyzingField takes nothing returns nothing
    local ParalyzingField pf=BuffData[GetHandleIndex(GetTriggerUnit())]
   
    set pf.active=false
  endfunction

  private function Paralyzing_Field_Actions takes nothing returns nothing
    local ParalyzingField pf=ParalyzingField.create()
    local real size
   
    set pf.u     =GetTriggerUnit()
    set pf.x     =GetSpellTargetX()
    set pf.y     =GetSpellTargetY()
    set pf.frozen=GetNextGroup()
    set pf.dummy =CreateUnit(Player(14),DummyId,pf.x,pf.y,0)
    set pf.mdl   =AddSpecialEffectTarget(FieldMdl,pf.dummy,FieldMdlAttach)
    set pf.lvl   =GetUnitAbilityLevel(pf.u,SpellId)
   
    set size     =PF_FieldMdlSize(pf.lvl)
    call SetUnitScale(pf.dummy,size,size,size)
   
    call AddHandleIndex(pf.u)
    call ParalyzingField.addMotion(pf)
    set BuffData[GetHandleIndex(pf.u)]=pf
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local boolexpr b=Condition( function Paralyzing_Field_Conditions )
    local integer i =0
    local unit upre
    local player p
 
    set frozenall=GetNextGroup()
    set gg_trg_Paralyzing_Field=CreateTrigger()
    call TriggerAddCondition(gg_trg_Paralyzing_Field, b )
    call TriggerAddAction(gg_trg_Paralyzing_Field, function Paralyzing_Field_Actions )

    set endcast=CreateTrigger()
    call TriggerAddCondition( endcast, b )
    call TriggerAddAction( endcast, function EndParalyzingField )
   
    loop
      set p=Player(i)
      call TriggerRegisterPlayerUnitEvent(gg_trg_Paralyzing_Field, p,EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)
      call TriggerRegisterPlayerUnitEvent(endcast, p,EVENT_PLAYER_UNIT_SPELL_ENDCAST, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
   
    set p=null
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,EffectId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(FieldMdl)
   
    set b   =null
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Burrowstrike by Darkt3mpl3r aka GiR- and coded by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor
// Notice: This spell just work together with the animations of the Cryptlord

scope Burrowstrike initializer init
   //===================================================================================================================
   //Constants
  globals
    private constant integer SpellId ='A00K'   //Ability Rawcode: Burrowstrike
    private constant integer EffectId='A01B'   //Ability Rawcode: Burrowstrike - Effect
    private constant integer DodgeId ='A00M'   //Ability Rawcode: Burrowstrike - Effect (Caster)
    private constant integer DummyId ='e000'   //Unit Rawcode: Dummy
    private constant real Range      =120.     //The range till the caster collide with the target
    private constant real AniTime    =0.9      //Animation time of the burrow
    private constant string AniGFX   ="morph"  //The burrow animation string
    private constant string AniEnd   ="spell throw"//The dig up animation string
    private constant real Speed      =15.      //The speed of the caster
    private constant real EndRange   =300.     //The range of the damage when the target unit reach again the ground
    private constant real JumpRange  =200.     //The distance the target jump away
    private constant real JumpHigh   =100.     //The height the target jump away
    private constant real JumpTime   =0.5      //The maximal jumptime of the target
    private constant string stunGFX  ="Abilities\\Spells\\Orc\\StasisTrap\\StasisTotemTarget.mdl"//The model of the target unit after hit
    private constant string stunATT  ="overhead"//The attach point of stunGFX
    private constant string endGFX   ="Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"//The model when the target reach the ground again
    private constant real periodic   =0.03     //The periodic motion time
  endglobals
 
  private constant function BS_UnitDamage takes integer lvl returns real
    //Damage the target get
    return 50.+100.*lvl
  endfunction
 
  private constant function BS_BuffDuration takes integer lvl returns real
    //The duration of the stun buff
    return 4.
  endfunction
 
  private constant function BS_GroupDamage takes integer lvl returns real
    //Damage what all units in the near get when the target reach the ground
    return lvl*25.+50.
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================
 
  //Conditions
  private function Burrowstrike_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SpellId
  endfunction
 
  //Actions
  //! runtextmacro BuffEffect("EffectId","0.5","")
 
  private struct BurrowChase
    unit u
    unit t
    effect mdl
   
    static method action takes nothing returns nothing
      local timer t       =GetExpiredTimer()
      local BurrowChase ej=GetTimerDataInt(t)
      local integer lvl   =GetUnitAbilityLevel(ej.u,SpellId)
      local real x        =GetUnitX(ej.t)
      local real y        =GetUnitY(ej.t)
      local real dmg      =BS_GroupDamage(lvl)
      local real dur      =BS_BuffDuration(lvl)
      local group g
      local unit a
     
      call SetUnitPathing(ej.t,true)
      call SetUnitPosition(ej.t,x,y)
     
      set x=GetUnitX(ej.t)
      set y=GetUnitY(ej.t)
      set g=GetUnitsInRange(EndRange,x,y)
      call DestroyEffect(ej.mdl)
      call DestroyEffect(AddSpecialEffect(endGFX,x,y))
     
      call TerrainDeformationRippleXY(1,false,x,y,0,EndRange,90,0.5,200)
      call UnitDamageTarget(ej.u,ej.t,BS_UnitDamage(lvl),true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
      loop
        set a=FirstOfGroup(g)
        exitwhen a==null
        call GroupRemoveUnit(g,a)
       
        if UnitFilter(ej.u,a) then
          call UnitAddBuff(a,dur,lvl)
       
          if a!=ej.t then
            call UnitDamageTarget(ej.u,a,dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
          endif
        endif
      endloop
     
      call ej.destroy()
      call RecycleTimer(t)
      set g=null
      set t=null
    endmethod
 
    method motion takes nothing returns nothing
      local real x    =GetUnitX(.u)
      local real y    =GetUnitY(.u)
      local real xt   =GetUnitX(.t)
      local real yt   =GetUnitY(.t)
      local real angle=Atan2(yt-y,xt-x)
     
      call SetUnitAnimation(.u,AniGFX)
      set x=x+Speed*Cos(angle)
      set y=y+Speed*Sin(angle)
     
      if D2PXY(x,y,xt,yt)>Range and UnitFilter(.u,.t) then
        call SetUnitPosition(.u,x,y)
        call SetUnitFacing(.u,angle*rad2deg)
      else
        set .active=false
      endif
    endmethod
   
    method endmotion takes nothing returns nothing
      local timer t
      local real x
      local real y
      local real angle
   
      call UnitRemoveAbility(.u,DodgeId)
      call SetUnitPosition(.u,GetUnitX(.u),GetUnitY(.u))
      call SetUnitPathing(.u,true)
      call SetUnitTimeScale(.u,1.)
      call SetUnitAnimation(.u,AniEnd)
   
      if UnitFilter(.u,.t) then
        set t    =GetNextTimerInt(this)
        set x    =GetUnitX(.t)
        set y    =GetUnitY(.t)
        set .mdl =AddSpecialEffectTarget(stunGFX,.t,stunATT)
        set angle=Atan2(y-GetUnitY(.u),x-GetUnitX(.u))
       
        call SetUnitPathing(.t,false)
       
        call LaunchMissileAtPointEx(.t,x,y,0.,JumpHigh,x+JumpRange*Cos(angle),y+JumpRange*Sin(angle),0.,JumpRange/JumpTime*MotionDatabase_periodic)
        call TimerStart(t,JumpTime,false,function BurrowChase.action)
     
        set t=null
      else
        call DestroyEffect(.mdl)
     
        set .mdl=null
        set .u=null
        set .t=null
        call .destroy()
      endif
    endmethod
   
    //! runtextmacro CostumMotion("BurrowChase","motion","endmotion","periodic")
  endstruct
 
  private function AnimationEnd takes nothing returns nothing
    local timer t       =GetExpiredTimer()
    local BurrowChase bc=GetTimerDataInt(t)
   
    call PauseUnit(bc.u,false)
    call SetUnitPathing(bc.u,false)
    call SetUnitTimeScale(bc.u,0.)
    call BurrowChase.addMotion(bc)
    call RecycleTimer(t)
    set t=null
  endfunction

  private function Burrowstrike_Actions takes nothing returns nothing
    local BurrowChase bc=BurrowChase.create()
    local timer t       =GetNextTimerInt(bc)
   
    set bc.u=GetTriggerUnit()
    set bc.t=GetSpellTargetUnit()
   
    call PauseUnit(bc.u,true)
    call UnitAddAbility(bc.u,DodgeId)
    call SetUnitAnimation(bc.u,AniGFX)
   
    call TimerStart(t,AniTime,false,function AnimationEnd)
    set t=null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing  
    local integer i=0
    local unit upre
   
    set gg_trg_Burrowstrike = CreateTrigger(  )
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Burrowstrike, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Burrowstrike, Condition( function Burrowstrike_Conditions ) )
    call TriggerAddAction( gg_trg_Burrowstrike, function Burrowstrike_Actions )
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,EffectId)
    call UnitAddAbility(upre,DodgeId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(stunGFX)
    call Preload(endGFX)
  endfunction
endscope
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Holy Shock by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope HolyShock initializer init
   //===================================================================================================================
   //Constants
  globals
     private constant integer SpellId       ='A00N'  //Ability Rawcode: Holy Shock
     private constant integer DummyId       ='e000'  //Unit Rawcode: Dummy
     private constant real distance         =600.    //Maximal distance the missiles will move
     private constant string MissileExplFunc="HolyShockEnd"//The endfunction of the missile move (better you don't change this)
     private constant string MissileMdl     ="Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"//The model of the missile 1#
     private constant string MissileMdl2    ="Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl"//The model of the missile 2#
     private constant string MissileAttach  ="origin"//The models attachpoint
     private constant real MissileSpeed     =10.     //The speed of the missiles
     private constant real DamageRange      =90.     //The collision range of the missiles
     private constant real MissileZ         =45.     //The flyheight of the missiles
     private constant real periodic         =0.03    //The periodic motion time

     private rect MaxArea                   =null    //The maximal movearea of the missiles
  endglobals
 
  private constant function Amount takes integer lvl returns real
    //The maximal amount of shock missiles
    return 8.
  endfunction
 
  private constant function Chance takes integer lvl returns real
    //The chance that missiles will be released
    return 10.+(10.*lvl)
  endfunction
 
  private constant function Damage takes integer lvl returns real
    //Damage the units get when they collide with missiles
    return lvl*25.+25.
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if IsUnitType(u,UNIT_TYPE_FLYING)==false then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================

  //Conditions
  private function Holy_Shock_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(GetTriggerUnit(),SpellId) > 0
  endfunction
 
  //Actions
  private struct HolyShockMissile
    unit u
    unit caster
    effect gfx
    effect mgfx
    real x
    real y
    real max
    real min
    real tdistance
    real dmg
   
    method motion takes nothing returns nothing
      local group g
      local unit a
      local real angle=GetRandomReal(.min,.max)*deg2rad
     
      set .x=.x+MissileSpeed*Cos(angle)
      set .y=.y+MissileSpeed*Sin(angle)
      if RectContainsCoords(MaxArea,.x,.y) then
        call SetUnitX(.u,.x)
        call SetUnitY(.u,.y)
      else
        set .active=false
      endif
      set g=GetUnitsInRange(DamageRange,.x,.y)
      call GroupRemoveUnit(g,.u)
      loop
        set a=FirstOfGroup(g)
        exitwhen a==null
        call GroupRemoveUnit(g,a)
       
        if UnitFilter(.caster,a) then
          call E2Null(AddSpecialEffectTarget(MissileMdl2,a,MissileAttach),0.5)
          call UnitDamageTarget(.caster,a,.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
          set .active=false
        endif
      endloop
      if .tdistance>distance then
        set .active=false
      endif
     
      set .tdistance=.tdistance+MissileSpeed
      set g=null
    endmethod
   
    method endmotion takes nothing returns nothing
      call U2Null(.u,0.5)
      call DestroyEffect(.gfx)
      call DestroyEffect(.mgfx)
     
      set .caster   =null
      set .u        =null
      set .gfx      =null
      set .mgfx     =null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("HolyShockMissile","motion","endmotion","periodic")
  endstruct  
 
 
  private function HolyShockBegin takes nothing returns boolean
    local integer i     =1
    local integer lvl   =GetUnitAbilityLevel(DamageSkill_attacked,SpellId)
    local real x        =GetUnitX(DamageSkill_attacked)
    local real y        =GetUnitY(DamageSkill_attacked)
    local real angle    =360./Amount(lvl)
    local real tangle   =GetRandomReal(0,360)
   
    local HolyShockMissile dat
   
    call E2Null(AddSpecialEffectTarget(MissileMdl2,DamageSkill_attacked,MissileAttach),0.5)
    loop
      exitwhen i>Amount(lvl)
     
      set dat          =HolyShockMissile.create()
      set dat.caster   =DamageSkill_attacked
      set dat.u        =CreateUnit(Player(14),DummyId,x,y,tangle)
      set dat.mgfx     =AddSpecialEffectTarget(MissileMdl,dat.u,MissileAttach)
      set dat.gfx      =AddSpecialEffectTarget(MissileMdl2,dat.u,MissileAttach)
      set dat.min      =tangle-angle
      set dat.max      =tangle+angle
      set dat.x        =x
      set dat.y        =y
      set dat.tdistance=0.
      set dat.dmg      =Damage(lvl)
      call UnitAddFly(dat.u)
      call SetUnitFlyHeight(dat.u,MissileZ,0.)    
     
      call HolyShockMissile.addMotion(dat)
     
      set tangle=tangle+angle
      set i=i+1
    endloop
   
    return true
  endfunction

  private function Holy_Shock_Actions takes nothing returns nothing
    local real rndm    =GetRandomReal(0,100)
    local unit a       =GetAttacker()
    local unit u       =GetTriggerUnit()
    if Chance(GetUnitAbilityLevel(u,SpellId))>=rndm then
       call TriggerAddDamageEvent(u,a,function HolyShockBegin)
    endif
    set a=null
    set u=null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0    
   
    set gg_trg_Holy_Shock = CreateTrigger(  )
    set MaxArea = bj_mapInitialPlayableArea    
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Holy_Shock, Player(i),EVENT_PLAYER_UNIT_ATTACKED, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Holy_Shock, Condition( function Holy_Shock_Conditions ) )
    call TriggerAddAction( gg_trg_Holy_Shock, function Holy_Shock_Actions )
   
    //Preload
    call Preload(MissileMdl)
    call Preload(MissileMdl2)
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Jade Shield by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope JadeShield initializer init
   //===================================================================================================================
   //Constants
  globals
    private constant integer SpellId  ='A00O'  //Ability Rawcode: Jade Shield
    private constant integer DummyId  ='e000'  //Unit Rawcode: Dummy
    private constant real speed       =10.     //Speed of rotating missiles
    private constant real distance    =120.    //Distance of rotating missiles to caster
    private constant real range       =90.     //Collision Range of missiles
    private constant integer amount   =3       //Amount of missiles which rotate around the caster
    private constant boolean knockback=true    //Enable/Disable small knockback when they collide with the missiles
    private constant real knockbackran=20.     //Knockback distance when unit collide with missile
    private constant string MissileMdl="Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl"  //Model of the missiles
    private constant string MissileAtt="chest"  //Attach point of the MissileMdl
    private constant string HitMdl    ="Abilities\\Spells\\Undead\\Possession\\PossessionMissile.mdl"  //Model when missiles hit a unit
    private constant string HitAtt    ="chest"  //Attach point of the HitMdl
    private constant real periodic    =0.03     //The periodic motion time
   
    //Don't change this. This is the key in that your datas will be attached.
     private integer array BuffData[maxIndex]   //Important attached datas
  endglobals
 
  private constant function Damage takes integer lvl returns real
    //Damage the victims get when they collide with the missiles
    return 50.*lvl+50.
  endfunction
 
  private constant function MaxTime takes integer lvl returns real
    //Maximal life time of the missiles
    return 10.
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if IsUnitType(u,UNIT_TYPE_FLYING)==false then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================
 
  //Conditions
  private function Jade_Shield_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SpellId
  endfunction
 
  //Actions
  private struct JadeShieldDatas
    unit caster=null
    unit array missile[amount]
    effect array gfx[amount]
    real angle
    real angledistance
    real time
    integer lvl
 
    method motion takes nothing returns nothing
      local real ux    =GetUnitX(.caster)
      local real uy    =GetUnitY(.caster)
      local real x
      local real y
      local real dmg   =Damage(.lvl)
      local group g
      local unit a
      local real angle =.angle
      local real direc
      local real ax
      local real ay
      local integer i  =1
      local integer f  =0
     
      loop
        exitwhen i>amount
       
        if .gfx[i-1]!=null then
          set x=ux+distance*Cos(angle*deg2rad)
          set y=uy+distance*Sin(angle*deg2rad)
          call SetUnitPosition(.missile[i-1],x,y)
          call SetUnitFacing(.missile[i-1],angle+90.)
          set g=GetUnitsInRange(range,x,y)
          call GroupRemoveUnit(g,.missile[i-1])
          loop
            set a=FirstOfGroup(g)
            exitwhen a==null or .gfx[i-1]==null
            call GroupRemoveUnit(g,a)
         
            if UnitFilter(.caster,a) then
              if knockback then
                set ax   =GetUnitX(a)
                set ay   =GetUnitY(a)
                set direc=Atan2(ay-uy,ax-ux)
           
                call SetUnitPosition(a,GetUnitX(a)+knockbackran*Cos(direc),GetUnitY(a)+knockbackran*Sin(direc))
              endif
         
              call DestroyEffect(AddSpecialEffectTarget(HitMdl,a,HitAtt))
              call UnitDamageTarget(.caster,a,dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
           
              call DestroyEffect(.gfx[i-1])
              call U2Null(.missile[i-1],0.5)
              set .gfx[i-1]=null
            endif
          endloop
          set g=null
        else
          set f=f+1
        endif
       
        set angle=angle+.angledistance                
        set i=i+1
      endloop
     
      set .active=.time<=MaxTime(.lvl) and f<amount and GetUnitState(.caster,UNIT_STATE_LIFE)>0.
      set .time =.time+periodic
      set .angle=.angle+speed
    endmethod
   
    method endmotion takes nothing returns nothing
      local integer i=0
   
      loop
        exitwhen i==amount
     
        if .gfx[i]!=null then
          call DestroyEffect(.gfx[i])
          call U2Null(.missile[i],0.5)
          set .gfx[i]    =null
          set .missile[i]=null
        endif
       
        set i=i+1
      endloop
     
      call ClearHandleIndex(.caster)
      set .caster       =null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("JadeShieldDatas","motion","endmotion","periodic")
  endstruct

  private function Jade_Shield_Actions takes nothing returns nothing
    local unit u             =GetTriggerUnit()
    local real angle
    local real x             =GetUnitX(u)
    local real y             =GetUnitY(u)
    local integer i          =0
    local integer d          =GetHandleIndex(u)
    local JadeShieldDatas dat=BuffData[d]
   
    if dat.active and dat.caster==u then
      set dat.active=false
    endif
   
    set dat              =JadeShieldDatas.create()
    set dat.caster       =u
    set dat.angledistance=360./amount
    set dat.angle        =GetRandomReal(0.,360.)
    set angle            =dat.angle
    set dat.lvl          =GetUnitAbilityLevel(u,SpellId)
    set dat.time         =0.
    loop
      exitwhen i==amount
     
      set dat.missile[i]=CreateUnit(Player(14),DummyId,x+distance*Cos(angle*deg2rad),y+distance*Sin(angle*deg2rad),angle-45)
      set dat.gfx[i]     =AddSpecialEffectTarget(MissileMdl,dat.missile[i],MissileAtt)
     
      set angle=angle+dat.angledistance
      set i=i+1
    endloop
   
    call AddHandleIndex(u)
    set d=GetHandleIndex(u)
    set BuffData[d]=dat
    call JadeShieldDatas.addMotion(dat)
    set u=null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0  
 
    set gg_trg_Jade_Shield = CreateTrigger(  )
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Jade_Shield, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(gg_trg_Jade_Shield, Condition( function Jade_Shield_Conditions ) )
    call TriggerAddAction(gg_trg_Jade_Shield, function Jade_Shield_Actions )
   
    //Preload
    call Preload(MissileMdl)
    call Preload(HitMdl)
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Berserk Rage by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope BerserkRage initializer init
   //===================================================================================================================
   //Constants
   globals
     private constant integer SpellId            ='A00R'    //Ability Rawcode: Berserk Rage
     private constant integer BuffSpellCasterId  ='A00P'    //Ability Rawcode: Berserk Rage - Effect (Caster)
     private constant integer BuffSpellId        ='A014'    //Ability Rawcode: Berserk Rage - Effect
     private constant integer BuffId             ='B00E'    //Buff Rawcode: Berserk Rage
     private constant integer DummyId            ='e000'    //Unit Rawcode: Dummy
     private constant string BuffSpellCasterOrder="soulburn"//Order string of the dummy to cast buff
     private constant string RunOrder            ="move"    //Order for caster to run at target point
     private constant string StopOrder           ="stop"    //Order to let the caster stop
     private constant real backDistance          =100.      //The distance your caster jump back
     private constant real backZ                 =50.       //The high your caster jump back
     private constant real pushDistance          =200.      //The distance the victim jump away
     private constant real pushZ                 =100.      //The high the victim jump away
     private constant real pushRange             =200.      //The pick up range of the victim after jump
     private constant real backRange             =200.      //The pick up range after collision
     private constant real speed                 =20.       //The speed your caster will be moved forward
     private constant real range                 =120.      //The collision range of the caster
     private constant real backTime              =0.5       //The flytime of the caster
     private constant real pushTime              =0.75      //The flytime of the victim
     private constant string casterMdl           ="Abilities\\Spells\\Other\\HowlOfTerror\\HowlTarget.mdl"  //Model after cast for caster
     private constant string casterAttach        ="chest"   //Attach Point of the casterMdl
     private constant string targetMdl           ="Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"  //Model when caster hit victim
     private constant string targetAttach        ="chest"   //Attach Point of the targetMdl
     private constant string endMdl              ="Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"  //Model when the victim or caster reach the ground again
     private constant string exitMdl             ="Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl"  //Model when the caster hit nobody  
     private constant real periodic              =0.03      //The periodic motion time
     
     private rect MaxArea=null                              //The maximal movearea of the missiles
   endglobals
   
   private constant function Damage takes integer lvl returns real
     //Damage of the spell
     return 50.*lvl+100
   endfunction
   
   private constant function BuffDuration takes integer lvl returns real
      //The duration of the buff
      return 1.25+0.25*lvl
   endfunction
   
   private function UnitFilter takes unit c,unit u returns boolean
     //The unit filter for the units who get damage
     if GetUnitState(u,UNIT_STATE_LIFE)>0. then
     if IsUnitType(u,UNIT_TYPE_FLYING)==false then
     if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
     return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
     endif
     endif
     endif
   
     return false
   endfunction
   //End Constants
   //===================================================================================================================
   
   //Conditions
   private function Berserker_Rush_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SpellId
   endfunction
     
   //Actions
   //! runtextmacro BuffEffect("BuffSpellId","0.5","")
   
   private struct PushDatas
     unit u
     unit caster
     
     method onDestroy takes nothing returns nothing
       set .u     =null
       set .caster=null
     endmethod
   endstruct
   
   private function PushEnd takes nothing returns nothing
     local timer t     =GetExpiredTimer()
     local PushDatas pd=GetTimerDataInt(t)
     local integer lvl =GetUnitAbilityLevel(pd.caster,SpellId)
     local real x      =GetUnitX(pd.u)
     local real y      =GetUnitY(pd.u)
     local real b      =BuffDuration(lvl)
     local group g     =GetUnitsInRange(pushRange,x,y)
     local unit a
     
     if IsUnitType(pd.u, UNIT_TYPE_FLYING) then
       call SetUnitFlyHeight(pd.u,GetUnitDefaultFlyHeight(pd.u),300.)
     endif    
     call DestroyEffect(AddSpecialEffect(endMdl,x,y))
     call GroupRemoveUnit(g,pd.caster)
     loop
       set a=FirstOfGroup(g)
       exitwhen a==null
       call GroupRemoveUnit(g,a)
       
       if UnitFilter(pd.caster,a) then
         call UnitAddBuff(a,b,lvl)
       endif
     endloop
     
     call SetUnitPathing(pd.u,true)
     call SetUnitPosition(pd.u,x,y)
     call pd.destroy()
     call RecycleTimer(t)
     set t=null
     set g=null
   endfunction
   
   private function BackEnd takes nothing returns nothing
     local timer t    =GetExpiredTimer()
     local unit u     =GetTimerDataUnit(t)
     local integer lvl=GetUnitAbilityLevel(u,SpellId)
     local real x     =GetUnitX(u)
     local real y     =GetUnitY(u)
     local real b     =BuffDuration(lvl)
     local group g    =GetUnitsInRange(backRange,x,y)
     local unit a
     
     if IsUnitType(u, UNIT_TYPE_FLYING) then
       call SetUnitFlyHeight(u,GetUnitDefaultFlyHeight(u),300.)
     endif
     call DestroyEffect(AddSpecialEffect(endMdl,x,y))
     call GroupRemoveUnit(g,u)
     loop
       set a=FirstOfGroup(g)
       exitwhen a==null
       call GroupRemoveUnit(g,a)
       
       if UnitFilter(u,a) then
         call UnitAddBuff(a,b,lvl)
       endif
     endloop

     call SetUnitPathing(u,true)
     call SetUnitPosition(u,x,y)  
     call RecycleTimer(t)
     set t=null
     set u=null
     set g=null
   endfunction

   private struct BerserkerRushDatas
      unit caster
      effect gfx
     
      real distance
      real angle
      real dmg      
     
      method motion takes nothing returns nothing
        local real x
        local real y
        local group g
        local unit a
        local real ax
        local real ay
        local timer t
        local PushDatas pd

        set .angle=GetUnitFacing(.caster)*deg2rad
        set x     =GetUnitX(.caster)+speed*Cos(.angle)
        set y     =GetUnitY(.caster)+speed*Sin(.angle)
        if .distance>0. and GetUnitState(.caster,UNIT_STATE_LIFE)>0. and RectContainsCoords(MaxArea,x,y) and IsPointWalkable(x,y) then
          call SetUnitX(.caster,x)
          call SetUnitY(.caster,y)

          set g=GetUnitsInRange(range,x,y)
          call GroupRemoveUnit(g,.caster)
          loop
            set a=FirstOfGroup(g)
            exitwhen a==null
            call GroupRemoveUnit(g,a)
           
            if UnitFilter(.caster,a) then
              set .active  =false
              set ax       =GetUnitX(a)
              set ay       =GetUnitY(a)
              set pd       =PushDatas.create()
              set pd.u     =a
              set pd.caster=.caster
              set t        =GetNextTimerInt(pd)

              call DestroyEffect(AddSpecialEffectTarget(targetMdl,a,targetAttach))
              call UnitDamageTarget(.caster,a,.dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
              call LaunchMissileAtPointEx(a,ax,ay,0.,pushZ,ax+pushDistance*Cos(.angle),ay+pushDistance*Sin(.angle),0.,pushDistance/pushTime*MotionDatabase_periodic)
              call TimerStart(t,pushTime,false,function PushEnd)
              call SetUnitPathing(a,false)
            endif
          endloop
         
          set .distance=.distance-speed
          set g=null
          set t=null
        else
          set .active=false
        endif
      endmethod
     
      method endmotion takes nothing returns nothing
          local timer t
          local real x =GetUnitX(.caster)
          local real y =GetUnitY(.caster)
         
          call IssueImmediateOrder(.caster,StopOrder)
          call DestroyBuffAfterTime(.caster,BuffId,2.)
          call DestroyEffect(.gfx)
     
          if .distance>0. and GetUnitState(.caster,UNIT_STATE_LIFE)>0. then
            set t=GetNextTimerAgent(.caster)
           
            call LaunchMissileAtPointEx(.caster,x,y,0.,backZ,x-backDistance*Cos(.angle),y-backDistance*Sin(.angle),0.,backDistance/backTime*MotionDatabase_periodic)
            call TimerStart(t,backTime,false,function BackEnd)
           
            set t=null
          else
            call SetUnitPathing(.caster,true)
            call DestroyEffect(AddSpecialEffect(exitMdl,x,y))
          endif
         
          set .caster   =null
          set .gfx      =null
          call .destroy()
      endmethod
     
      //! runtextmacro CostumMotion("BerserkerRushDatas","motion","endmotion","periodic")
   endstruct

  private function Berserker_Rush_Actions takes nothing returns nothing
      local BerserkerRushDatas dat=BerserkerRushDatas.create()
      local unit u                =GetTriggerUnit()
      local real ux               =GetUnitX(u)
      local real uy               =GetUnitY(u)
      local real tx               =GetSpellTargetX()
      local real ty               =GetSpellTargetY()
      local real distance         =D2PXY(ux,uy,tx,ty)
      local unit bx
     
      set dat.caster   =u
      set dat.distance =distance
      set dat.gfx      =AddSpecialEffectTarget(casterMdl,u,casterAttach)
      set dat.angle    =Atan2(ty-uy,tx-ux)
      set dat.dmg      =Damage(GetUnitAbilityLevel(u,SpellId))
     
      if (ux!=tx or uy!=ty) then
        set bx=CreateUnit(Player(14),DummyId,ux,uy,0)
        call UnitAddAbility(bx,BuffSpellCasterId)
        call IssueTargetOrder(bx,BuffSpellCasterOrder,u)
        call U2Null(bx,0.5)
        set bx=null
      endif
     
      call SetUnitPathing(u,false)
      call IssuePointOrder(u,RunOrder,tx,ty)

      call BerserkerRushDatas.addMotion(dat)
     
      set u         =null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0
    local unit upre

    set gg_trg_Berserk_Rage = CreateTrigger(  )
    set MaxArea = bj_mapInitialPlayableArea
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Berserk_Rage, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(gg_trg_Berserk_Rage, Condition( function Berserker_Rush_Conditions ) )
    call TriggerAddAction( gg_trg_Berserk_Rage, function Berserker_Rush_Actions )
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,BuffSpellCasterId)
    call UnitAddAbility(upre,BuffSpellId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(casterMdl)
    call Preload(targetMdl)
    call Preload(endMdl)
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Brain Soak by Darkt3mpl3r aka GiR- and coded by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope BrainSoak initializer init
  //===================================================================================================================
  //Constants
  globals
    private constant integer SpellId      ='A00U'  //Ability Rawcode: Brain Soak
    private constant integer BuffSpellId  ='A01C'  //Ability Rawcode: Brain Soak - Effect
    private constant integer DummyId      ='e000'  //Unit Rawcode: Dummy
    private constant real DamageDistance  =100.    //Distance till mana soak
    private constant string SoakMdl       ="Abilities\\Spells\\Undead\\OrbOfDeath\\OrbOfDeathMissile.mdl"//The soak effect model
    private constant string SoakMdlAttach ="chest" //The attach point of the SoakMdl
    private constant real periodic        =0.25    //The periodic time of the buff
   
    // This you shouldn't change
    private integer array BuffData[maxIndex]       //Important attached datas
  endglobals
 
  private constant function ManaPerDistance takes integer lvl returns real
    //Mana you loose after every reached distance
    return 2.*lvl
  endfunction
 
  private constant function BuffDuration takes integer lvl returns real
    //The duration of the buff
    return 5.+lvl
  endfunction
  //End Constants
  //===================================================================================================================
 
  //Conditions
  private function Brain_Soak_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SpellId
  endfunction
 
  //Actions
  private struct SoakDatas
    unit u
    real x
    real y
    real distance
    real mana
    real duration
    real time
 
    method check takes nothing returns nothing
      local real mx
      local real my
     
      set .time=.time+periodic
      set mx       =GetUnitX(.u)
      set my       =GetUnitY(.u)
      set .distance=.distance+D2PXY(.x,.y,mx,my)
       
      if .distance>DamageDistance then
        set .distance=0.
        call SetUnitState(.u,UNIT_STATE_MANA,RMaxBJ(0,GetUnitState(.u,UNIT_STATE_MANA)-.mana))
        call DestroyEffect(AddSpecialEffectTarget(SoakMdl,.u,SoakMdlAttach))
      endif
       
      set .x=mx
      set .y=my
     
      if not IsUnitNotBuffImmune(.u) or .time>.duration then
        call UnitRemoveAbility(.u,BuffSpellId)
        set .active=false
      endif
    endmethod
   
    method endcheck takes nothing returns nothing
      call ClearHandleIndex(.u)
      set .u=null
      call .destroy()
    endmethod
   
    //! runtextmacro CostumMotion("SoakDatas","check","endcheck","periodic")
  endstruct

  private function Brain_Soak_Actions takes nothing returns nothing
    local integer lvl =GetUnitAbilityLevel(GetTriggerUnit(),SpellId)
    local unit u      =GetSpellTargetUnit()
    local integer d
    local SoakDatas sd
   
    if GetUnitAbilityLevel(u,BuffSpellId)>0 then
      set d =GetHandleIndex(u)
      set sd=BuffData[d]
      call UnitRemoveAbility(sd.u,BuffSpellId)
    else
      call AddHandleIndex(u)
      set d =GetHandleIndex(u)
      set sd=SoakDatas.create()
    endif
   
    set sd.u       =u
    set sd.x       =GetUnitX(sd.u)
    set sd.y       =GetUnitY(sd.u)
    set sd.distance=0.
    set sd.mana    =GetUnitState(sd.u,UNIT_STATE_MAX_MANA)*ManaPerDistance(lvl)/100.
    set sd.duration=BuffDuration(lvl)
    set sd.time    =0.
   
    call UnitAddAbility(sd.u,BuffSpellId)
    call SetUnitAbilityLevel(sd.u,BuffSpellId,lvl)
   
    set BuffData[d]=sd
    call SoakDatas.addMotion(sd)
   
    set u=null
  endfunction

  //===========================================================================
  private function init takes nothing returns nothing
    local integer i=0
    local unit upre
 
    set gg_trg_Brain_Soak = CreateTrigger(  )
    loop
      call TriggerRegisterPlayerUnitEvent(gg_trg_Brain_Soak, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, MainFunctions_filter)

      set i=i+1
      exitwhen i==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_Brain_Soak, Condition( function Brain_Soak_Conditions ) )
    call TriggerAddAction( gg_trg_Brain_Soak, function Brain_Soak_Actions )
   
    //Preload Buffs
    set upre=CreateUnit(Player(14),DummyId,PreX,PreY,0)
    call UnitAddAbility(upre,BuffSpellId)
    call RemoveUnit(upre)
    set upre=null
   
    //Preload Models
    call Preload(SoakMdl)
  endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//Aggressive Infection by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

scope AggressiveInfection initializer init
  //===================================================================================================================
  //Constants
  globals
    private constant integer SpellId            ='A00S'  //Ability Rawcode: Aggressive Infection
    private constant integer BuffSpellId        ='A009'  //Ability Rawcode: Aggressive Infection - Effect
    private constant integer DummyId            ='e000'  //Unit Rawcode: Dummy
    private constant string InfectTargetFunction="AggressiveInfection_InfectTargetUnit"//The hit function (better you don't change this)
    private constant real ReducePerSplit        =25.     //Reduce amount of the damage after every split
    private constant real InfectSpeed           =10.     //The infection missile speed
    private constant real InfectZRate           =300.    //The rate how fast the missile will change his height
    private constant real InfectRange           =250.    //The infection range
    private constant string InfectMdl           ="Abilities\\Spells\\Undead\\PlagueCloud\\PlagueCloudCaster.mdl"//The missile model
    private constant string InfectMdlAtt        ="chest" //The attach point of InfectMdl
    private constant string DamageMdl           ="Objects\\Spawnmodels\\Undead\\UndeadBlood\\UndeadBloodCryptFiend.mdl"//The damage model
    private constant string DamageMdlAtt        ="origin"//The attach point of DamageMdl
    private constant real periodic              =0.25    //The periodic time of the buff
   
    // This you shouldn't change
    private integer array BuffData[maxIndex]             //Important attached datas
  endglobals
 
  private constant function MaximalInfections takes integer lvl returns integer
    //The maximal split number
    return lvl+2
  endfunction
 
  private constant function BuffDuration takes integer lvl returns real
    //The duration of the buff
    return 10.+5.*lvl
  endfunction
 
  private constant function Damage takes integer lvl returns real
    //The maximal start damage
    return 25.*lvl
  endfunction
 
  private function UnitFilter takes unit c,unit u returns boolean
    //The unit filter for the units who get damage
    if IsUnitEnemy(u,GetOwningPlayer(c)) then
    if GetUnitState(u,UNIT_STATE_LIFE)>0. then
    if GetUnitAbilityLevel(u,invulnerable_id)<=0 then
    if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==false then
    return IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
    endif
    endif
    endif
    endif
   
    return false
  endfunction
  //End Constants
  //===================================================================================================================
 
  //Conditions
  private function Aggressive_Infection_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SpellId
  endfunction
 
  //Actions
  private struct MissileData
    effect mdl
    integer max
    real dmg
  endstruct
 
  private struct InfectionDatas
    unit caster
    unit victim
   
    real dmg
    integer C_openInfections
    integer C_maxInfections
   
    real time
    real duration
 
    method check takes nothing returns nothing
      local group g
      local MissileData md
      local real x
      local real y
      local unit dummy
      local unit a
     
      if .C_openInfections<=.C_maxInfections then
        set g=GetUnitsInRange(InfectRange,GetUnitX(.victim),GetUnitY(.victim))
        call GroupRemoveUnit(g,.victim)
        loop
          set a=FirstOfGroup(g)
          exitwhen a==null or .C_openInfections>.C_maxInfections
          call GroupRemoveUnit(g,a)
       
          if UnitFilter(.caster,a) and GetUnitAbilityLevel(a,BuffSpellId)<=0 then
            set x     =GetUnitX(.victim)
            set y     =GetUnitY(.victim)
            set dummy =CreateUnit(Player(14),DummyId,x,y,0)
            set md    =MissileData.create()
            set md.max=.C_maxInfections+1
            set md.dmg=.dmg*ReducePerSplit/100.
            set md.mdl=AddSpecialEffectTarget(InfectMdl,dummy,InfectMdlAtt)
         
            call LaunchNormalChaseMissileAtPointEx(.caster,dummy,x,y,GetUnitDefaultFlyHeight(a),a,InfectSpeed,InfectZRate,InfectTargetFunction,md)
       
            set .C_openInfections=.C_openInfections+1
          endif