• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Divine Envoy Spellset Code

JASS:
////////////////////////////////////////////////////////////////////
//                   DIVINE ENVOY SPELLSET V1.00                  //                                                                //
//  Author: Tank-Commander                                        //
//  Requires: Dummy.mdl                                           //
//  Purpose: Combo Spell Set                                      //
//                                                                //
//  Notes:                                                        //
//    -  Read the readme before you try modifying the config      //
//    -  Use the "Helpful files" to help you import the spell     //
//                                                                //
//  Credits:                                                      //
//    -  (Dummy.mdl) Vexorian                                     //
//    -  (Orb Models) Frankster                                   //
//                                                                //
//                                                                //
//  If you have used this spellset in your map, you are required  //
//  to give credits to Tank-Commander for the creation of it      //
//  If you would like to use snippets of code from this for       //
//  whatever, getting permission and crediting the source/linking //
//  would be much appreciated.                                    //
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
//  README:                                                       //
//    Before modifying this spell a few things need to be         //
//    understood and read, this is one of those things, while     //
//    most modification can be considered intuitive, it still     //
//    helps to read through these intstructions, as they will     //
//    inform you about how to configure this spell to your        //
//    desire.                                                     //
//----------------------------------------------------------------//
//  Initial importing: The variable creator trigger can be        //
//  imported first and if you have the correct settings (file,    //
//  preferences, General, automatically create unknown variables  //
//  checked, then when you paste in the variable creator it       //
//  will automatically give you all the variables you need for    //
//  this spell                                                    //
//                                                                //
//  While the remaining object editor based data is not required  //
//  to function (provided they're replaced with equivelents)      //
//  it's recommended that they are also imported, if their data   //
//  value are not the same as listed in the configuration, those  //
//  configurables will need to be changed to work correctly       //
//----------------------------------------------------------------//
//  This configuration is divided up for each ability so that     //
//  it's easier to navigate for each individual ability, with     //
//  general functions in a seperate section the order:            //
//   - General                                                    //
//   - Orbs of Creation                                           //
//   - Orbs of Destruction                                        //
//   - Orbs of Justice                                            //
//   - Cycle of Life                                              //
//   - Equaliser                                                  //
//   - Trial by Fire                                              //
//   - Pillars of Judgement                                       //
//   - Wild Growth                                                //
//   - Armageddon                                                 //
//   - Countdown                                                  //
//   - Divine Envoy                                               //
//   - Loop control (Can be configured, but mostly read-only)     //
//----------------------------------------------------------------//
//  CONFIGURABLE INFORMATION/HELP:                                //
//                                                                //
//  - Viewing data values: To see data values in the editor you   //
//  need to press Ctrl + D, to shift back to normal viewing       //
//  press it again                                                //
//                                                                //
//  - Effects: Pathnames for effects used in the spells should    //
//  have two "\"s throughout or the effect will not work (the     //
//  WE progress bar will not go away when saving, however if      //
//  fixed afterwards the save will still work, but the progress   //
//  bar will still remain until the WE is closed)                 //
//  e.g. "units\\human\\Footman\\Footman"                         //
//                                                                //
//  - Effect Scaling: Some effects have scale values below them   //
//  the scale determines the size of the effect and is expressed  //
//  as a real percentage (1.00 = 100%)                            //
//                                                                //
//  - Removing Effects: to remove an effect you don't want from   //
//  the ability, set the model path to that of Dummy.mdl          //
//                                                                //
//  - Base and Per Values: Most configurables have a base and per //
//  value, Base values are what a value is set to regardless of   //
//  other factors. Per values are what a value is set to based on //
//  what the per value is the formula for calculating the result  //
//  is as follows:                                                //
//    - BaseValue + (Factor * PerValue)                           //
//                                                                //
//  - Factors: Per values all have factors, what the factor is,   //
//  is described in the configuration. Common factors are:        //
//    - Level: The level of the base ability                      //
//    - PowerLevel: The Stored power in an Orb                    //
//                                                                //
//  - Timer: Some configurables have PerSecond values, the code   //
//  automatically accounts for changes to the timer as to         //
//  maintain consistency with what the user has chosen            //
//  All times in the system are expressions of seconds            //
//                                                                //
//  - True or Incoming Speed: Most spells have this configurable  //
//  and it controls the form of movement used by the spell, if    //
//  it is set to true, then the True values in the configurables  //
//  will be used, if set to false then the Speed will be found    //
//  from the Incoming Time (the time to reach the target) and     //
//  the Timer speed, note that incoming times should not be       //
//  lower than the timer speed, and definitely not 0 (may cause   //
/// crashes)                                                      //
//                                                                //
//  - AttackTypes: This should match the Damage Type of the       //
//  ability, though it can be something else if you wish          //
//                                                                //
//  - DamageTypes: This changes the damage multiplyer vs. enemy   //
//  armour types, note that by default the damage filters         //
//  exclude magic immune units so changing this from MAGIC        //
//  damage will not make them take damage                         //
//                                                                //
//  - WeaponTypes: Generally don't need to be used, should only   //
//  not be null if you particularly wish or need to use them      //
//                                                                //
//  - Modifying StageIDs and TypeIDs in the loop control can      //
//  cause the system to stop functioning corretly, understanding  //
//  of the code is strongly recommended should you attempt to     //
//  change these                                                  //
//                                                                //
//----------------------------------------------------------------//
//                           GENERAL                              //
//----------------------------------------------------------------//
//  TimerSpeed: This is the rate in which the loop function runs  //
//  default value is 0.031250000, this value cannot be 0, for any //
//  other value the system automatically adjusts so that things   //
//  remain as normal, vals between 0.03 <-> 0.04 are recommended  //
constant function DES_TimerSpeed takes nothing returns real
    return 0.031250000
endfunction
//----------------------------------------------------------------//
//  DummyID: This is the data value of the unit that serves as    //
//  the dummy, it should have Dummy.mdl set to its model have     //
//  locust as its ability, movement type floar (or fly) and 0     //
//  pitch and roll angle for optimal use                          //
constant function DES_DummyID takes nothing returns integer
    return 'u000'
endfunction
//----------------------------------------------------------------//
//  TreantID: This is the data value of the unit that serves as   //
//  the treants for Wild Growth - all their stats are object      //
//  editor based and can be anything you wish                     //
constant function DES_TreantID takes nothing returns integer
    return 'efon'
endfunction
//----------------------------------------------------------------//
//  TreeCheckerID: This is the data value of the unit that is     //
//  used to scan for trees in the system (if DestroyTrees is      //
//  enabled) this unit should have the harvest ability            //
//  and dummy.mdl for its model (to make it invisible)            //
constant function DES_TreeCheckerID takes nothing returns integer
    return 'u001'
endfunction
//----------------------------------------------------------------//
//  CreationID: This is the data value of the ability used as     //
//  a base to cast Orbs of Creation from, it should be a          //
//  target point ability (AOE optional)                           //
constant function DES_CreationID takes nothing returns integer
    return 'A000'
endfunction
//----------------------------------------------------------------//
//  DestructionID: This is the data value of the ability used     //
//  as a base to cast Orbs of Destruction, it should be a         //
//  target point ability (AOE optional)                           //
constant function DES_DestructionID takes nothing returns integer
    return 'A001'
endfunction
//----------------------------------------------------------------//
//  JusticeID: This is the data value of the ability used as a    //
//  base to cast Orbs of Justice, it should be a target point     //
//  ability (AOE Optional, None for optimal)                      //      
constant function DES_JusticeID takes nothing returns integer
    return 'A002'
endfunction
//----------------------------------------------------------------//
//  PillarsID: This is the data value of the ability used as a    //
//  base to cast Pillars of Justice, it should be a target        //
//  point ability (AOE Optional)                                  //
constant function DES_PillarsID takes nothing returns integer
    return 'A003'
endfunction
//----------------------------------------------------------------//
//  SlowID: This is the data value of the ability used by Orbs    //
//  of Justice to slow nearby enemy units, it should be based     //
//  off Slow Aura (Tornado) with the same amount of levels as     //
//  Orbs of Justice (it can have an extra one if you intend the   //
//  ultimate to use a unique level of this ability)               //
constant function DES_SlowID takes nothing returns integer
    return 'A004'
endfunction
//----------------------------------------------------------------//
//  CountdownID: This is the data value of the ability used by    //
//  Countdown to mark units that are affected by it, which        //
//  targets both enemies and allies, it should be based off       //
//  Slow Aura (Tornado) but only needs 1 level as it's used       //
//  for creating the buff icon rather than any other effect       //
constant function DES_CountdownID takes nothing returns integer
    return 'A005'
endfunction
//----------------------------------------------------------------//
//  BurnID: This is the data value of the ability used by Trial   //
//  by Fire to mark units that are on Fire and taking damage      //
//  over time, it should be based off Slow Aura (Tornado) and     //
//  only needs 1 level, as it's used for creating the buff        //
//  icon rather than any other effect                             //
constant function DES_BurnID takes nothing returns integer
    return 'A006'
endfunction
//----------------------------------------------------------------//
//  TimedLifeID: This is the data value of the buff used to       //
//  mark units with timed lives, the only time this is            //
//  visible to players is on the Treants, hence use an            //
//  appropriate buff for the units that you summon via Wild       //
//  Growth, the default ID is the one for Force of Nature         //
constant function DES_TimedLifeID takes nothing returns integer
    return 'BEfn'
endfunction
//----------------------------------------------------------------//
//  LightningID: This is the data value of the lightning          //
//  effect used by Divine Envoy, no other ability uses it so      //
//  pick based on the effects you use for Divine Envoy            //
constant function DES_LightningID takes nothing returns string
    return "CLPB"
endfunction
//----------------------------------------------------------------//
//  LightningRed: This is the percentage (1.00 = 100%) of red     //
//  in the lightning effect picked in LightningID                 //
constant function DES_LightningRed takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  LightningGreen: This is the percentage (1.00 = 100%) of       //
//  green in the lightning effect picked in LightningID           //
constant function DES_LightningGreen takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  LightningBlue: This is the percentage (1.00 = 100%) of        //
//  blue in the lightning effect picked in LightningID            //
constant function DES_LightningBlue takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  LightningAlpha: This is the percentage of visibility or       //
//  transparity of the lightning effect (1.00 = 100%) with 0.00   //
//  being invisible                                               //
constant function DES_LightningAlpha takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  Gravity: This is the strength of gravity in the map, this     //
//  has an effect on the height projectiles reach depending on    //
//  their form of movement (incoming time trajectories will have  //
//  more shallow angles, as will true speed trajectories the      //
//  lower the gravity is, but the knockback from Divine Envoy     //
//  will have a higher trajectory, and vice Versa                 //
//  setting this to 0 will cause game crashes in certain          //
//  situations, they may also occur with particularly low values  //
constant function DES_Gravity takes nothing returns real
    return 4.12
endfunction
//----------------------------------------------------------------//
//  TerrainHeightMatters: Setting this value to true will cause   //
//  projectiles to take the terrain height of the ground beneath  //
//  them into account throughout their trajectories making arcs   //
//  smoother, however they may also hit the ground if terrain     //
//  obstructs their path which may result in the ability not      //
//  reaching the target area (if this is a persistent problem     //
//  increasing the strength of gravity can resolve this)          //
constant function DES_TerrainHeightMatters takes nothing returns boolean
    return true
endfunction
//----------------------------------------------------------------//
//  DestroyTrees: Setting this value to true will cause units     //
//  that are being pulled or knocked back to destroy trees        //
//  en-route, preventing them from getting stuck. Note: Units     //
//  may still be thrown into trees and get stuck if you use 3D    //
//  knockback with Divine Envoy                                   //
constant function DES_DestroyTrees takes nothing returns boolean
    return true
endfunction
//----------------------------------------------------------------//
//  TreeDestroyRadius: This is the area around units that will    //
//  be checked for trees that are obstructing, setting this       //
//  to a high value (x > 100) may result in lag when many units   //
//  are pulled into trees (for instance if Pillars of Judgement   //
//  is cast in the centre of many trees) due to the amount of     //
//  checks that must run in that scenario, may also occur with    //
//  knockback though is significantly less likely                 //
constant function DES_TreeDestroyRadius takes nothing returns real
    return 60.00
endfunction
//----------------------------------------------------------------//
//  Effect Expiration Timer: This is the duration which dead      //
//  Dummy units stick around for so that their death effects can  //
//  play, this mostly applies to Pillars of Judgement at the end  //
//  and other effects spawned like impact and combo effects       //
constant function DES_EffectExpirationTimer takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  DummyPlayer: This is the player that gains ownership of all   //
//  of the dummy units (primarily so that the spell does not      //
//  have an effect on the game scorescreen by filling it with     //
//  dummy stats) this should be one of the neutral players, the   //
//  default is neutral passive, however for neutral passive to    //
//  function correctly in maps the Gameplay constant "Creep       //
//  guard area" needs to be higherthan the maximum distance of    //
//  the abilities in your map, otherwise it should be set to a    //
//  player which is always present (e.g. a dummy computer player  //
//  or the player which has control of the units which can use    //
//  these abilities                                               //
constant function DES_DummyPlayer takes nothing returns player
    return Player(14)
endfunction
//----------------------------------------------------------------//
//  AttachmentPoint: This is the attachment point on the dummy    //
//  units which all effects are placed on, this can be anything   //
//  so long as it's a valid attachment point, try different ones  //
//  to find one you like                                          //
constant function DES_AttachmentPoint takes nothing returns string
    return "origin"
endfunction
//----------------------------------------------------------------//
//  ComboCollision: This is the distance between two orbs that    //
//  is necessary to trigger a combo, this should reflect the      //
//  general size of the orbs (this not per instance as both orbs  //
//  should be able to confirm the location of the other)          //
constant function DES_ComboCollision takes nothing returns real
    return 60.00
endfunction
//----------------------------------------------------------------//
//  GroundDrag: This is the percentage reduction per timer cycle  //
//  of units being knocked back, this value should not be over    //
//  (or equal to) 1.00, as this will cause the units to be        //
//  permanently pushed back                                       //
constant function DES_GroundDrag takes nothing returns real  
    return 0.95
endfunction
//----------------------------------------------------------------//
//  GroundDragStop: This is the speed units must be travelling    //
//  for the system to stop knocking them back, this can be any    //
//  value, but should not be 0.00 (though it may still work)      //
//  and setting this to negative values will cause units that     //
//  are knocked back to permanently by treated as being knocked   //
//  back, even if they physically aren't being knocked back       //
constant function DES_GroundDragStop takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  FallDamageMultiplyer: This is the bonus fall damage units     //
//  take as a percentage of their Z velocity upon hitting the     //
//  ground (units falling from a higher height, take more damage) //
//  (1.00 = 100%)                                                 //
constant function DES_FallDamageMultiplyer takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  FilterMaxZ: This is the highest height a unit can be at       //
//  while still qualifying for the target filters (this is so     //
//  you can make low-flyers specifically targetable will not      //
//  affecting high flyers, however Divine Envoy should not have   //
//  3D knockback if this value is above 0, also using negative    //
//  values will make all units untargetable                       //
constant function DES_FilterMaxZ takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  KnockbackEffect: This is the path of the effect used on       //
//  units that have been knocked back when they are in flight     //
constant function DES_KnockbackEffect takes nothing returns string
    return "Abilities\\Spells\\Other\\Tornado\\Tornado_Target.mdl"
endfunction
//----------------------------------------------------------------//
//  GroundHeightLet: This is the height at which the unit is      //
//  treated as being on the ground (its fly height wil be set to  //
//  0.                                                            //
constant function DES_GroundHeightLet takes nothing returns real
    return 0.
endfunction
//----------------------------------------------------------------//
//                       ORBS OF CREATION                         //
//----------------------------------------------------------------//
//  CPowerLevel: This is the amount of stored power in the Orbs   //
//  and increases all other ability stats                         //
constant function DES_CPowerLevelBase takes nothing returns real
    return 1.50
endfunction
//                                                                //
constant function DES_CPowerLevelPerLevel takes nothing returns real
    return 0.50
endfunction
//----------------------------------------------------------------//
//  COrbCount: This is the amount of Orbs created by the ability  //
constant function DES_COrbCountBase takes nothing returns integer
    return 0
endfunction
//                                                                //
constant function DES_COrbCountPerLevel takes nothing returns integer
    return 3
endfunction
//----------------------------------------------------------------//
//  COrbEffect: This is the effect used for the Orbs              //
constant function DES_COrbEffect takes nothing returns string
    return "war3mapImported\\OrbPoisonX.mdx"
endfunction
//----------------------------------------------------------------//
//  COrbScale: This is the size of the Orbs                       //
constant function DES_COrbScaleBase takes nothing returns real
    return 0.40
endfunction
//                                                                //
constant function DES_COrbScalePerPowerLevel takes nothing returns real
    return 0.20
endfunction
//----------------------------------------------------------------//
//  CDeathEffect: This is the effect played when the Orb dies     //
constant function DES_CDeathEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
endfunction
//----------------------------------------------------------------//
//  CImpactEffect: This is the effect played when the Orb hits    //
//  the terrain                                                   //
constant function DES_CImpactEffect takes nothing returns string
    return "Objects\\Spawnmodels\\NightElf\\NEDeathSmall\\NEDeathSmall.mdl"
endfunction
//----------------------------------------------------------------//
//  CImpactScale: This is the size of the impact effect           //
constant function DES_CImpactScaleBase takes nothing returns real
    return 0.20
endfunction
//                                                                //
constant function DES_CImpactScalePerPowerLevel takes nothing returns real
    return 0.20
endfunction
//----------------------------------------------------------------//
//  CMoveEffect: This is the effect attached to the Orb while     //
//  it is arcing                                                  //
constant function DES_CMoveEffect takes nothing returns string
    return "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
endfunction
//----------------------------------------------------------------//
//  CHealEffect: This is the effect attached to units which are   //
//  being passively healed                                        //
constant function DES_CHealEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\ResourceItems\\ResourceEffectTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  CImpactHealEffect: This is the effect attached to units       //
//  which are hit when the Orb lands                              //
constant function DES_CImpactHealEffect takes nothing returns string
    return "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
endfunction
//----------------------------------------------------------------//
//  CSpreadAOE: This is how far the Orbs are spread out from      //
//  eachother from the circle centre                              //
constant function DES_CSpreadAOEBase takes nothing returns real
    return 150.00
endfunction
//                                                                //
constant function DES_CSpreadAOEPerLevel takes nothing returns real
    return 15.00
endfunction
//----------------------------------------------------------------//
//  CImpactAOE: This is the area that is affected by the Orbs     //
//  when they land                                                //
constant function DES_CImpactAOEBase takes nothing returns real
    return 45.00
endfunction
//                                                                //
constant function DES_CImpactAOEPerPowerLevel takes nothing returns real
    return 20.00
endfunction
//----------------------------------------------------------------//
//  CPassiveHealAOE: This is the area that is affected by the     //
//  passive healing of the Orbs                                   //
constant function DES_CPassiveHealAOEBase takes nothing returns real
    return 45.00
endfunction
//                                                                //
constant function DES_CPassiveHealAOEPerPowerLevel takes nothing returns real
    return 20.00
endfunction
//----------------------------------------------------------------//
//  CImpactHealHealth: This is the amount of health restored to   //
//  units in the Impact area of the Orbs when they land           //
constant function DES_CImpactHealHealthBase takes nothing returns real
    return 10.00
endfunction
//                                                                //
constant function DES_CImpactHealHealthPerPowerLevel takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//  CImpactHealMana: This is the amount of mana restored to       //
//  units in the impact area of the Orbs when they land           //
constant function DES_CImpactHealManaBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_CImpactHealManaPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  CPassiveHealHealth: This is the amount of health restored to  //
//  units that are being passively healed by the Orbs             //
constant function DES_CPassiveHealHealthBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_CPassiveHealHealthPerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  CPassiveHealMana: This is the amount of mana restored to      //
//  units that are being passively healed by the Orbs             //
constant function DES_CPassiveHealManaBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_CPassiveHealManaPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  CTrueOrIncomingSpeed: This determines the form of movement    //
//  the Orbs use                                                  //
constant function DES_CTrueOrIncomingSpeed takes nothing returns boolean
    return false
endfunction
//----------------------------------------------------------------//
//  CTrueSpeed: This is the true speed value of the Obs           //
constant function DES_CTrueSpeedBase takes nothing returns real
    return 5.00
endfunction
//                                                                //
constant function DES_CTrueSpeedPerPowerLevel takes nothing returns real
    return 7.00
endfunction
//----------------------------------------------------------------//
//  CIncomingTime: This is the time it takes for the Orbs to land //
constant function DES_CIncomingTimeBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_CIncomingTimePerPowerLevel takes nothing returns real
    return -0.30
endfunction
//----------------------------------------------------------------//
//  CPassiveDelay: This is the time between passive healing       //
//  bursts from the Orbs                                          //
constant function DES_CPassiveDelayBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_CPassiveDelayPerPowerLevel takes nothing returns real
    return -0.075
endfunction
//----------------------------------------------------------------//
//  CTimedLife: This is how long the Orbs last after they have    //
//  landed on the terrain                                         //
constant function DES_CTimedLifeBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_CTimedLifePerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//                      ORBS OF DESTRUCTION                       //
//----------------------------------------------------------------//
//  DPowerLevel: This is the amount of stored power in the Orbs   //
//  and increases all other ability stats                         //
constant function DES_DPowerLevelBase takes nothing returns real
    return 1.50
endfunction
//                                                                //
constant function DES_DPowerLevelPerLevel takes nothing returns real
    return 0.50
endfunction
//----------------------------------------------------------------//
//  LargeDPowerLevelMultiplyer: This is the extra stored power    //
//  in the intial Destruction Orb as a multiplyer of the normal   //
//  Orb's stored power                                            //
constant function DES_LargeDPowerLevelMultiplyerBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_LargeDPowerLevelMultiplyerPerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  DOrbCount: This is the amount of Orbs created upon the large  //
//  Orb hitting the ground                                        //
constant function DES_DOrbCountBase takes nothing returns integer
    return 3
endfunction
//                                                                //
constant function DES_DOrbCountPerLevel takes nothing returns integer
    return 2
endfunction
//----------------------------------------------------------------//
//  DOrbEffect: This is the effect used as the model for the Orbs //
constant function DES_DOrbEffect takes nothing returns string
    return "war3mapImported\\OrbFireX.mdx"
endfunction
//----------------------------------------------------------------//
//  DOrbScale: This is the size of the Orbs                       //
constant function DES_DOrbScaleBase takes nothing returns real
    return 0.40
endfunction
//                                                                //
constant function DES_DOrbScalePerPowerLevel takes nothing returns real
    return 0.20
endfunction
//----------------------------------------------------------------//
//  DDeathEffect: This is the effect used when the Orb dies       //
constant function DES_DDeathEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
endfunction
//----------------------------------------------------------------//
//  DImpactEffect: This is the effect used when the Orbs hit the  //
//  terrain                                                       //
constant function DES_DImpactEffect takes nothing returns string
    return "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
endfunction
//----------------------------------------------------------------//
//  DImpactScale: This is the size of the effect used when the    //
//  Orbs hit the terrain                                          //
constant function DES_DImpactScaleBase takes nothing returns real
    return 0.40
endfunction
//                                                                //
constant function DES_DImpactScalePerPowerLevel takes nothing returns real
    return 0.10
endfunction
//----------------------------------------------------------------//
//  DMoveEffect: This is the effect attached to the Orbs when     //
//  they are in flight                                            //
constant function DES_DMoveEffect takes nothing returns string
    return "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
endfunction
//----------------------------------------------------------------//
//  DImpactDamageEffect: This is the effect attached to units     //
//  that are within the Impact Area of the Ors when they hit the  //
//  ground
constant function DES_DImpactDamageEffect takes nothing returns string
    return "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl"
endfunction
//----------------------------------------------------------------//
//  DDamageEffect: This is the effect attached to Units that are  //
//  being passively damaged by the Orbs                           //
constant function DES_DDamageEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl"
endfunction
//----------------------------------------------------------------//
//  DMinSpreadAOE: This is the minimum distance from the centre   //
//  of impact that all normal sized Orbs are aimed at             //
constant function DES_DMinSpreadAOE takes nothing returns real
    return 50.00
endfunction
//----------------------------------------------------------------//
//  DImpactAOE: This is the size of the area for which units take //
//  damage if they're in when the Orbs hit the ground             //
constant function DES_DImpactAOEBase takes nothing returns real
    return 45.00
endfunction
//                                                                //
constant function DES_DImpactAOEPerPowerLevel takes nothing returns real
    return 40.00
endfunction
//----------------------------------------------------------------//
//  DPassiveDamageAOE: this is the size of the area for which     //
//  units take passive damage from the Orbs if they are within    //
constant function DES_DPassiveDamageAOEBase takes nothing returns real
    return 45.00
endfunction
//                                                                //
constant function DES_DPassiveDamageAOEPerPowerLevel takes nothing returns real
    return 20.00
endfunction
//----------------------------------------------------------------//
//  DImpactDamageHealth: This is the amount of health damage      //
//  dealt to units within the Impact Area when the Orbs land      //
constant function DES_DImpactDamageHealthBase takes nothing returns real
    return 10.00
endfunction
//                                                                //
constant function DES_DImpactDamageHealthPerPowerLevel takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//  DImpactDamageMana: This is the amount of mana damage dealt    //
//  to units within the Impact Area when the Orbs land            //
constant function DES_DImpactDamageManaBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_DImpactDamageManaPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  DPassiveDamageHealth: This is the amount of health damage     //
//  dealt passively to enemies near the Orbs                      //
constant function DES_DPassiveDamageHealthBase takes nothing returns real
    return 5.00
endfunction
//                                                                //
constant function DES_DPassiveDamageHealthPerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  DPassiveDamageMana: This is the amount of mana damage dealt   //
//  passively to enemies near the Orbs                            //
constant function DES_DPassiveDamageManaBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_DPassiveDamageManaPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  DTrueOrIncomingSpeed: This determines what form of movement   //
//  type is used for the Orbs when they are in flight             //   
constant function DES_DTrueOrIncomingSpeed takes nothing returns boolean
    return true
endfunction
//----------------------------------------------------------------//
//  DTrueSpeed: Determines the true speed of the Orbs while they  //
//  are in flight                                                 //
constant function DES_DTrueSpeedBase takes nothing returns real
    return 5.00
endfunction
//                                                                //
constant function DES_DTrueSpeedPerPowerLevel takes nothing returns real
    return 3.00
endfunction
//----------------------------------------------------------------//
//  DIncomingTime: Determines how many seconds it takes for the   //
//  Orbs to land after being launched                             //
constant function DES_DIncomingTimeBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_DIncomingTimePerPowerLevel takes nothing returns real
    return -0.30
endfunction
//----------------------------------------------------------------//
//  DPassiveDelay: This is how many seconds there are between     //
//  bursts of damage from the Orbs                                //
constant function DES_DPassiveDelayBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_DPassiveDelayPerPowerLevel takes nothing returns real
    return -0.075
endfunction
//----------------------------------------------------------------//
//  DTimedLife: This is how long the Orbs last after they have    //
//  hit the terrain                                               //
constant function DES_DTimedLifeBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_DTimedLifePerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  DAttackType: This is the attack type used by all damage done  //
//  by the Orbs                                                   //
constant function DES_DAttackType takes nothing returns attacktype
    return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  DDamageType: This is the damage type used by all damage done  //
//  by the Orbs                                                   //
constant function DES_DDamageType takes nothing returns damagetype
    return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  DWeaponType: This is the weapon type used by all damage done  //
//  by the Orbs                                                   //
constant function DES_DWeaponType takes nothing returns weapontype
    return null
endfunction
//----------------------------------------------------------------//
//                        ORBS OF JUSTICE                         //
//----------------------------------------------------------------//
//  JPowerLevel: This is the amount of stored power in the Orbs   //
//  and increases all other ability stats                         //
constant function DES_JPowerLevelBase takes nothing returns real
    return 1.50
endfunction
//                                                                //
constant function DES_JPowerLevelPerLevel takes nothing returns real
    return 0.50
endfunction
//----------------------------------------------------------------//
//  JOrbCount: This is the amount of Orbs created by the ability  //
constant function DES_JOrbCountBase takes nothing returns integer
    return 0
endfunction
//                                                                //
constant function DES_JOrbCountPerLevel takes nothing returns integer
    return 3
endfunction
//----------------------------------------------------------------//
//  JOrbEffect: This is the effect used as the model for the Orbs //
constant function DES_JOrbEffect takes nothing returns string
    return "war3mapImported\\OrbDragonX.mdx"
endfunction
//----------------------------------------------------------------//
//  JOrbScale: This is the size of the Orbs                       //
constant function DES_JOrbScaleBase takes nothing returns real
    return 0.40
endfunction
//                                                                //
constant function DES_JOrbScalePerPowerLevel takes nothing returns real
    return 0.20
endfunction
//----------------------------------------------------------------//
//  JDeathEffect: This is the effect used when the Orbs dies      //
constant function DES_JDeathEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
endfunction
//----------------------------------------------------------------//
//  JDamageEffect: This is the effect used on units that have     //
//  taken damage from the Orbs                                    //
constant function DES_JDamageEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  JImpactScale: This is the size of the damage effect used      //
//  when units take damage from the Orbs                          //
constant function DES_JImpactScaleBase takes nothing returns real
    return 1.00
endfunction
//                                                                //
constant function DES_JImpactScalePerPowerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  JMoveEffect: This is the effect placed on the Orbs while they //
//  are moving                                                    //
constant function DES_JMoveEffect takes nothing returns string
    return "Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl"
endfunction
//----------------------------------------------------------------//
//  JSlowEffect: This is the effect placed on units which are     //
//  being slowed by the Orbs                                      // 
constant function DES_JSlowEffect takes nothing returns string
    return "Abilities\\Weapons\\ZigguratFrostMissile\\ZigguratFrostMissile.mdl"
endfunction
//----------------------------------------------------------------//
//  JAngleAreaBase: This is the angle (degrees) covered by the    //
//  Orbs when the ability is cast                                 //
constant function DES_JAngleAreaBase takes nothing returns real
    return 45.00
endfunction
//                                                                //
constant function DES_JAngleAreaPerLevel takes nothing returns real
    return 18.33
endfunction
//----------------------------------------------------------------//
// JDamageAOE: This is the area around the Orbs which damages     //
// units that the Orbs pass by                                    //
constant function DES_JDamageAOEBase takes nothing returns real  
    return 45.00
endfunction
//                                                                //
constant function DES_JDamageAOEPerPowerLevel takes nothing returns real
    return 20.00
endfunction
//----------------------------------------------------------------//
//  JDamageHealth: This is the amount of health damage dealt to   //
//  units the Orbs pass by                                        //
constant function DES_JDamageHealthBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_JDamageHealthPerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  JDamageMana: This is the amount of mana damage dealt to units //
//  the Orbs pass by                                              //
constant function DES_JDamageManaBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_JDamageManaPerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  JDamageManaburnRatio: This is the percentage of mana damage   //
//  that is converted to extra health damage by the Orbs          //
//  (1.00 = 100%)                                                 //
constant function DES_JDamageManaburnRatioBase takes nothing returns real
    return 0.50
endfunction
//                                                                //
constant function DES_JDamageManaburnRatioPerPowerLevel takes nothing returns real
    return 0.20
endfunction
//----------------------------------------------------------------//
//  JTrueOrIncomingSpeed: This is the type of movement used by    //
//  the Orbs when they are spreading out                          //
constant function DES_JTrueOrIncomingSpeed takes nothing returns boolean
    return false
endfunction
//----------------------------------------------------------------//
//  JTrueSpeed: Determines the true speed of the Orbs when they   //
//  are spreading out                                             //
constant function DES_JTrueSpeedBase takes nothing returns real
    return 5.00
endfunction
//                                                                //
constant function DES_JTrueSpeedPerPowerLevel takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//  JIncomingTime: Determines how long in seconds it takes for    //
//  the Orbs to spread out                                        //
constant function DES_JIncomingTimeBase takes nothing returns real
    return 1.50
endfunction
//                                                                //
constant function DES_JIncomingTimePerPowerLevel takes nothing returns real
    return -0.25
endfunction
//----------------------------------------------------------------//
//  JDamageDelay: This is the time in seconds between each burst  //
//  of damage dealt by the Orbs to units they pass by, works      //
//  best with true speed (incoming speed can result in units      //
//  being hit many times if they are in close range)              //
constant function DES_JDamageDelayBase takes nothing returns real
    return 0.30
endfunction
//                                                                //
constant function DES_JDamageDelayPerPowerLevel takes nothing returns real
    return -0.05
endfunction
//----------------------------------------------------------------//
//  JTimedLife: This is the duration of the Orbs after they have  //
//  have finished spreading out in seconds                        //
constant function DES_JTimedLifeBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_JTimedLifePerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  JAttackType: This is the attack type used by all damage done  //
//  by the Orbs                                                   //
constant function DES_JAttackType takes nothing returns attacktype
    return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  JDamageType: This is the damage type used by all damage done  //
//  by the Orbs                                                   //
constant function DES_JDamageType takes nothing returns damagetype
    return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  JWeaponType: This is the weapon type used by all damage done  //
//  by the Orbs                                                   //
constant function DES_JWeaponType takes nothing returns weapontype
    return null
endfunction
//----------------------------------------------------------------//
//                         CYCLE OF LIFE                          //
//----------------------------------------------------------------//
//  CycleActivateEffect: This is the effect played at the centre  //
//  of the combo ability                                          //
constant function DES_CycleActivateEffect takes nothing returns string
    return "Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  CycleActivateScale: This is the size of the effect played at  //
//  the centre of the combo ability                               //
constant function DES_CycleActivateScaleBase takes nothing returns real
    return 0.30
endfunction
//                                                                //
constant function DES_CycleActivateScalePerPowerLevel takes nothing returns real
    return 0.1
endfunction
//----------------------------------------------------------------//
//  CycleBoarderEffect: This is the effect played around the      //
//  edges of the combo ability                                    //
constant function DES_CycleBoarderEffect takes nothing returns string
    return "Units\\NightElf\\Wisp\\WispExplode.mdl"
endfunction
//----------------------------------------------------------------//
//  CycleBoarderScale: This is the size of the effect played      //
//  around the edges of the combo ability                         //
constant function DES_CycleBoarderScaleBase takes nothing returns real
    return 0.05
endfunction
//----------------------------------------------------------------//
constant function DES_CycleBoarderScalePerPowerLevel takes nothing returns real
    return 0.015
endfunction
//----------------------------------------------------------------//
//  CycleBoarderSpace: This is the amount of the circumference    //
//  used up by a single boarder entity                            //
constant function DES_CycleBoarderSpaceBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_CycleBoarderSpacePerPowerLevel takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//  CycleDamageEffect: This is the damage effect played on units  //
//  that take damage from the combo ability                       //
constant function DES_CycleDamageEffect takes nothing returns string
    return "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
endfunction
//----------------------------------------------------------------//
//  CycleHealEffect: This is the heal effect played on units      //
//  that are healed by the combo ability                          //
constant function DES_CycleHealEffect takes nothing returns string
    return "Abilities\\Spells\\Orc\\HealingWave\\HealingWaveTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  CycleAOE: This is the Area that is affected by the combo      //
//  ability                                                       //
constant function DES_CycleAOEBase takes nothing returns real
    return  50.00
endfunction
//                                                                //
constant function DES_CycleAOEPerPowerLevel takes nothing returns real
    return 25.00
endfunction
//----------------------------------------------------------------//
//  CycleDamageHealth: This is the amount of health damage dealt  //
//  to enemies affected by the combo ability                      //
constant function DES_CycleDamageHealthBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_CycleDamageHealthPerPowerLevel takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//  CycleDamageMana: This is the amount of mana damage dealt to   //
//  enemies affected by the combo ability                         //
constant function DES_CycleDamageManaBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_CycleDamageManaPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  CycleHealHealthRatio: This is the ratio of damage dealt to    //
//  enemies into health healed to allies (1.00 = 100%)            //
constant function DES_CycleHealHealthRatioBase takes nothing returns real
    return 0.05
endfunction
//                                                                //
constant function DES_CycleHealHealthRatioPerPowerLevel takes nothing returns real
    return 0.02
endfunction
//----------------------------------------------------------------//
//  CycleHealManaRatio: This is the ratio of damage deal to       //
//  enemies into Mana restored to allies (1.00 = 100%)            //
constant function DES_CycleHealManaRatioBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_CycleHealManaRatioPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  CycleAttackType: This is the attack type used by all damage   //
//  done by the combo ability                                     //
constant function DES_CycleAttackType takes nothing returns attacktype
    return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  CycleDamageType: This is the damage type used by all damage   //
//  done by the combo ability                                     //
constant function DES_CycleDamageType takes nothing returns damagetype
    return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  CycleWeaponType: This is the weapon type used by all damage   //
//  done by the combo ability                                     //
constant function DES_CycleWeaponType takes nothing returns weapontype
    return null
endfunction
//----------------------------------------------------------------//
//                           EQUALISER                            //
//----------------------------------------------------------------//
//  EqualActivateEffect: This is the effect played at the centre  //
//  of the combo ability                                          //
constant function DES_EqualActivateEffect takes nothing returns string
    return "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  EqualActivateScale: This is the size of the effect played at  //
//  the centre of the combo ability                               //
constant function DES_EqualActivateScaleBase takes nothing returns real
    return 0.50
endfunction
//                                                                //
constant function DES_EqualActivateScalePerPowerLevel takes nothing returns real
    return 0.0075
endfunction
//----------------------------------------------------------------//
//  EqualBoarderEffect: This is the effect played around the      //
//  edges of the combo ability                                    //
constant function DES_EqualBoarderEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  EqualBoarderScale: This is the size of the effect played      //
//  around the edges of the combo ability                         //
constant function DES_EqualBoarderScaleBase takes nothing returns real
    return 0.20
endfunction
//                                                                //
constant function DES_EqualBoarderScalePerPowerLevel takes nothing returns real
    return 0.015
endfunction
//----------------------------------------------------------------//
//  EqualBoarderSpace: This is the amount of the circumference    //
//  used up by a single boarder entity                            //
constant function DES_EqualBoarderSpaceBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_EqualBoarderSpacePerPowerLevel takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//  EqualAlterEffect: This is the effect played on units which    //
//  have their health altered by the combo ability
constant function DES_EqualAlterEffect takes nothing returns string
    return "Abilities\\Spells\\Human\\Invisibility\\InvisibilityTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  EqualAOE: This is the Area that is affected by the combo      //
//  ability                                                       //
constant function DES_EqualAOEBase takes nothing returns real
    return 50.00
endfunction
//                                                                //
constant function DES_EqualAOEPerPowerLevel takes nothing returns real
    return 25.00
endfunction
//----------------------------------------------------------------//
//  EqualManaCost: This is the amount of mana drained from units  //
//  that are affected by the combo ability                        //
constant function DES_EqualManaCostBase takes nothing returns real
    return 10.00
endfunction
//                                                                //
constant function DES_EqualManaCostPerPowerLevel takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//                         TRIAL BY FIRE                          //
//----------------------------------------------------------------//
//  TrialActivateEffect: This is the effect played at the centre  //
//  of the combo ability                                          //
constant function DES_TrialActivateEffect takes nothing returns string
    return "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
endfunction
//----------------------------------------------------------------//
//  TrialActivateScale: This is the size of the effect played at  //
//  the centre of the combo ability                               //
constant function DES_TrialActivateScaleBase takes nothing returns real
    return 0.20
endfunction
//                                                                //
constant function DES_TrialActivateScalePerPowerLevel takes nothing returns real
    return 0.10
endfunction
//----------------------------------------------------------------//
//  TrialBoarderEffect: This is the effect played around the      //
//  edges of the combo ability                                    //
constant function DES_TrialBoarderEffect takes nothing returns string
    return "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
endfunction
//----------------------------------------------------------------//
//  TrialBoarderScale: This is the size of the effect played      //
//  around the edges of the combo ability                         //
constant function DES_TrialBoarderScaleBase takes nothing returns real
    return 0.10
endfunction
//                                                                //
constant function DES_TrialBoarderScalePerPowerLevel takes nothing returns real
    return 0.015
endfunction
//----------------------------------------------------------------//
//  TrialBoarderSpace: This is the amount of the circumference    //
//  used up by a single boarder entity                            //
constant function DES_TrialBoarderSpaceBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_TrialBoarderSpacePerPowerLevel takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//  TrialDamageEffect: This is the effect played on units that    //
//  are set on fire by the combo ability                          //
constant function DES_TrialDamageEffect takes nothing returns string
    return "Abilities\\Spells\\Other\\Incinerate\\IncinerateBuff.mdl"
endfunction
//----------------------------------------------------------------//
//  TrialBurnEffect: This is the effect played on units that are  //
//  currently on fire                                             //
constant function DES_TrialBurnEffect takes nothing returns string
    return "Environment\\LargeBuildingFire\\LargeBuildingFire2.mdl"
endfunction
//----------------------------------------------------------------//
//  TrialExplodeEffect: This is the effect played on units that   //
//  died while on fire                                            //
constant function DES_TrialExplodeEffect takes nothing returns string
    return "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl"
endfunction
//----------------------------------------------------------------//
//  TrialAOE: This is the Area that is affected by the combo      //
//  ability                                                       //
constant function DES_TrialAOEBase takes nothing returns real
    return 50.00
endfunction
//                                                                //
constant function DES_TrialAOEPerPowerLevel takes nothing returns real
    return 25.00
endfunction
//----------------------------------------------------------------//
//  TrialExplosionAOE: This is the Area that is affected by units //
//  which die while on fire                                       //
constant function DES_TrialExplosionAOEBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_TrialExplosionAOEPerPowerLevel takes nothing returns real
    return 10.00
endfunction
//----------------------------------------------------------------//
//  TrialDamageHealth: This is the amount of health damage dealt  //
//  to units that are set on fire                                 //
constant function DES_TrialDamageHealthBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_TrialDamageHealthPerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  TrialDamageMana: This is the amount of mana damage dealt to   //
//  units that are set on fire                                    //
constant function DES_TrialDamageManaBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_TrialDamageManaPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  TrialExplosionHealthDamage: This is the amount of health      //
//  damage dealt to units near a unit that died while on fire     //
constant function DES_TrialExplosionHealthDamageBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_TrialExplosionHealthDamagePerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  TrialExplosionManaDamage: This is the amount of mana damage   //
//  dealt to units near a unit that died while on fire            //
constant function DES_TrialExplosionManaDamageBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_TrialExplosionManaDamagePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  TrialBurnHealthDamage: This is the amount of health damage    //
//  dealt to units that are currently on fire                     //
constant function DES_TrialBurnHealthDamageBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_TrialBurnHealthDamagePerPowerLevel takes nothing returns real
    return 0.5
endfunction
//----------------------------------------------------------------//
//  TrialBurnManaDamage: This is the amount of mana damage dealt  //
//  to units that are currently on fire                           //
constant function DES_TrialBurnManaDamageBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_TrialBurnManaDamagePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  TrialDamageDelay: This is the time in seconds between bursts  //
//  of damage to units that are on fire                           //
constant function DES_TrialDamageDelayBase takes nothing returns real
    return 0.50
endfunction
//                                                                //
constant function DES_TrialDamageDelayPerPowerLevel takes nothing returns real 
    return 0.00
endfunction
//----------------------------------------------------------------//
//  TrialBurnDuration: This is the amount of time that units are  //
//  on fire for                                                   //
constant function DES_TrialBurnDurationBase takes nothing returns real
    return 1.00
endfunction
//                                                                //
constant function DES_TrialBurnDurationPerPowerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  TrialAttackType: This is the attack type used by all damage   //
//  done by the combo ability                                     //
constant function DES_TrialAttackType takes nothing returns attacktype
    return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  TrialDamageType: This is the damage type used by all damage   //
//  done by the combo ability                                     //
constant function DES_TrialDamageType takes nothing returns damagetype
    return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  TrialWeaponType: This is the weapon type used by all damage   //
//  done by the combo ability                                     //
constant function DES_TrialWeaponType takes nothing returns weapontype
    return null
endfunction
//----------------------------------------------------------------//
//                      PILLARS OF JUDGEMENT                      //
//----------------------------------------------------------------//
//  PPowerForOrb: This is the amount of power required to have    //
//  been gathered from a type of Orb to add an Orb onto the stack //
constant function DES_PPowerForOrbBase takes nothing returns real
    return 7.00
endfunction
//                                                                //
constant function DES_PPowerForOrbPerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PCreationStartingPower: This is the amount of Power starting  //
//  on the Orb of Creation stack                                  //
constant function DES_PCreationStartingPowerBase takes nothing returns real
    return 21.00
endfunction
//                                                                //
constant function DES_PCreationStartingPowerPerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDestructionStartingPower: This is the amount of Power        //
//  starting on the Orb of Destruction stack                      //
constant function DES_PDestructionStartingPowerBase takes nothing returns real
    return 21.00
endfunction
//                                                                //
constant function DES_PDestructionStartingPowerPerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PJusticeStartingPower: This is the amount of Power starting   //
//  on the Orb of Justice stack                                   //
constant function DES_PJusticeStartingPowerBase takes nothing returns real   
    return 21.00
endfunction
//                                                                //
constant function DES_PJusticeStartingPowerPerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PSmallOrbSizeLimiter: This is the divider used to make the    //
//  orbs smaller treating their size as if their power level was  //
//  1/5 of what it actually is when determining their size        //
constant function DES_PSmallOrbSizeLimiter takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//  POrbEffect: This is the Effect used as the central Orb        //
constant function DES_POrbEffect takes nothing returns string
    return "Abilities\\Weapons\\WitchDoctorMissile\\WitchDoctorMissile.mdl"
endfunction
//----------------------------------------------------------------//
//  POrbScale: This is the size of the central Orb                //
constant function DES_POrbScaleBase takes nothing returns real
    return 3.00
endfunction
//                                                                //
constant function DES_POrbScalePerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  PBoarderEffect: This is the effect placed around the central  //
//  Orb                                                           //
constant function DES_PBoarderEffect takes nothing returns string
    return "Abilities\\Spells\\NightElf\\SpiritOfVengeance\\SpiritOfVengeanceOrbs1.mdl"
endfunction
//----------------------------------------------------------------//
//  PBoarderScale: This is the size of the effect placed around   //
//  the central Orb                                               //
constant function DES_PBoarderScaleBase takes nothing returns real
    return 7.00
endfunction
//                                                                //
constant function DES_PBoarderScalePerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  PBoarderCount: This is the amount of effected placed around   //
//  the central Orb                                               //
constant function DES_PBoarderCountBase takes nothing returns integer
    return 8
endfunction
//                                                                //
constant function DES_PBoarderCountPerLevel takes nothing returns integer
    return 0
endfunction
//----------------------------------------------------------------//
//  PSpawnEffect: This is the effect created when the ability     //
//  starts                                                        //
constant function DES_PSpawnEffect takes nothing returns string
    return "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  PPullEffect: This is the effect put on units that are being   //
//  pulled into the centre                                        //
constant function DES_PPullEffect takes nothing returns string
    return "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl"
endfunction
//----------------------------------------------------------------//
//  PPullEffectDelay: This is the time in seconds between the     //
//  pulling effect being renewed on units that are being pulled   //
constant function DES_PPullEffectDelayBase takes nothing returns real
    return 1.00
endfunction
//                                                                //
constant function DES_PPullEffectDelayPerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PAbsorbEffect: This is the effect played on Orbs that are     //
//  being absorbed into the stack                                 //
constant function DES_PAbsorbEffect takes nothing returns string
    return "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  PDeathEffect: This is the death effect of the Central Orb     //
//  and its associated parts                                      //
constant function DES_PDeathEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
endfunction
//----------------------------------------------------------------//
//  POrbHeightOffset: This is the height off the ground the       //
//  central Orb is placed at                                      //
constant function DES_POrbHeightOffsetBase takes nothing returns real
    return 200.00
endfunction
//                                                                //
constant function DES_POrbHeightOffsetPerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PBoarderHeightOffsetAlter: This the height of the boarder in  //
//  relation to the height of the central Orb                     //
constant function DES_PBoarderHeightOffsetAlterBase takes nothing returns real
    return -50.
endfunction
//                                                                //
constant function DES_PBoarderHeightOffsetAlterPerLevel takes nothing returns real
    return 0.
endfunction
//----------------------------------------------------------------//
//  PBoarderOffset: This is the distance from the centre of the   //
//  ability that the boarder effects are placed at                //
constant function DES_PBoarderOffsetBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PBoarderOffsetPerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PSmallOrbAngleOffset: This is the angle offset between each   //
//  Pillar or Stack                                               //
constant function DES_PSmallOrbAngleOffset takes nothing returns real
    return 120.
endfunction
//----------------------------------------------------------------//
//  PSmallOrbOffset: This is the distance from the centre of the  //
//  ability to each of the stacks                                 //
constant function DES_PSmallOrbOffsetBase takes nothing returns real
    return 150.00
endfunction
//                                                                //
constant function DES_PSmallOrbOffsetPerLevel takes nothing returns real
    return 50.00
endfunction
//----------------------------------------------------------------//
//  PSmallOrbHeightOffset: This is the height distance between    //
//  each of the small orbs on the stacks                          //
constant function DES_PSmallOrbsHeightOffsetBase takes nothing returns real
    return 50.00
endfunction
//                                                                //
constant function DES_PSmallOrbsHeightOffsetPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PSpinTrueOrIncomingSpeed: This is the form of movement used   //
//  by the stacks as they revolve around the central Orb          //
constant function DES_PSpinTrueOrIncomingSpeed takes nothing returns boolean
    return false
endfunction
//----------------------------------------------------------------//
//  POrbTruSpinSpeed: Determines the Speed of which the stacks    //
//  spin around the central Orb                                   //
constant function DES_POrbTrueSpinSpeedBase takes nothing returns real
    return 0.50
endfunction
//                                                                //
constant function DES_POrbTrueSpinSpeedPerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  POrbSpinIncomingTime: Determines how many seconds it takes    //
//  for the stacks to complete 1 full revolution around the       //
//  central Orb                                                   //
constant function DES_POrbSpinIncomingTimeBase takes nothing returns real
    return 3.00
endfunction
//                                                                //
constant function DES_POrbSpinIncomingTimePerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PPullAOE: This is the Area in which units and Orbs within     //
//  pulled into the central Orb                                   //
constant function DES_PPullAOEBase takes nothing returns real
    return 600.00
endfunction
//                                                                //
constant function DES_PPullAOEPerLevel takes nothing returns real
    return 50.00
endfunction
//----------------------------------------------------------------//
//  PPullStrength: This is how strongly the units and Orbs are    //
//  pulled into the central Orb                                   //
constant function DES_PPullStrengthBase takes nothing returns real
    return 140.00
endfunction
//                                                                //
constant function DES_PPullStrengthPerLevel takes nothing returns real
    return 10.00
endfunction
//----------------------------------------------------------------//
//  PPullDurationBase: This is how long the ultimate will pull    //
//  in units and Orbs in seconds, before it calculates the        //
//  resulting effect                                              //
constant function DES_PPullDurationBase takes nothing returns real
    return 9.00
endfunction
//                                                                //
constant function DES_PPullDurationPerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  PSlowLevel: This is the level of the slow effect the          //
//  ultimate uses for the Orbs of Justice                         //
constant function DES_PSlowLevel takes nothing returns integer
    return 3
endfunction
//----------------------------------------------------------------//
//  PAttackType: This is the attack type used by all damage       //
//  done by the Ultimate                                          //
constant function DES_PAttackType takes nothing returns attacktype
    return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  PDamageType: This is the damage type used by all damage       //
//  done by the Ultimate                                          //
constant function DES_PDamageType takes nothing returns damagetype
    return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  PWeaponType: This is the weapon type used by all damage       //
//  done by the Ultimate                                          //
constant function DES_PWeaponType takes nothing returns weapontype
    return null
endfunction
//----------------------------------------------------------------//
//                          WILD GROWTH                           //
//----------------------------------------------------------------//
//  PWildSpawnEffect: This is the effect played on the units      //
//  that are created by Wild Growth                               //
constant function DES_PWildSpawnEffect takes nothing returns string
    return "Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  PWildStartAOE: This is the distance away from the centre      //
//  that the first units are spawned                              //
constant function DES_PWildStartAOEBase takes nothing returns real
    return 50.00
endfunction
//                                                                //
constant function DES_PWildStartAOEPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PWildAOE: This is the distance away from the centre that      //
//  the last units are spawned                                    //
constant function DES_PWildAOEBase takes nothing returns real
    return 150.00
endfunction
//                                                                //
constant function DES_PWildAOEPerPowerLevel takes nothing returns real
    return 15.00
endfunction
//----------------------------------------------------------------//
//  PWildTreantCountPerRing: This is the amount of units that     //
//  are spawned in each circle around the ultimate                //
constant function DES_PWildTreantCountPerRingBase takes nothing returns real
    return 3.00
endfunction
//                                                                //
constant function DES_PWildTreantCountPerRingPerPowerLevel takes nothing returns real
    return 0.10
endfunction
//----------------------------------------------------------------//
//  PWildExpandRingCount: This is the amount of rings created     //
//  by Wild Growth                                                //
constant function DES_PWildExpandRingCountBase takes nothing returns real
    return 3.00
endfunction
//                                                                //
constant function DES_PWildExpandRingCountPerPowerLevel takes nothing returns real
    return 0.10
endfunction
//----------------------------------------------------------------//
//  PWildTreantSpawnDelay: This is the time between each ring     //
//  being made in seconds                                         //
constant function DES_PWildTreantSpawnDelayBase takes nothing returns real
    return 0.50
endfunction
//                                                                //
constant function DES_PWildTreantSpawnDelayPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PWildTreantDuration: This is the amount of time in seconds    //
//  the units that are created last                               //
constant function DES_PWildTreantDurationBase takes nothing returns real
    return 10.00
endfunction
//                                                                //
constant  function  DES_PWildTreantDurationPerPowerLevel takes nothing returns real
    return 0.1
endfunction
//----------------------------------------------------------------//
//                          ARMAGEDDON                            //
//----------------------------------------------------------------//
//  PArmaProjecitleEffect: This is the effect used as the model   //
//  for the Armageddon projectiles                                //
constant function DES_PArmaProjectileEffect takes nothing returns string
    return "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl"
endfunction
//----------------------------------------------------------------//
//  PArmaProjectileScale: This is the size of the projectiles     //
constant function DES_PArmaProjectileScale takes nothing returns real
    return 1.50
endfunction
//----------------------------------------------------------------//
//  PArmaProjectileMoveEffect: This is the effect attached to     //
//  the projectiles while they are in flight                      //
constant function DES_PArmaProjectileMoveEffect takes nothing returns string
    return "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
endfunction
//----------------------------------------------------------------//
//  PArmaImpactEffect: This is the effect created when the        //
//  projectiles come into contact with the ground                 //
constant function DES_PArmaImpactEffect takes nothing returns string
    return "war3mapImported\\dummy.mdl"
endfunction
//----------------------------------------------------------------//
//  PArmaDamageEffect: This is the effect put on units which      //
//  take damage as the result of being hit by a projectile        //
constant function DES_PArmaDamageEffect takes nothing returns string
    return "war3mapImported\\dummy.mdl"
endfunction
//----------------------------------------------------------------//
//  PArmaProjectilesPerSecond: This is the amount of projectiles  //
//  created per second by the ultimate                            //
constant function DES_PArmaProjectilesPerSecondBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_PArmaProjectilesPerSecondPerPowerLevel takes nothing returns real
    return 0.10
endfunction
//----------------------------------------------------------------//
//  PArmaAOE: This is the area in which Projectiles will be       //
//  launched at, around the central Orb of the ultimate           //
constant function DES_PArmaAOEBase takes nothing returns real
    return 100.00
endfunction
//                                                                //
constant function DES_PArmaAOEPerPowerLevel takes nothing returns real
    return 10.00
endfunction
//----------------------------------------------------------------//
//  PArmaMinAOE: This is the minimum distance away from the       //
//  central Orb that projectiles will be launched at              //
constant function DES_PArmaMinAOE takes nothing returns real
    return 100.00
endfunction
//----------------------------------------------------------------//
//  PArmaProjectileAOE: This is the area in which units within    //
//  take damage from the Ultimate                                 //
constant function DES_PArmaProjectileAOEBase takes nothing returns real
    return 40.00
endfunction
//                                                                //
constant function DES_PArmaProjectileAOEPerPowerLevel takes nothing returns real
    return 2.50
endfunction
//----------------------------------------------------------------//
//  PArmaProjectileHealthDamage: This is the amount of health     //
//  damage each projectile deals to enemy units                   //
constant function DES_PArmaProjectileHealthDamageBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_PArmaProjectileHealthDamagePerPowerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  PArmaProjectileManaDamage: This is the amount of mana damage  //
//  each projectile deals to enemy units                          //
constant function DES_PArmaProjectileManaDamageBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PArmaProjectileManaDamagePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PArmaTrueOrIncomingSpeed: This is the type of movement used   //
//  by the projectiles of the ultimate                            //
constant function DES_PArmaTrueOrIncomingSpeed takes nothing returns boolean
    return false
endfunction
//----------------------------------------------------------------//
//  PArmaTrueSpeed: Determines the speed of the projectiles       //
constant function DES_PArmaTrueSpeedBase takes nothing returns real
    return 3.00
endfunction
//                                                                //
constant function DES_PArmaTrueSpeedPerPowerLevel takes nothing returns real
    return 0.10
endfunction
//----------------------------------------------------------------//
//  PArmaIncomingTimeBase: Determines how long in seconds it      //
//  takes for a projectile to hit the ground                      //
constant function DES_PArmaIncomingTimeBase takes nothing returns real
    return 1.00
endfunction
//                                                                //
constant function DES_PArmaIncomingTimePerPowerLevel takes nothing returns real
    return -0.01
endfunction
//----------------------------------------------------------------//
//  PArmaLaunchDelay: This is how long in seconds is inbetween    //
//  a launch of a new projectile from the ultimate                //
constant function DES_PArmaLaunchDelayBase takes nothing returns real
    return 0.06
endfunction
//                                                                //
constant function DES_PArmaLaunchDelayPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PArmaDuration: This is how long in seconds the ultimate runs  //
//  for                                                           //
constant function DES_PArmaDurationBase takes nothing returns real
    return 5.00
endfunction
//                                                                //
constant function DES_PArmaDurationPerPowerLevel takes nothing returns real
    return 0.10
endfunction
//----------------------------------------------------------------//
//                          COUNTDOWN                             //
//----------------------------------------------------------------//
//  PCountEffect: This is the effect placed on units that are     //
//  under the buff effect of Countdown                            //
constant function DES_PCountEffect takes nothing returns string
    return "Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  PCountDamageEffect: This is the effect played on units that   //
//  are damaged by the ability                                    //
constant function DES_PCountDamageEffect takes nothing returns string
    return "Objects\\Spawnmodels\\Undead\\UndeadDissipate\\UndeadDissipate.mdl"
endfunction
//----------------------------------------------------------------//
//  PCountHealEffect: This is the effect played on units that     //
//  are healed by the ability                                     //
constant function DES_PCountHealEffect takes nothing returns string
    return "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
endfunction
//----------------------------------------------------------------//
//  PCountAOE: This is the area in which units within are given   //
//  the countdown buff                                            //
constant function DES_PCountAOEBase takes nothing returns real
    return 150.00
endfunction
//                                                                //
constant function DES_PCountAOEPerPowerLevel takes nothing returns real
    return 5.00
endfunction
//----------------------------------------------------------------//
//  PCountHealthDamage: This is the amount of health damage       //
//  dealt to units after the countdown ends                       //
constant function DES_PCountHealthDamageBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_PCountHealthDamagePerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  PCountHealthHeal: This is the amount of health healed on      //
//  units after the countdown ends                                //
constant function DES_PCountHealthHealBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_PCountHealthHealPerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  PCountManaDamae: This is the amount of mana damage dealt to   //
//  units after the countdown ends                                //
constant function DES_PCountManaDamageBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_PCountManaDamagePerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  PCountManaHeal: This is the amount of mana restored to units  //
//  after the countdown ends                                      //
constant function DES_PCountManaHealBase takes nothing returns real
    return 20.00
endfunction
//                                                                //
constant function DES_PCountManaHealPerPowerLevel takes nothing returns real
    return 2.00
endfunction
//----------------------------------------------------------------//
//  PCountTimer: This is the time it takes in seconds for the     //
//  countdown to end                                              //
constant function DES_PCountTimerBase takes nothing returns real
    return 10.00
endfunction
//                                                                //
constant function DES_PCountTimerPerPowerLevel takes nothing returns real
    return -0.10
endfunction
//----------------------------------------------------------------//
//                         DIVINE ENVOY                           //
//----------------------------------------------------------------//
//  PDivineStormStrike: This is the effect created on the ground  //
//  when a lightning bolt strikes it                              //
constant function DES_PDivineStormStrikeEffect takes nothing returns string
    return "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  PDivineStormStrikeScale: This is the size of the effect       //
//  created on the ground when a lightning bolt strikes it        //
constant function DES_PDivineStormStrikeScaleBase takes nothing returns real
    return 0.30
endfunction
//                                                                //
constant function DES_PDivineStormStrikeScalePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormDamageEffect: This is the effect created when     //
//  enemies units are struck by a lightning effect                //
constant function DES_PDivineStormDamageEffect takes nothing returns string
    return "Abilities\\Spells\\Human\\Feedback\\ArcaneTowerAttack.mdl"
endfunction
//----------------------------------------------------------------//
//  PDivineStormHealEffect: This is the effect created when       //
//  allied units are struck by a lightning effect                 // 
constant function DES_PDivineStormHealEffect takes nothing returns string
    return "Abilities\\Spells\\Undead\\ReplenishMana\\SpiritTouchTarget.mdl"
endfunction
//----------------------------------------------------------------//
//  PDivineLaserEffect: This is the effect used for the laser at  //
//  end of the ultimate                                           //
constant function DES_PDivineLaserEffect takes nothing returns string
    return "Abilities\\Spells\\Other\\Awaken\\Awaken.mdl"
endfunction
//----------------------------------------------------------------//
//  PDivineLaserStartScale: This is the size of the laser effect  //
//  when it is initially created                                 //
constant function DES_PDivineLaserStartScaleBase takes nothing returns real
    return 0.01
endfunction
//                                                                //
constant function DES_PDivineLaserStartScalePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineLaserEndScale: This is the final size of the laser     //
//  effect when it'ends                                           //
constant function DES_PDivineLaserEndScaleBase takes nothing returns real
    return 4.00
endfunction
//                                                                //
constant function DES_PDivineLaserEndScalePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineLaserDamagEffect: This is the effect played on units   //
//  that have taken damage from the laser                         //
constant function DES_PDivineLaserDamageEffect takes nothing returns string
    return "war3mapImported\\dummy.mdl"
endfunction
//----------------------------------------------------------------//
//  PDivineLaserHealEffect: This is the effect played on units    //
//  that have been healed by the laser                            //
constant function DES_PDivineLaserHealEffect takes nothing returns string
    return "war3mapImported\\dummy.mdl"
endfunction
//----------------------------------------------------------------//
//  PDivineSmallOrbsOffsetIncrease: This is how much the stacks   //
//  move away from the Central Orb on top of their intiial        //
//  distance when Divine Envoy starts                             //
constant function DES_PDivineSmallOrbsOffsetIncreaseBase takes nothing returns real
    return 90.00
endfunction
//                                                                //
constant function DES_PDivineSmallOrbsOffsetIncreasePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineHeightIncrease: This is the heght increase of the      //
//  central Orb that it gains when Divine Envoy starts            //
constant function DES_PDivineHeightIncreaseBase takes nothing returns real
    return 300.00
endfunction
//                                                                //
constant function DES_PDivineHeightIncreasePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormLightningOffset: This is how far from the central //
//  Orb lightnings effects can spawn                              //
constant function DES_PDivineStormLightningOffset takes nothing returns real
    return 180.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormAmountPerSecond; This is the amount of lightning  //
//  strikes that occur per second during the storm stage          //
constant function DES_PDivineStormAmountPerSecondBase takes nothing returns real
    return 10.00
endfunction
//                                                                //
constant function DES_PDivineStormAmountPerSecondPerPowerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormAOE: This is the Area in which Lightning effects  //
//  can spawn during the storm stage                              //
constant function DES_PDivineStormAOEBase takes nothing returns real
    return 400.00
endfunction
//                                                                //
constant function DES_PDivineStormAOEPerPowerLevel takes nothing returns real
    return 3.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormStrikeAOE: This is the area in which units within //
//  are affeced by the Lightning effects                          //
constant function DES_PDivineStormStrikeAOEBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PDivineStormStrikeAOEPerPowerLevel takes nothing returns real
    return 4.00
endfunction
//----------------------------------------------------------------//
//  PDivineLaserAOEToScaleRatio: This is the Area in which units  //
//  within are affected by the laser, in relation to the scaling  //
//  of the laser at the time                                      //
constant function DES_PDivineLaserAOEToScaleRatioBase takes nothing returns real
    return 60.00
endfunction
//                                                                //
constant function DES_PDivineLaserAOEToScaleRatioPerPowerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormHealthDamage: This is the amount of health damage //
//  dealt to enemies by lightning effects                         //
constant function DES_PDivineStormHealthDamageBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PDivineStormHealthDamagePerPowerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormManaDamage: This is the amount of mana damage     //
//  dealt to enemies by lightning effects                         //
constant function DES_PDivineStormManaDamageBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PDivineStormManaDamagePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormHealthHeal: This is the amount of health          //
//  restored to allies by lightning effects                       //
constant function DES_PDivineStormHealthHealBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PDivineStormHealthHealPerPowerLevel takes nothing returns real 
    return 1.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormManaHeal: This is the amount of mana restored to  //
//  allies by lightning effects                                   //
constant function DES_PDivineStormManaHealBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PDivineStormManaHealPerPowerLevel takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  PDivineLaserHealthDamage: This is the amount of health damage //
//  dealt to enemies by the laser                                 //
constant function DES_PDivineLaserHealthDamageBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PDivineLaserHealthDamagePerPowerLevel takes nothing returns real
    return 4.00
endfunction
//----------------------------------------------------------------//
//  PDivineLaserManaDamage: This is the amount of mana damage     //
//  dealt to enemies by the laser                                 //
constant function DES_PDivineLaserManaDamageBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PDivineLaserManaDamagePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineLaserHealthHeal: This is the amount of health restored //
//  to allies by the laser                                        //
constant function DES_PDivineLaserHealthHealBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PDivineLaserHealthHealPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineLaserManaHeal: This is the amount of mana restored to  //
//  allies by the laser                                           //
constant function DES_PDivineLaserManaHealBase takes nothing returns real
    return 0.00
endfunction
//                                                                //
constant function DES_PDivineLaserManaHealPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineLaserKnockbackPower: This is the strength of the       //
//  knockback the laser inflicts on enemy units, it is divided    //
//  by the distance to the unit from the laser, i.e. 7500 power   //
//  on a unit 400 distance away results in 18.75 resultant        //
//  velocity                                                      //
constant function DES_PDivineLaserKnockbackPowerBase takes nothing returns real
    return 7500.00
endfunction
//                                                                //
constant function DES_PDivineLaserKnockbackPowerPerPowerLevel takes nothing returns real
    return 200.0
endfunction
//----------------------------------------------------------------//
//  PDivineLaserKnockbackPowerCap: This is the limit to the       //
//  velocity of units that are knocked back by the laser          //
constant function DES_PDivineLaserKnockbackPowerCapBase takes nothing returns real
    return 30.00
endfunction
//                                                                //
constant function DES_PDivineLaserKnockbackPowerCapPerPowerLevel takes nothing returns real
    return 0.50
endfunction
//----------------------------------------------------------------//
//  PDivineLaserKnockbackAngle: This is the angle by which units  //
//  are knocked back, it is a measurement of radians (PI/2) = up  //
constant function DES_PDivineLaserKnockbackAngle takes nothing returns real
    return 1.308
endfunction
//----------------------------------------------------------------//
//  PDivineAscensionTime: This is the time it takes for the       //
//  Height alterations of the ultimate to complete                //
constant function DES_PDivineAscensionTimeBase takes nothing returns real
    return 2.00
endfunction
//                                                                //
constant function DES_PDivineAscensionTimePerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineStormDuration: This is the amount of time in seconds   //
//  the storm stage of Divine Envoy lasts                         //
constant function DES_PDivineStormDurationBase takes nothing returns real
    return 5.00
endfunction
//                                                                //
constant function DES_PDivineStormDurationPerPowerLevel takes nothing returns real
    return 0.10
endfunction
//----------------------------------------------------------------//
//  PDivineStormDelay: This is the time in seconds between each   //
//  lightning effect created by Divine Envoy                      // 
constant function DES_PDivineStormDelayBase takes nothing returns real
    return 0.15
endfunction
//                                                                //
constant function DES_PDivineStormDelayPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  PDivineLaserTimer: This is the time it takes for the laser    //
//  to reach full size and the ultimate to start ending           //
constant function DES_PDivineLaserTimerBase takes nothing returns real
    return 1.50
endfunction
//                                                                //
constant function DES_PDivineLaserTimerPerPowerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//                         LOOP CONTROL                           //
//----------------------------------------------------------------//
// CStageID: StageID of Orbs of Creation                          //
constant function DES_CStageID takes nothing returns integer
    return 1
endfunction
//----------------------------------------------------------------//
// DStageID: StageID of Orbs of Destruction                       //
constant function DES_DStageID takes nothing returns integer
    return 2
endfunction
//----------------------------------------------------------------//
// JStageID: StageID of Orbs of Justice                           //
constant function DES_JStageID takes nothing returns integer
    return 3
endfunction
//----------------------------------------------------------------//
// LargeDStageID: StageID of Large Orbs of Destruction            //
constant function DES_LargeDStageID takes nothing returns integer
    return 4
endfunction
//----------------------------------------------------------------//
// UnitStageID: StageID of Affected units                         //
constant function DES_UnitStageID takes nothing returns integer
    return 5
endfunction
//----------------------------------------------------------------//
// UltimateStageID: StageID of Ultimates                          //
constant function DES_UltimateStageID takes nothing returns integer
    return 6
endfunction
//----------------------------------------------------------------//
// PProjectileStageID: StageID of Armageddon Projectiles          //
constant function DES_PProjectileStageID takes nothing returns integer
    return 7
endfunction
//----------------------------------------------------------------//
// RecycleStageID: StageID of Recycled Nodes                      //
constant function DES_RecycleStageID takes nothing returns integer
    return 8
endfunction
//----------------------------------------------------------------//
//  UltimateWaitingTypeID: TypeID of the Ultimate when inactive   //
constant function DES_UltimateWaitingTypeID takes nothing returns integer
    return 0
endfunction
//----------------------------------------------------------------//
//  UltimatePullingTypeID: TypeID of the Ultimate when pulling    //
//  Orbs and units into it to absorb the power                    //
constant function DES_UltimatePullingTypeID takes nothing returns integer
    return 1
endfunction
//----------------------------------------------------------------//
//  UltimateWildTypeID: TypeID of the Ultimate when casting Wild  //
//  Growth                                                        //
constant function DES_UltimateWildTypeID takes nothing returns integer
    return 2
endfunction
//----------------------------------------------------------------//
//  UltimateArmaTypeID: TypeID of the Ultimate when casting       //
//  Armageddon                                                    //
constant function DES_UltimateArmaTypeID takes nothing returns integer
    return 3
endfunction
//----------------------------------------------------------------//
//  UltimateCountTypeID: TypeID of the Ultimate when casting      //
//  Countdown                                                     //
constant function DES_UltimateCountTypeID takes nothing returns integer
    return 4
endfunction
//----------------------------------------------------------------//
//  UltimateDivineStartTypeID: TypeID of the Ultimate when        //
//  starting Divine Envoy                                         //
constant function DES_UltimateDivineStartTypeID takes nothing returns integer
    return 5
endfunction
//----------------------------------------------------------------//
//  UltimateDivineStormTypeID: TypeID of the Ultimate when        //
//  casting the storm stage of Divine Envoy                       //
constant function DES_UltimateDivineStormTypeID takes nothing returns integer
    return 6
endfunction
//----------------------------------------------------------------//
//  UltimateDivineLaserTypeID: TypeID of the Ultimate when        //
//  casting the laser stage of Divine Envoy                       //
constant function DES_UltimateDivineLaserTypeID takes nothing returns integer
    return 7
endfunction
//----------------------------------------------------------------//
//  UltimateLightningTypeID: TypeID of the Lightning casted by    //
//  Divine Envoy                                                  //
constant function DES_UltimateDivineLightningTypeID takes nothing returns integer
    return 8
endfunction
//----------------------------------------------------------------//
//                      END OF CONFIGURATION                      //
//----------------------------------------------------------------//
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
//  Target filter Code (can be configured but requires some       //
//  understanding of programming to do so)                        //
////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
//  Target filter function - passed units and players and checks   //
//  if the unit is allowed to be targetted by this ability         //
/////////////////////////////////////////////////////////////////////
function DES_NeutralTargetFilter takes unit u returns boolean

    //Checks if the unit can be used as a target
    if (not IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (GetUnitFlyHeight(u) <= DES_FilterMaxZ()) and (IsUnitType(u, UNIT_TYPE_GROUND)) and (not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) and (GetUnitTypeId(u) != DES_DummyID()) and not(IsUnitType(u, UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0) then
        return true
    endif
    
    return false
    
endfunction

/////////////////////////////////////////////////////////////////////
//  Enemy target filter function - Passed units and players, using //
//  them to check if the unit can be treated as an enemy by the    //
//  spellset                                                       //
/////////////////////////////////////////////////////////////////////
function DES_EnemyTargetFilter takes unit u, player pl returns boolean

    //Checks if the unit can be used as a target
    if (not IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (GetUnitFlyHeight(u) <= DES_FilterMaxZ()) and (IsUnitType(u, UNIT_TYPE_GROUND)) and (not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) and (IsUnitEnemy(u, pl)) and (GetUnitTypeId(u) != DES_DummyID()) and not(IsUnitType(u, UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0) then
        return true
    endif
    
    return false
    
endfunction

/////////////////////////////////////////////////////////////////////
//  Friendly target filter function - Passed units and players,    //
//  using them to check if the unit can be treated as an ally by   //
//  the spellset                                                   //
/////////////////////////////////////////////////////////////////////
function DES_FriendlyTargetFilter takes unit u, player pl returns boolean

    //Checks if the unit can be used as a target
    if (not IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (GetUnitFlyHeight(u) <= DES_FilterMaxZ()) and (IsUnitType(u, UNIT_TYPE_GROUND)) and (not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) and (not(IsUnitEnemy(u, pl))) and (GetUnitTypeId(u) != DES_DummyID()) and not(IsUnitType(u, UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0) then
        return true
    endif
    
    return false
    
endfunction

/////////////////////////////////////////////////////////////////////
//  Orb target filter function - Passed units and players, using   //
//  them to check if the unit can be treated as an Orb by the      //
//  spellset                                                       //
/////////////////////////////////////////////////////////////////////
function DES_OrbTargetFilter takes integer Node, integer StageID, player pl returns boolean

    //Checks if the unit can be treated as an Orb
    if ((GetUnitTypeId(udg_DES_Unit[Node]) == DES_DummyID()) and (udg_DES_StageID[Node] <= DES_JStageID()) and (udg_DES_Boolean1[Node] == true) and (udg_DES_Boolean2[Node] == false) and (udg_DES_Player[Node] == pl) and (not(udg_DES_StageID[Node] == StageID))) then
        return true
    endif
    
    return false
    
endfunction

////////////////////////////////////////////////////////////////////
//  Beyond this point are system functions that should not be     //
//  modified unless you are a skilled programmer and know what    //
//  you are doing                                                 //
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
//  Function used to recycle instances, so that they can used     //
//  again later, keeping the total array sizes smaller            //
////////////////////////////////////////////////////////////////////
function DES_Recycle takes integer Node returns nothing
           
        //Set up the StageID to prevent interaction
        set udg_DES_StageID[Node] = DES_RecycleStageID()
        
        if (udg_DES_LastNode == Node) then
            set udg_DES_LastNode = udg_DES_PrevNode[Node]
        endif
           
        //Recycles the node
        set udg_DES_RecycleNodes[udg_DES_RecyclableNodes] = Node
        set udg_DES_RecyclableNodes = udg_DES_RecyclableNodes + 1
        set udg_DES_NextNode[udg_DES_PrevNode[Node]] = udg_DES_NextNode[Node]
        set udg_DES_PrevNode[udg_DES_NextNode[Node]] = udg_DES_PrevNode[Node]
        set udg_DES_AbilityCounter = udg_DES_AbilityCounter - 1

        //Stops the timer if this is the only remaining Node
        if (udg_DES_AbilityCounter == 0) then
            call PauseTimer(udg_DES_Timer)
        endif

endfunction

////////////////////////////////////////////////////////////////////
//  Function used to create new Nodes for the system whenever a   //
//  unit or effect is added to run in the loop function           //
////////////////////////////////////////////////////////////////////
function DES_CreateNode takes nothing returns integer
    //set up local
    local integer Node = 0
    
    //Checking for recycleable Nodes
    if (udg_DES_RecyclableNodes == 0) then
        set udg_DES_NodeNumber = udg_DES_NodeNumber + 1
        set Node = udg_DES_NodeNumber
    else
        set udg_DES_RecyclableNodes = udg_DES_RecyclableNodes - 1
        set Node = udg_DES_RecycleNodes[udg_DES_RecyclableNodes]
    endif

    //Sets up this Node
    set udg_DES_NextNode[Node] = 0
    set udg_DES_NextNode[udg_DES_LastNode] = Node
    set udg_DES_PrevNode[Node] = udg_DES_LastNode
    set udg_DES_LastNode = Node
    
    set udg_DES_AbilityCounter = udg_DES_AbilityCounter + 1
    
    return Node
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to get the z height of locations needed by the  //
//  spell, since it can only be done with locations, this one     //
//  is reused throughout, instead of creating/destroying them     //
////////////////////////////////////////////////////////////////////
function DES_GetZ takes real x, real y returns real

    //Gets the location Z of the selected location
    call MoveLocation(udg_DES_Loc, x, y)
    return GetLocationZ(udg_DES_Loc)
    
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to make sure that the location is within the    //
//  map bounds so that units cannot be moved outside of it and    //
//  get permanently stuck                                         //
////////////////////////////////////////////////////////////////////
function DES_ValidateLocation takes real x, real y returns boolean
    
    //Check if the point is within the map bounds
    if (x < udg_DES_MapMaxX) and (x > udg_DES_MapMinX) and (y < udg_DES_MapMaxY) and (y > udg_DES_MapMinY) then
        return true
    endif
    
    return false

endfunction

////////////////////////////////////////////////////////////////////
//  Function used to destroy trees which have been found close    //
//  to affected units (knockback and pull)                        //
////////////////////////////////////////////////////////////////////
function DES_TreeDestroy takes nothing returns nothing
    //set up local
    local destructable Tree = GetEnumDestructable()
    
    //Order the tree checker to harvest the tree
    call IssueTargetOrderById(udg_DES_TreeChecker, 852018, Tree)
    
    //Check if the current order is to harvest the tree
    if (GetUnitCurrentOrder(udg_DES_TreeChecker) == 852018) then
        call KillDestructable(Tree)
    endif

    //Order the tree checker to stop
    call IssueImmediateOrderById(udg_DES_TreeChecker, 851972)
    
    set Tree = null
endfunction

////////////////////////////////////////////////////////////////////
//  Locates trees next to units being pulled or knocked back and  //
//  calls TreeDestroy to remove them                              //
////////////////////////////////////////////////////////////////////
function DES_GetTrees takes real x, real y returns nothing
    //set up local
    local rect TempRect = Rect(x - DES_TreeDestroyRadius(), y - DES_TreeDestroyRadius(), x + DES_TreeDestroyRadius(), y + DES_TreeDestroyRadius())
    
    //Get all the trees in radius
    call MoveLocation(udg_DES_Loc, x, y)
    set bj_enumDestructableCenter = udg_DES_Loc
    set bj_enumDestructableRadius = DES_TreeDestroyRadius()
    call EnumDestructablesInRect(TempRect, filterEnumDestructablesInCircleBJ, function DES_TreeDestroy)
    
    call RemoveRect(TempRect)
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to remove all the parts of the ultimate when    //
//  it ends and play their death effects                          //
////////////////////////////////////////////////////////////////////
function DES_EndUltimate takes integer Node returns nothing
    //sets up locals
    local integer TempInt = 0
    local integer TempNode = 0
    
    //Find all parts of the ultimate
    loop
        set TempInt = TempInt + 1
        exitwhen TempInt > udg_DES_AbilityCounter
        set TempNode = udg_DES_NextNode[TempNode]
        
        if (udg_DES_Core[TempNode] == udg_DES_Unit[Node]) then
            
            //Clean up the part
            call DestroyEffect(udg_DES_CurrentEffect[TempNode])
            set udg_DES_StageID[TempNode] = DES_RecycleStageID()
            call DES_Recycle(TempNode)
            set TempInt = TempInt - 1
            
            if (udg_DES_Boolean4[TempNode] == true) and (udg_DES_Boolean3[TempNode] == false) then
                //Play death effect
                call DestroyEffect(AddSpecialEffectTarget(DES_PDeathEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint()))
            else
                call RemoveUnit(udg_DES_Unit[TempNode])
            endif
            
            call UnitApplyTimedLife(udg_DES_Unit[TempNode], DES_TimedLifeID(), DES_EffectExpirationTimer())
        endif
        
    endloop

endfunction

////////////////////////////////////////////////////////////////////
//  Function used to start the Countdown version of the ultimate  //
//  it has it's own function as unlike the others, there's two    //
//  scenarios in which the outcome results in this effect         //
////////////////////////////////////////////////////////////////////
function DES_UltimateCountStart takes integer Node returns nothing
    //Set up Countdown data
    set udg_DES_Integer1[Node] = DES_UltimateCountTypeID()
    set udg_DES_Real4[Node] = DES_PCountAOEBase() + (udg_DES_Real3[Node] * DES_PCountAOEPerPowerLevel())
    set udg_DES_Real5[Node] = DES_PCountHealthDamageBase() + (udg_DES_Real2[Node] * DES_PCountHealthDamagePerPowerLevel())
    set udg_DES_Real6[Node] = DES_PCountManaDamageBase() + (udg_DES_Real2[Node] * DES_PCountManaDamagePerPowerLevel())
    set udg_DES_Real7[Node] = DES_PCountHealthHealBase() + (udg_DES_Real2[Node] * DES_PCountHealthHealBase())
    set udg_DES_Real10[Node] = DES_PCountManaHealBase() + (udg_DES_Real2[Node] * DES_PCountManaHealPerPowerLevel())
    set udg_DES_Real11[Node] = DES_PCountTimerBase() + (udg_DES_Real1[Node] * DES_PCountTimerPerPowerLevel())
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to add Orbs to the stacks of the ultimate       //
////////////////////////////////////////////////////////////////////
function DES_AddOrb takes integer Node, integer Type, real x, real y, real Height, real Angle returns nothing
    //sets up locals
    local integer TempNode = DES_CreateNode()
    local real x2 = x + udg_DES_Real8[Node] * Cos(Angle)
    local real y2 = y + udg_DES_Real8[Node] * Sin(Angle)
    
    //Check what kind of orb it is to add
    if (Type == DES_CStageID()) then
        //Set up Orb data
        set udg_DES_Real2[TempNode] = DES_CPassiveHealAOEBase() + (udg_DES_Real3[Node] * DES_CPassiveHealAOEPerPowerLevel())
        set udg_DES_Real3[TempNode] = DES_CPassiveHealHealthBase() + (udg_DES_Real3[Node] * DES_CPassiveHealHealthPerPowerLevel())
        set udg_DES_Real4[TempNode] = DES_CPassiveHealManaBase() + (udg_DES_Real3[Node] * DES_CPassiveHealManaPerPowerLevel())
        set udg_DES_Real5[TempNode] = DES_CPassiveDelayBase() + (udg_DES_Real3[Node] * DES_CPassiveDelayPerPowerLevel())
        set udg_DES_Real6[TempNode] = udg_DES_Real5[TempNode]
        set udg_DES_Boolean1[TempNode] = true
        set udg_DES_Boolean2[TempNode] = true
        set udg_DES_Boolean3[TempNode] = false
        set udg_DES_Boolean4[TempNode] = true
        set udg_DES_StageID[TempNode] = DES_CStageID()
        set udg_DES_Caster[TempNode] = udg_DES_Caster[Node]
        set udg_DES_Core[TempNode] = udg_DES_Unit[Node]
        set udg_DES_Player[TempNode] = udg_DES_Player[Node]
        
        //Set up the unit
        set udg_DES_Unit[TempNode] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x2, y2, Angle)
        set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_COrbEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint())
        call SetUnitScale(udg_DES_Unit[TempNode], (DES_COrbScaleBase() + (udg_DES_Real3[Node] * DES_COrbScalePerPowerLevel())) / DES_PSmallOrbSizeLimiter(), 0, 0)
        
        if UnitAddAbility(udg_DES_Unit[TempNode], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[TempNode], 'Amrf') then
        endif
        
        call SetUnitFlyHeight(udg_DES_Unit[TempNode], Height, 0.)
    elseif (Type == DES_DStageID()) then
        //Set up Orb data
        set udg_DES_Real2[TempNode] = DES_DPassiveDamageAOEBase() + (udg_DES_Real3[Node] * DES_DPassiveDamageAOEPerPowerLevel())
        set udg_DES_Real3[TempNode] = DES_DPassiveDamageHealthBase() + (udg_DES_Real3[Node] * DES_DPassiveDamageHealthPerPowerLevel())
        set udg_DES_Real4[TempNode] = DES_DPassiveDamageManaBase() + (udg_DES_Real3[Node] * DES_DPassiveDamageManaPerPowerLevel())
        set udg_DES_Real5[TempNode] = DES_DPassiveDelayBase() + (udg_DES_Real3[Node] * DES_DPassiveDelayPerPowerLevel())
        set udg_DES_Real6[TempNode] = udg_DES_Real5[TempNode]
        set udg_DES_Boolean1[TempNode] = true
        set udg_DES_Boolean2[TempNode] = true
        set udg_DES_Boolean3[TempNode] = false
        set udg_DES_Boolean4[TempNode] = true
        
        set udg_DES_StageID[TempNode] = DES_DStageID()
        set udg_DES_Caster[TempNode] = udg_DES_Caster[Node]
        set udg_DES_Core[TempNode] = udg_DES_Unit[Node]
        set udg_DES_Player[TempNode] = udg_DES_Player[Node]
        
        //Set up unit
        set udg_DES_Unit[TempNode] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x2, y2, Angle)
        set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_DOrbEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint())
        call SetUnitScale(udg_DES_Unit[TempNode], (DES_DOrbScaleBase() + (udg_DES_Real3[Node] * DES_DOrbScalePerPowerLevel())) / DES_PSmallOrbSizeLimiter(), 0, 0)
        
        if UnitAddAbility(udg_DES_Unit[TempNode], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[TempNode], 'Amrf') then
        endif
        
        call SetUnitFlyHeight(udg_DES_Unit[TempNode], Height, 0.)
    else
        //Set up Orb data
        set udg_DES_Real2[TempNode] = DES_JDamageAOEBase() + (udg_DES_Real3[Node] * DES_JDamageAOEPerPowerLevel())
        set udg_DES_Integer2[TempNode] = DES_PSlowLevel()
        set udg_DES_Boolean1[TempNode] = true
        set udg_DES_Boolean2[TempNode] = true
        set udg_DES_Boolean3[TempNode] = false
        set udg_DES_Boolean4[TempNode] = true
        
        set udg_DES_StageID[TempNode] = DES_JStageID()
        set udg_DES_Caster[TempNode] = udg_DES_Caster[Node]
        set udg_DES_Core[TempNode] = udg_DES_Unit[Node]
        set udg_DES_Player[TempNode] = udg_DES_Player[Node]
        
        //Set up unit
        set udg_DES_Unit[TempNode] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x2, y2, Angle * bj_RADTODEG)
        set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_JOrbEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint())
        call SetUnitScale(udg_DES_Unit[TempNode], (DES_JOrbScaleBase() + (udg_DES_Real3[Node] * DES_JOrbScalePerPowerLevel())) / DES_PSmallOrbSizeLimiter(), 0, 0)
        
        if UnitAddAbility(udg_DES_Unit[TempNode], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[TempNode], 'Amrf') then
        endif
        
        call SetUnitFlyHeight(udg_DES_Unit[TempNode], Height, 0.)
    endif
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to handle all the special effects used by the   //
//  combo abilities                                               //
////////////////////////////////////////////////////////////////////
function DES_ComboEffects takes real x, real y, integer Divider, real AOE, real BoarderScale, real ActivateScale, string BoarderEffect, string ActivateEffect returns nothing
    //sets up locals
    local integer iLoop = 0
    local real Angle = 0
    local real Angle2 = 0
    local unit u = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, 0)
    local integer BoarderCount= (360 / Divider)
    
    //Create central effect
    call DestroyEffect(AddSpecialEffectTarget(ActivateEffect, u, DES_AttachmentPoint()))
    call SetUnitScale(u, ActivateScale, 0,0)
    call UnitApplyTimedLife(u, DES_TimedLifeID(), DES_EffectExpirationTimer()) 
    
    set u = null
    
    //Create Boarder effects
    loop
        set iLoop = iLoop + 1
        set Angle = Angle + Divider
        set Angle2 = Angle * bj_DEGTORAD
        set u = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x + AOE * Cos(Angle2),  y + AOE * Sin(Angle2), 0)
        call DestroyEffect(AddSpecialEffectTarget(BoarderEffect, u, DES_AttachmentPoint()))
        call SetUnitScale(u, BoarderScale, 0, 0)
        call UnitApplyTimedLife(u, DES_TimedLifeID(), DES_EffectExpirationTimer())
        set u = null
        exitwhen iLoop > BoarderCount
    endloop
    
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to create the Cycle of life combo effect        //
//  when the appropriate combo has been detected                  //
////////////////////////////////////////////////////////////////////
function DES_CycleOfLife takes real x, real y, real Power, unit Caster, player pl returns nothing
    //sets up locals
    local real AOE = DES_CycleAOEBase() + (Power * DES_CycleAOEPerPowerLevel())
    local real DamageHealth = DES_CycleDamageHealthBase() + (Power * DES_CycleDamageHealthPerPowerLevel())
    local real DamageMana = DES_CycleDamageManaBase() + (Power * DES_CycleDamageManaPerPowerLevel())
    local real HealHealthRatio = DES_CycleHealHealthRatioBase() + (Power * DES_CycleHealHealthRatioPerPowerLevel())
    local real HealManaRatio = DES_CycleHealManaRatioBase() + (Power * DES_CycleHealManaRatioPerPowerLevel())
    local real TotalDamageHealth = 0
    local real TotalDamageMana = 0
    local real TempReal
    local integer Divider = R2I((bj_PI * AOE * 2) / (DES_CycleBoarderSpaceBase() + (Power * DES_CycleBoarderSpacePerPowerLevel())))
    local unit u
    
    //Run effects
    call DES_ComboEffects(x, y, Divider, AOE, DES_CycleBoarderScaleBase() + (Power * DES_CycleBoarderScalePerPowerLevel()), DES_CycleActivateScaleBase() + (Power * DES_CycleActivateScalePerPowerLevel()), DES_CycleBoarderEffect(), DES_CycleActivateEffect())
    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, AOE, null)
    
    //Damage enemy units
    loop
        set u = FirstOfGroup(udg_DES_TempGroup)
        exitwhen  u == null
        
        if (DES_EnemyTargetFilter(u, pl)) then
            call DestroyEffect(AddSpecialEffectTarget(DES_CycleDamageEffect(), u, DES_AttachmentPoint()))
            set TempReal = GetUnitState(u, UNIT_STATE_LIFE)
            call UnitDamageTarget(Caster, u, DamageHealth, false, false, DES_CycleAttackType(), DES_CycleDamageType(), DES_CycleWeaponType())
            set TotalDamageHealth = TotalDamageHealth + (TempReal - GetUnitState(u, UNIT_STATE_LIFE))
            set TempReal = GetUnitState(u, UNIT_STATE_MANA)
            call SetUnitState(u, UNIT_STATE_MANA, TempReal - DamageMana)
            set TotalDamageMana = TotalDamageMana + (TempReal - GetUnitState(u, UNIT_STATE_MANA))
        endif
        
        call GroupRemoveUnit(udg_DES_TempGroup, u)
    endloop
    
    //Calculate amount to heal
    set TotalDamageHealth = TotalDamageHealth * HealHealthRatio
    set TotalDamageMana = TotalDamageMana * HealManaRatio
    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, AOE, null)
    
    //Heal Allied units
    loop
        set u = FirstOfGroup(udg_DES_TempGroup)
        exitwhen  u == null
        
        if (DES_FriendlyTargetFilter(u, pl)) then
            call DestroyEffect(AddSpecialEffectTarget(DES_CycleHealEffect(), u, DES_AttachmentPoint()))
            call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + TotalDamageHealth)
            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) + TotalDamageMana)
        endif
        
        call GroupRemoveUnit(udg_DES_TempGroup, u)
    endloop    
    
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to create the Equaliser combo effect            //
//  when the appropriate combo has been detected                  //
////////////////////////////////////////////////////////////////////
function DES_Equaliser takes real x, real y, real Power, unit Caster, player pl returns nothing
    //sets up locals
    local real AOE = DES_EqualAOEBase() + (Power * DES_EqualAOEPerPowerLevel())
    local real ManaCost = DES_EqualManaCostBase() + (Power * DES_EqualManaCostPerPowerLevel())
    local real Health= 0
    local real iCount = 0
    local integer Divider = R2I((bj_PI * AOE * 2) / (DES_EqualBoarderSpaceBase() + (Power * DES_EqualBoarderSpacePerPowerLevel())))
    local unit u
    
    //Run effects
    call DES_ComboEffects(x, y, Divider, AOE, DES_EqualBoarderScaleBase() + (Power * DES_EqualBoarderScalePerPowerLevel()), DES_EqualActivateScaleBase() + (Power * DES_EqualActivateScalePerPowerLevel()), DES_EqualBoarderEffect(), DES_EqualActivateEffect())
    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, AOE, null)
    
    //Add up available HP and drain mana
    loop
        set u = FirstOfGroup(udg_DES_TempGroup)
        exitwhen  u == null
        
        if (DES_NeutralTargetFilter(u)) then
            call GroupAddUnit(udg_DES_TempGroup2, u)
            set iCount = iCount + 1
            set Health = Health + GetUnitState(u, UNIT_STATE_LIFE)
            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - ManaCost)
        endif
        
        call GroupRemoveUnit(udg_DES_TempGroup, u)
    endloop
    
    //Find average Health
    set Health = Health / iCount
    
    //Apply average health to units
    loop
        set u = FirstOfGroup(udg_DES_TempGroup2)
        exitwhen u == null
        call DestroyEffect(AddSpecialEffectTarget(DES_EqualAlterEffect(), u, DES_AttachmentPoint()))
        call SetUnitState(u, UNIT_STATE_LIFE, Health)
        call GroupRemoveUnit(udg_DES_TempGroup2, u)
    endloop
    
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to create the Trial by fire combo effect        //
//  when the appropriate combo has been detected                  //
////////////////////////////////////////////////////////////////////
function DES_TrialByFire takes real x, real y, real Power, integer Node returns nothing
    //sets up locals
    local real AOE = DES_TrialAOEBase() + (Power * DES_TrialAOEPerPowerLevel())
    local real BoarderScale = DES_TrialBoarderScaleBase() + (Power * DES_TrialBoarderScalePerPowerLevel())
    local real DamageHealth = DES_TrialDamageHealthBase() + (Power * DES_TrialDamageHealthPerPowerLevel())
    local real DamageMana = DES_TrialDamageManaBase() + (Power * DES_TrialDamageManaPerPowerLevel())
    local integer Divider = R2I((bj_PI * AOE * 2) / (DES_TrialBoarderSpaceBase() + (Power * DES_TrialBoarderSpacePerPowerLevel())))
    local integer TempNode = 0
    local unit u
    
    //Run effects
    call DES_ComboEffects(x, y, Divider, AOE, DES_TrialBoarderScaleBase() + (Power * DES_TrialBoarderScalePerPowerLevel()), DES_TrialActivateScaleBase() + (Power * DES_TrialActivateScalePerPowerLevel()), DES_TrialBoarderEffect(), DES_TrialActivateEffect())
    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, AOE, null)

    //Find enemy units to set on fire
    loop
        set u = FirstOfGroup(udg_DES_TempGroup)
        exitwhen u == null
        
        if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
            //Play effects and damage
            call DestroyEffect(AddSpecialEffectTarget(DES_TrialDamageEffect(), u, DES_AttachmentPoint()))
            call UnitDamageTarget(udg_DES_Caster[Node], u, DamageHealth, false, false, DES_TrialAttackType(), DES_TrialDamageType(), DES_TrialWeaponType())
            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - DamageMana)
            
            //Set up Data
            set TempNode = DES_CreateNode()
            set udg_DES_Real1[TempNode] = Power
            set udg_DES_Real2[TempNode] = DES_TrialExplosionAOEBase() + (Power * DES_TrialExplosionAOEPerPowerLevel())
            set udg_DES_Real3[TempNode] = DES_TrialExplosionHealthDamageBase() + (Power * DES_TrialExplosionHealthDamagePerPowerLevel())
            set udg_DES_Real4[TempNode] = DES_TrialExplosionManaDamageBase() + (Power * DES_TrialExplosionManaDamagePerPowerLevel())
            set udg_DES_Real5[TempNode] = DES_TrialBurnHealthDamageBase() + (Power * DES_TrialBurnHealthDamagePerPowerLevel())
            set udg_DES_Real6[TempNode] = DES_TrialBurnManaDamageBase() + (Power * DES_TrialBurnManaDamagePerPowerLevel())
            set udg_DES_Real7[TempNode] = DES_TrialBurnDurationBase() + (Power * DES_TrialBurnDurationPerPowerLevel())
            set udg_DES_Real8[TempNode] = DES_TrialDamageDelayBase() + (Power * DES_TrialDamageDelayPerPowerLevel())
            set udg_DES_Real9[TempNode] = udg_DES_Real8[TempNode]
            set udg_DES_Boolean1[TempNode] = true
            set udg_DES_Boolean2[TempNode] = false
            set udg_DES_Boolean3[TempNode] = false
            set udg_DES_Boolean4[TempNode] = false
            
            set udg_DES_StageID[TempNode] = DES_UnitStageID() 
            set udg_DES_Caster[TempNode] = udg_DES_Caster[Node]
            set udg_DES_Unit[TempNode] = u
            set udg_DES_Core[TempNode] = udg_DES_Unit[Node]
            
            //Apply burn effect
            set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_TrialBurnEffect(), u, DES_AttachmentPoint())
        endif
        
        call GroupRemoveUnit(udg_DES_TempGroup, u)
    endloop
    
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to find units that currently have the slow      //
//  effect on them but need it removed due to one of various      //
//  reasons                                                       //
////////////////////////////////////////////////////////////////////
function DES_SlowScan takes integer Node returns nothing
    //sets up locals
    local integer TempNode = 0
    local integer TempInt = 0
    
    //Find units with the slow who need it removed 
    loop
        set TempInt = TempInt + 1
        exitwhen TempInt > udg_DES_AbilityCounter
        set TempNode = udg_DES_NextNode[TempNode]
        
        if (udg_DES_Core[TempNode] == udg_DES_Unit[Node]) and (udg_DES_Boolean2[TempNode] == true) and (udg_DES_StageID[TempNode] == DES_UnitStageID()) then
            //Remove the slow
            call UnitRemoveAbility(udg_DES_Unit[TempNode], DES_SlowID())
            call DestroyEffect(udg_DES_CurrentEffect[TempNode])
            //Recycle
            call DES_Recycle(TempNode)
            set TempInt = TempInt - 1
        endif
        
    endloop
    
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to detect whenever a combo has occured          //
//  between two orbs and determine which combo effect should      //
//  occur in the space between them                               //
////////////////////////////////////////////////////////////////////
function DES_ComboCollisionDetection takes real x, real y, integer Node returns nothing
    //sets up locals
    local integer TempInt = 0
    local integer TempNode = 0
    local real x2 = 0
    local real y2 = 0
    local real TempReal = 0
    local real TempReal2 = 0
    
    loop
        //Moves to the next node
        set TempInt = TempInt + 1
        exitwhen ((TempInt > udg_DES_AbilityCounter) or (udg_DES_StageID[Node] == DES_RecycleStageID()))
        set TempNode = udg_DES_NextNode[TempNode]

        //Find valid combo orbs
        if (DES_OrbTargetFilter(TempNode, udg_DES_StageID[Node], udg_DES_Player[Node])) then
            set x2 = GetUnitX(udg_DES_Unit[TempNode])
            set y2 = GetUnitY(udg_DES_Unit[TempNode])
            set TempReal = SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y))
            
            //Check if the orb is close enough
            if (TempReal <= DES_ComboCollision()) then
                set x = x + (x2 - x)
                set y = y + (y2 - y)
                
                //Check if it's a Orb of Justice in transit
                if (udg_DES_StageID[Node] == DES_JStageID()) then
                    call DestroyEffect(udg_DES_SecondaryEffect[Node])
                    call DES_SlowScan(Node)
                elseif (udg_DES_StageID[TempNode] == DES_JStageID()) then
                    call DestroyEffect(udg_DES_SecondaryEffect[TempNode])
                    call DES_SlowScan(TempNode)
                endif
                
                //Caluclate total Stored Power
                set TempReal = udg_DES_StageID[TempNode] * udg_DES_StageID[Node]
                set TempReal2 = udg_DES_Real1[TempNode] + udg_DES_Real1[Node]
                
                //recycle
                call DES_Recycle(Node)
                call DES_Recycle(TempNode)
                set TempInt = TempInt - 1
                
                //Play Effects
                call DestroyEffect(udg_DES_CurrentEffect[Node])
                call DestroyEffect(udg_DES_CurrentEffect[TempNode])
                call UnitApplyTimedLife(udg_DES_Unit[Node], DES_TimedLifeID(), DES_EffectExpirationTimer())
                call UnitApplyTimedLife(udg_DES_Unit[TempNode], DES_TimedLifeID(), DES_EffectExpirationTimer())
                
                //Run Combo Ability
                if (TempReal == DES_DStageID()) then
                    call DES_CycleOfLife(x, y, TempReal2, udg_DES_Caster[Node], udg_DES_Player[Node])
                elseif  (TempReal == DES_JStageID()) then
                    call DES_Equaliser(x, y, TempReal2, udg_DES_Caster[Node], udg_DES_Player[Node])
                else
                    call DES_TrialByFire(x, y, TempReal2, Node)
                endif
                
            endif
            
        endif
        
    endloop
    
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to handle all units that are currently being    //
//  knocked back (and are in flight) and all projectiles          //
//  generated by the spellset                                     //
////////////////////////////////////////////////////////////////////
function DES_ProjectileHandler takes integer Node returns boolean
    //sets up locals
    local real z
    local real z2
    local real x = GetUnitX(udg_DES_Unit[Node])
    local real x2 = x + udg_DES_Real6[Node]
    local real y = GetUnitY(udg_DES_Unit[Node])
    local real y2 = y + udg_DES_Real7[Node]
    local real TempReal
    local integer iLoop = 0
    local unit u
    
    //Check if the new location is within the map bounds
    if (DES_ValidateLocation(x2, y2)) then
        call SetUnitX(udg_DES_Unit[Node], x2)
        call SetUnitY(udg_DES_Unit[Node], y2)
    endif
    
    //Check if the Orb is a justice Orb (no arc)
    if (udg_DES_StageID[Node] == DES_JStageID()) then
        set udg_DES_Real5[Node] = udg_DES_Real5[Node] - udg_DES_Real8[Node]
        
        //Check if it's time for another damage burst
        if (udg_DES_Real11[Node] <= 0) then
            set udg_DES_Real11[Node] = udg_DES_Real10[Node]
            call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node], null)
            
            //Find valid enemy targets
            loop
                set u = FirstOfGroup(udg_DES_TempGroup)
                exitwhen u == null
                
                if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                    //Damage enemies
                    call DestroyEffect(AddSpecialEffectTarget(DES_JDamageEffect(), u, DES_AttachmentPoint()))
                    call UnitDamageTarget(udg_DES_Caster[Node], u, udg_DES_Real3[Node], false, false, DES_JAttackType(), DES_JDamageType(), DES_JWeaponType())
                    set TempReal = GetUnitState(u, UNIT_STATE_MANA)
                    call SetUnitState(u, UNIT_STATE_MANA, TempReal - udg_DES_Real4[Node])
                    call UnitDamageTarget(udg_DES_Caster[Node], u, (TempReal - GetUnitState(u, UNIT_STATE_MANA)) * udg_DES_Real9[Node], false, false, DES_JAttackType(), DES_JDamageType(), DES_JWeaponType())
                endif
                
                call GroupRemoveUnit(udg_DES_TempGroup, u)
            endloop
            
        else
            set udg_DES_Real11[Node] = udg_DES_Real11[Node] - DES_TimerSpeed()
        endif
        
        //Check for combo capability
        call DES_ComboCollisionDetection(x, y, Node)
        
        if (udg_DES_Real5[Node] <= 0) then
            return true
        endif
        
    else
        
        //Check if the user has enabled TerrainHeightMatters
        if (DES_TerrainHeightMatters()) then
            set z2 = DES_GetZ(x2, y2)
            set z = DES_GetZ(x, y)
            set z = GetUnitFlyHeight(udg_DES_Unit[Node]) + udg_DES_Real5[Node] - (z2 - z)
        else
            set z = GetUnitFlyHeight(udg_DES_Unit[Node]) + udg_DES_Real5[Node]        
        endif

        //Change the units z velocity
        set udg_DES_Real5[Node] = udg_DES_Real5[Node] - DES_Gravity()
        call SetUnitFlyHeight(udg_DES_Unit[Node], z, 0.)
        
        //Check if it has hit the "ground"
        if (z <= DES_GroundHeightLet()) then
            call SetUnitFlyHeight(udg_DES_Unit[Node], 0., 0.)
            return true
        endif
        
    endif
    
    return false
endfunction

////////////////////////////////////////////////////////////////////
//  The main functino which is used to handle all the key         //
//  components of the spellset, including handling all Orb        //
//  effects, all forms of the Ultimate and all units which are    //
//  being affected by anything from the spellset                  //
////////////////////////////////////////////////////////////////////
function DES_Loop takes nothing returns nothing
    //sets up locals
    local integer TempInt = 0
    local integer TempInt2 = 0
    local integer iLoop = 0
    local integer Node = 0
    local integer TempNode = 0
    local real x
    local real x2
    local real y
    local real y2
    local real z
    local real z2
    local real Angle = 0
    local real TempReal = 0
    local unit u
    
    //Main loop
    loop
        //Moves to the next node
        set TempInt = TempInt + 1
        exitwhen TempInt > udg_DES_AbilityCounter
        set Node = udg_DES_NextNode[Node]
        
        //Creation Orbs
        if (udg_DES_StageID[Node] == DES_CStageID()) then
        
            //Check if the orb is still alive
            if ((IsUnitType(udg_DES_Unit[Node], UNIT_TYPE_DEAD)) or (GetUnitTypeId(udg_DES_Unit[Node]) == null)) then
                call DestroyEffect(AddSpecialEffectTarget(DES_CDeathEffect(), udg_DES_Unit[Node], DES_AttachmentPoint()))
                //Recycle
                call DES_Recycle(Node)
                set TempInt = TempInt - 1
            else
                //Find the current location of the Orb
                set x = GetUnitX(udg_DES_Unit[Node])
                set y = GetUnitY(udg_DES_Unit[Node])
                
                //Check if the Orb has hit the ground
                if (udg_DES_Boolean1[Node] == false) then
                
                    //Move the Orb
                    if (DES_ProjectileHandler(Node)) then
                        set udg_DES_Boolean1[Node] = true
                        call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node], null)
                        
                        //Heal Allied units
                        loop
                            set u = FirstOfGroup(udg_DES_TempGroup)
                            exitwhen u == null
                            
                            if (DES_FriendlyTargetFilter(u, udg_DES_Player[Node])) then
                                call DestroyEffect(AddSpecialEffectTarget(DES_CImpactHealEffect(), u, DES_AttachmentPoint()))
                                call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + udg_DES_Real3[Node])
                                call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) + udg_DES_Real4[Node])
                            endif
                            
                            call GroupRemoveUnit(udg_DES_TempGroup, u)
                        endloop
                        
                        //Play Effects
                        set u = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, 0)
                        call SetUnitScale(u, DES_CImpactScaleBase() + (udg_DES_Real1[Node] * DES_CImpactScalePerPowerLevel()), 0., 0.)
                        call DestroyEffect(AddSpecialEffectTarget(DES_CImpactEffect(), u, DES_AttachmentPoint()))
                        call DestroyEffect(udg_DES_SecondaryEffect[Node])
                        
                        //Set up Data
                        set udg_DES_Real2[Node] = DES_CPassiveHealAOEBase() + (udg_DES_Real1[Node] * DES_CPassiveHealAOEPerPowerLevel())
                        set udg_DES_Real3[Node] = DES_CPassiveHealHealthBase() + (udg_DES_Real1[Node] * DES_CPassiveHealHealthPerPowerLevel())
                        set udg_DES_Real4[Node] = DES_CPassiveHealManaBase() + (udg_DES_Real1[Node] * DES_CPassiveHealManaPerPowerLevel())
                        set udg_DES_Real5[Node] = DES_CPassiveDelayBase() + (udg_DES_Real1[Node] * DES_CPassiveDelayPerPowerLevel())
                        set udg_DES_Real6[Node] = udg_DES_Real5[Node]
                        
                        call UnitApplyTimedLife(u, DES_TimedLifeID(), DES_EffectExpirationTimer())
                        call UnitApplyTimedLife(udg_DES_Unit[Node], DES_TimedLifeID(), DES_CTimedLifeBase() * (udg_DES_Real1[Node] * DES_CTimedLifePerPowerLevel()))

                        set u = null
                        //Check for Combo Capability
                        call DES_ComboCollisionDetection(x, y, Node)
                        
                    endif
                
                //Passive heal
                elseif (udg_DES_Real6[Node] <= 0) then
                    set udg_DES_Real6[Node] = udg_DES_Real5[Node]
                    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node], null)
                    
                    //Heal allied units
                   loop
                        set u = FirstOfGroup(udg_DES_TempGroup)
                        exitwhen u == null
                        
                        if (DES_FriendlyTargetFilter(u, udg_DES_Player[Node])) then
                            call DestroyEffect(AddSpecialEffectTarget(DES_CHealEffect(), u, DES_AttachmentPoint()))
                            call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + udg_DES_Real3[Node])
                            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) + udg_DES_Real4[Node])
                        endif
                        
                        call GroupRemoveUnit(udg_DES_TempGroup, u)
                    endloop
                    
                else
                    set udg_DES_Real6[Node] = udg_DES_Real6[Node] - DES_TimerSpeed()
                endif
                
            endif
        //Destruction Orbs
        elseif (udg_DES_StageID[Node] == DES_DStageID()) then
        
            //Check if the Orb is still alive
            if ((IsUnitType(udg_DES_Unit[Node], UNIT_TYPE_DEAD)) or (GetUnitTypeId(udg_DES_Unit[Node]) == null)) then
                call DestroyEffect(AddSpecialEffectTarget(DES_DDeathEffect(), udg_DES_Unit[Node], DES_AttachmentPoint()))
                //Recycle
                call DES_Recycle(Node)
                set TempInt = TempInt - 1
            else
                //Get the current Coordinates of the Orb
                set x = GetUnitX(udg_DES_Unit[Node])
                set y = GetUnitY(udg_DES_Unit[Node])
                
                //Check if the Orb has hit the ground
                if (udg_DES_Boolean1[Node] == false) then
                
                    //Move the Orb
                    if (DES_ProjectileHandler(Node)) then
                        set udg_DES_Boolean1[Node] = true
                        call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node], null)
                    
                        //Damage enemy units
                        loop
                            set u = FirstOfGroup(udg_DES_TempGroup)
                            exitwhen u == null
                            
                            if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                                call DestroyEffect(AddSpecialEffectTarget(DES_DImpactDamageEffect(), u, DES_AttachmentPoint()))
                                call UnitDamageTarget(udg_DES_Caster[Node], u, udg_DES_Real3[Node], false, false, DES_DAttackType(), DES_DDamageType(), DES_DWeaponType())
                                call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - udg_DES_Real4[Node])
                            endif
                            
                            call GroupRemoveUnit(udg_DES_TempGroup, u)
                        endloop
                        
                        //Play Effects
                        set u = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, 0)
                        call SetUnitScale(u, DES_DImpactScaleBase() + (udg_DES_Real1[Node] * DES_DImpactScalePerPowerLevel()), 0., 0.)
                        call DestroyEffect(AddSpecialEffectTarget(DES_DImpactEffect(), u, DES_AttachmentPoint()))
                        call DestroyEffect(udg_DES_SecondaryEffect[Node])
                        
                        //Set up data
                        set udg_DES_Real2[Node] = DES_DPassiveDamageAOEBase() + (udg_DES_Real1[Node] * DES_DPassiveDamageAOEPerPowerLevel())
                        set udg_DES_Real3[Node] = DES_DPassiveDamageHealthBase() + (udg_DES_Real1[Node] * DES_DPassiveDamageHealthPerPowerLevel())
                        set udg_DES_Real4[Node] = DES_DPassiveDamageManaBase() + (udg_DES_Real1[Node] * DES_DPassiveDamageManaPerPowerLevel())
                        set udg_DES_Real5[Node] = DES_DPassiveDelayBase() + (udg_DES_Real1[Node] * DES_DPassiveDelayPerPowerLevel())
                        set udg_DES_Real6[Node] = udg_DES_Real5[Node]
                        
                        call UnitApplyTimedLife(u, DES_TimedLifeID(), DES_EffectExpirationTimer())
                        call UnitApplyTimedLife(udg_DES_Unit[Node], DES_TimedLifeID(), DES_DTimedLifeBase() * (udg_DES_Real1[Node] * DES_DTimedLifePerPowerLevel()))
                    
                        set u = null
                        //Check for Combo Capability
                        call DES_ComboCollisionDetection(x, y, Node)
                        
                    endif
                    
                //Passive Damage
                elseif (udg_DES_Real6[Node] <= 0) then
                    set udg_DES_Real6[Node] = udg_DES_Real5[Node]
                    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node], null)
                    
                    //Damage enemy units
                   loop
                        set u = FirstOfGroup(udg_DES_TempGroup)
                        exitwhen u == null
                        
                        if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                            call DestroyEffect(AddSpecialEffectTarget(DES_DDamageEffect(), u, DES_AttachmentPoint()))
                            call UnitDamageTarget(udg_DES_Caster[Node], u, udg_DES_Real3[Node], false, false, DES_DAttackType(), DES_DDamageType(), DES_DWeaponType())
                            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - udg_DES_Real4[Node])
                        endif
                        
                        call GroupRemoveUnit(udg_DES_TempGroup, u)
                    endloop
                    
                else
                    set udg_DES_Real6[Node] = udg_DES_Real6[Node] - DES_TimerSpeed()
                endif
            
            endif
        //Justice Orbs
        elseif (udg_DES_StageID[Node] == DES_JStageID()) then
            
            //Check if the Orb is still alive
            if (IsUnitType(udg_DES_Unit[Node], UNIT_TYPE_DEAD)) or (GetUnitTypeId(udg_DES_Unit[Node]) == null) then
                call DestroyEffect(AddSpecialEffectTarget(DES_JDeathEffect(), udg_DES_Unit[Node], DES_AttachmentPoint()))
                call DES_SlowScan(Node)
                //Recycle
                call DES_Recycle(Node)
                set TempInt = TempInt - 1
            else
                //Get the current Coordinates of the Orb
                set x = GetUnitX(udg_DES_Unit[Node])
                set y = GetUnitY(udg_DES_Unit[Node])
                call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node], null)
                
                //Passive Slow
                loop
                    set u = FirstOfGroup(udg_DES_TempGroup)
                    exitwhen u == null
                    
                    if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                    
                        if (UnitAddAbility(u, DES_SlowID())) then
                            set TempNode = DES_CreateNode()
                            set udg_DES_Unit[TempNode] = u
                            set udg_DES_Core[TempNode] = udg_DES_Unit[Node]
                            call SetUnitAbilityLevel(udg_DES_Unit[TempNode], DES_SlowID(), udg_DES_Integer2[Node])
                            set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_JSlowEffect(), u, DES_AttachmentPoint())
                            set udg_DES_Integer1[TempNode] = Node
                            set udg_DES_Boolean1[TempNode] = false
                            set udg_DES_Boolean2[TempNode] = true
                            set udg_DES_Boolean3[TempNode] = false
                            set udg_DES_Boolean4[TempNode] = false
                            set udg_DES_StageID[TempNode] = DES_UnitStageID()
                        endif
                        
                    endif
                    
                    call GroupRemoveUnit(udg_DES_TempGroup, u)
                endloop
                
                //Check if the Orb is still moving
                if (udg_DES_Boolean3[Node] == true) then
                    
                    //Move the Orb
                    if (DES_ProjectileHandler(Node)) then
                        set udg_DES_Boolean3[Node] = false
                        call UnitApplyTimedLife(udg_DES_Unit[Node], DES_TimedLifeID(), DES_JTimedLifeBase() * (udg_DES_Real1[Node] * DES_JTimedLifePerPowerLevel()))
                        call DestroyEffect(udg_DES_SecondaryEffect[Node])
                    endif

                endif
            
            endif
            
        //Large Destruction Orbs
        elseif (udg_DES_StageID[Node] == DES_LargeDStageID()) then
            
            //Move the Orb
            if (DES_ProjectileHandler(Node)) then
                //Get The current Coordinates of the Orb
                set x = GetUnitX(udg_DES_Unit[Node])
                set y = GetUnitY(udg_DES_Unit[Node])
                call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node], null)
                
                //Damage Enemy Units
                loop
                    set u = FirstOfGroup(udg_DES_TempGroup)
                    exitwhen u == null
                    
                    if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                        call DestroyEffect(AddSpecialEffectTarget(DES_DImpactDamageEffect(), u, DES_AttachmentPoint()))
                        call UnitDamageTarget(udg_DES_Caster[Node], u, udg_DES_Real3[Node], false, false, DES_DAttackType(), DES_DDamageType(), DES_DWeaponType())
                        call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - udg_DES_Real4[Node])
                    endif
                    
                    call GroupRemoveUnit(udg_DES_TempGroup, u)
                endloop
                
                //Create smaller Orbs
                set z = DES_GetZ(x, y)
                set iLoop = 0
                
                loop
                    set iLoop = iLoop + 1
                    exitwhen iLoop > udg_DES_Integer1[Node]
                    set Angle = GetRandomReal(-bj_PI,bj_PI)
                    set TempReal = GetRandomReal(DES_DMinSpreadAOE(), udg_DES_Real2[Node])
                    set x2 = x + TempReal * Cos(Angle)
                    set y2 = y + TempReal * Sin(Angle)
                    set z2 = DES_GetZ(x2 , y2)
                
                    //Set up Orb Data
                    set TempNode = DES_CreateNode()
                    set udg_DES_Real1[TempNode] = udg_DES_Real8[Node]
                    set udg_DES_Real2[TempNode] = DES_DImpactAOEBase() + (udg_DES_Real1[TempNode] * DES_DImpactAOEPerPowerLevel())
                    set udg_DES_Real3[TempNode] = DES_DImpactDamageHealthBase() + (udg_DES_Real1[TempNode] * DES_DImpactDamageHealthPerPowerLevel())
                    set udg_DES_Real4[TempNode] = DES_DImpactDamageManaBase() + (udg_DES_Real1[TempNode] * DES_DImpactDamageManaPerPowerLevel())
                    
                    if (DES_CTrueOrIncomingSpeed()) then
                        set udg_DES_Real5[TempNode] = DES_DTrueSpeedBase() + (udg_DES_Real1[TempNode] * DES_DTrueSpeedPerPowerLevel())
                    else
                        set udg_DES_Real5[TempNode] = TempReal / ((DES_DIncomingTimeBase() + (udg_DES_Real1[TempNode] * DES_DIncomingTimePerPowerLevel())) / DES_TimerSpeed())
                    endif
                    
                    set TempReal = TempReal / udg_DES_Real5[TempNode]
                    set udg_DES_Real6[TempNode] = udg_DES_Real5[TempNode] * Cos(Angle)
                    set udg_DES_Real7[TempNode] = udg_DES_Real5[TempNode] * Sin(Angle)
                    set udg_DES_Real5[TempNode] = ((z2 - z) + ((DES_Gravity() * (TempReal) * (TempReal)) / 2)) / TempReal
                    set udg_DES_Boolean1[TempNode] = false
                    set udg_DES_Boolean2[TempNode] = false
                    set udg_DES_Boolean3[TempNode] = false
                    set udg_DES_Boolean4[TempNode] = false
                    set udg_DES_StageID[TempNode] = DES_DStageID()
                    set udg_DES_Caster[TempNode] = udg_DES_Caster[Node]
                    set udg_DES_Core[TempNode] = udg_DES_Core[Node]
                    set udg_DES_Player[TempNode] = GetOwningPlayer(udg_DES_Caster[TempNode])
                
                    //Set up Orb Unit
                    set udg_DES_Unit[TempNode] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, Angle * bj_RADTODEG)
                    set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_DOrbEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint())
                    set udg_DES_SecondaryEffect[TempNode] = AddSpecialEffectTarget(DES_DMoveEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint())
                    call SetUnitScale(udg_DES_Unit[TempNode], DES_DOrbScaleBase() + (udg_DES_Real1[TempNode] * DES_DOrbScalePerPowerLevel()), 0, 0)
                    
                    if UnitAddAbility(udg_DES_Unit[TempNode], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[TempNode], 'Amrf') then
                    endif

                endloop
                
                //Play Effects
                set u = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, 0)
                call SetUnitScale(u, DES_DImpactScaleBase() + (udg_DES_Real1[Node] * DES_DImpactScalePerPowerLevel()), 0., 0.)
                call DestroyEffect(AddSpecialEffectTarget(DES_DImpactEffect(), u, DES_AttachmentPoint()))
                call DestroyEffect(udg_DES_SecondaryEffect[Node])
                call DestroyEffect(udg_DES_CurrentEffect[Node])

                call UnitApplyTimedLife(u, DES_TimedLifeID(), DES_EffectExpirationTimer())
                call UnitApplyTimedLife(udg_DES_Unit[Node], DES_TimedLifeID(), DES_EffectExpirationTimer())
                //Recycle
                call DES_Recycle(Node)
                set TempInt = TempInt - 1
                
                set u = null
            endif
            
        //Afflicted Units
        elseif (udg_DES_StageID[Node] == DES_UnitStageID()) then
        
            //Check if the unit is on Fire
            if (udg_DES_Boolean1[Node]) then
                
                //Check if the unit is still alive
                if (IsUnitType(udg_DES_Unit[Node], UNIT_TYPE_DEAD) or (GetUnitTypeId(udg_DES_Unit[Node]) == null)) then
                    //Play Effects
                    call DestroyEffect(udg_DES_CurrentEffect[Node])
                    call DestroyEffect(AddSpecialEffectTarget(DES_TrialExplodeEffect(), udg_DES_Unit[Node], DES_AttachmentPoint()))
                    call UnitRemoveAbility(udg_DES_Unit[Node], DES_BurnID())
                    set x = GetUnitX(udg_DES_Unit[Node])
                    set y = GetUnitY(udg_DES_Unit[Node])
                    
                    //Damage Enemy Units
                    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node], null)
                    
                    loop
                        set u = FirstOfGroup(udg_DES_TempGroup)
                        exitwhen u == null
                        
                        if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                            call UnitDamageTarget(udg_DES_Caster[Node], u, udg_DES_Real3[Node], false, false, DES_TrialAttackType(), DES_TrialDamageType(), DES_TrialWeaponType())
                            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - udg_DES_Real4[Node])
                        endif
                        
                        call GroupRemoveUnit(udg_DES_TempGroup, u)
                    endloop
                    
                    //Recycle
                    call DES_Recycle(Node)
                    set TempInt = TempInt - 1
                else
                    //Apply Buff
                    set udg_DES_Real7[Node] = udg_DES_Real7[Node] - DES_TimerSpeed()
                    call UnitAddAbility(udg_DES_Unit[Node], DES_BurnID())
                    
                    //Burn over Time
                    if (udg_DES_Real7[Node] > 0.00) then
                    
                        //Damage unit
                        if (udg_DES_Real9[Node] <= 0.00) then
                            set udg_DES_Real9[Node] = udg_DES_Real8[Node]
                            call UnitDamageTarget(udg_DES_Caster[Node], udg_DES_Unit[Node], udg_DES_Real5[Node], false, false, DES_TrialAttackType(), DES_TrialDamageType(), DES_TrialWeaponType())
                            call SetUnitState(udg_DES_Unit[Node], UNIT_STATE_MANA, GetUnitState(udg_DES_Unit[Node], UNIT_STATE_MANA) - udg_DES_Real6[Node])
                        else
                            set udg_DES_Real9[Node] = udg_DES_Real9[Node] - DES_TimerSpeed()
                        endif
                        
                    else
                        call UnitRemoveAbility(udg_DES_Unit[Node], DES_BurnID())
                        call DestroyEffect(udg_DES_CurrentEffect[Node])
                        //Recycle
                        call DES_Recycle(Node)
                        set TempInt = TempInt - 1
                    endif
                    
                endif
                
            //Check if the unit is being slowed
            elseif (udg_DES_Boolean2[Node]) then
            
                //Check if the unit is still alive
                if (IsUnitType(udg_DES_Unit[Node], UNIT_TYPE_DEAD) or (GetUnitTypeId(udg_DES_Unit[Node]) == null)) then
                    call UnitRemoveAbility(udg_DES_Unit[Node], DES_SlowID())
                    call DestroyEffect(udg_DES_CurrentEffect[Node])
                    //Recycle
                    call DES_Recycle(Node)
                    set TempInt = TempInt - 1
                else
                    //Check how far the unit is away from its Orb
                    set x = GetUnitX(udg_DES_Unit[Node])
                    set y = GetUnitY(udg_DES_Unit[Node])
                    set x2 = GetUnitX(udg_DES_Unit[udg_DES_Integer1[Node]])
                    set y2 = GetUnitY(udg_DES_Unit[udg_DES_Integer1[Node]])
                    set TempReal = SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y))
                    
                    if (TempReal > udg_DES_Real2[udg_DES_Integer1[Node]]) then
                        call UnitRemoveAbility(udg_DES_Unit[Node], DES_SlowID())
                        call DestroyEffect(udg_DES_CurrentEffect[Node])
                        //Recycle
                        call DES_Recycle(Node)
                        set TempInt = TempInt - 1
                    endif
                    
                endif
                
            //Check if the unit is under the effect of Countdown
            elseif (udg_DES_Boolean3[Node]) then
            
                //Check if the unit is still alive
                if (IsUnitType(udg_DES_Unit[Node], UNIT_TYPE_DEAD) or (GetUnitTypeId(udg_DES_Unit[Node]) == null)) then
                    call UnitRemoveAbility(udg_DES_Unit[Node], DES_CountdownID())
                    call DestroyEffect(udg_DES_CurrentEffect[Node])
                    call DES_Recycle(Node)
                    set TempInt = TempInt - 1
                else
                    //Check how far the unit is away from the ultimate centre
                    set x = GetUnitX(udg_DES_Unit[Node])
                    set y = GetUnitY(udg_DES_Unit[Node])
                    set x2 = GetUnitX(udg_DES_Unit[udg_DES_Integer1[Node]])
                    set y2 = GetUnitY(udg_DES_Unit[udg_DES_Integer1[Node]])
                    set TempReal = SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y))
                    
                    if (TempReal > udg_DES_Real4[udg_DES_Integer1[Node]]) then
                        call UnitRemoveAbility(udg_DES_Unit[Node], DES_CountdownID())
                        call DestroyEffect(udg_DES_CurrentEffect[Node])
                        //recycle
                        call DES_Recycle(Node)
                        set TempInt = TempInt - 1
                    endif
                    
                endif
                
            //Check if the unit is being knocked back & In flight
            elseif (udg_DES_Boolean4[Node]) then
            
                //Move the unit
                if (DES_ProjectileHandler(Node)) then
                    set udg_DES_Boolean4[Node] = false
                    call DestroyEffect(udg_DES_CurrentEffect[Node])
                    //Do fall damage
                    call UnitDamageTarget(udg_DES_Caster[Node], udg_DES_Unit[Node], (DES_FallDamageMultiplyer() * (-udg_DES_Real5[Node])), false, false, DES_PAttackType(), DES_PDamageType(), DES_PWeaponType())
                    call SetUnitState(udg_DES_Unit[Node], UNIT_STATE_MANA, GetUnitState(udg_DES_Unit[Node], UNIT_STATE_MANA) - (DES_FallDamageMultiplyer() * (-udg_DES_Real5[Node])))
                endif
                
            //Unit is being knocked back (on the ground)
            else
                //Get the current coordinates of the unit
                set x = GetUnitX(udg_DES_Unit[Node])
                set y = GetUnitY(udg_DES_Unit[Node])
                //Calculate new speeds
                set udg_DES_Real6[Node] = udg_DES_Real6[Node] * DES_GroundDrag()
                set udg_DES_Real7[Node] = udg_DES_Real7[Node] * DES_GroundDrag()
                set TempReal = SquareRoot((udg_DES_Real6[Node] * udg_DES_Real6[Node]) + (udg_DES_Real7[Node] * udg_DES_Real7[Node]))
                
                //Check if the unit should stop
                if (TempReal <= DES_GroundDragStop()) then
                    //Recycle
                    call DES_Recycle(Node)
                    set TempInt = TempInt - 1
                //Check if the new point is valid
                elseif (DES_ValidateLocation(x, y)) then
                
                    //Check if any trees need to be destroyed
                    if (DES_DestroyTrees()) then
                        call DES_GetTrees(x, y)
                    endif
                    
                    //Move the unit
                    call SetUnitX(udg_DES_Unit[Node], x + udg_DES_Real6[Node])
                    call SetUnitY(udg_DES_Unit[Node], y + udg_DES_Real7[Node])
                endif
                
            endif
        //Ultimate
        elseif (udg_DES_StageID[Node] == DES_UltimateStageID()) then
        
            //Check that the ultimate is not ending
            if (udg_DES_Integer1[Node] <= DES_UltimateDivineStormTypeID()) then
                set x = GetUnitX(udg_DES_Unit[Node])
                set y = GetUnitY(udg_DES_Unit[Node])
                
                set udg_DES_Real12[Node] = udg_DES_Real12[Node] + udg_DES_Real9[Node]
                set TempInt2 = TempInt
                set TempNode = Node
                
                //Control Orbit of Stacks
                loop
                    set TempInt2 = TempInt2 + 1
                    exitwhen TempInt2 > udg_DES_AbilityCounter
                    set TempNode = udg_DES_NextNode[TempNode]
                    
                    if (udg_DES_Boolean2[TempNode] == true) and (udg_DES_Core[TempNode] == udg_DES_Unit[Node]) then
                        set Angle = (udg_DES_Real12[Node] + (DES_PSmallOrbAngleOffset() * udg_DES_StageID[TempNode])) * bj_DEGTORAD
                        call SetUnitX(udg_DES_Unit[TempNode], x + udg_DES_Real8[Node] * Cos(Angle))
                        call SetUnitY(udg_DES_Unit[TempNode], y + udg_DES_Real8[Node] * Sin(Angle))
                        
                        if (udg_DES_Integer1[Node] == DES_UltimateDivineStartTypeID()) then
                            call SetUnitFlyHeight(udg_DES_Unit[TempNode], GetUnitFlyHeight(udg_DES_Unit[TempNode]) + udg_DES_Real6[Node], 0.)
                        endif
                        
                    endif
                    
                    if (udg_DES_Integer1[Node] == DES_UltimateDivineStartTypeID()) and (udg_DES_Boolean4[TempNode] == true) and (udg_DES_Core[TempNode] == udg_DES_Unit[Node]) then
                        call SetUnitFlyHeight(udg_DES_Unit[TempNode], GetUnitFlyHeight(udg_DES_Unit[TempNode]) + udg_DES_Real3[Node], 0.)
                    endif
                    
                endloop
                
            endif
            
            //Check if the ultimate is currently pulling in units and orbs
            if (udg_DES_Integer1[Node] == DES_UltimatePullingTypeID()) then
                set udg_DES_Real2[Node] = udg_DES_Real2[Node] - DES_TimerSpeed()
                set udg_DES_Real11[Node] = udg_DES_Real11[Node] - DES_TimerSpeed()
                
                //Check if there's time left for pulling
                if (udg_DES_Real2[Node] > 0) then
                    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real1[Node], null)
                    
                    set TempInt2 = 0
                    set TempNode = 0
                    
                    //Get Orbs to pull
                    loop
                        set TempInt2 = TempInt2 + 1
                        exitwhen TempInt2 > udg_DES_AbilityCounter
                        set TempNode = udg_DES_NextNode[TempNode]
                        
                        //Check if the Orb is a valid target
                        if (not(udg_DES_Core[TempNode] == udg_DES_Unit[Node])) and (udg_DES_StageID[TempNode] <= DES_JStageID()) and (udg_DES_Boolean1[TempNode] == true) and (udg_DES_Boolean3[TempNode] == false) and (udg_DES_Boolean4[TempNode] == false) and (GetUnitTypeId(udg_DES_Unit[Node]) == DES_DummyID()) then
                            
                            set x2 = GetUnitX(udg_DES_Unit[TempNode])
                            set y2 = GetUnitY(udg_DES_Unit[TempNode])
                            //Find the distance to the Orb
                            set TempReal = SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y))
                            
                            //Check if the Orb is close enough to pull
                            if (TempReal <= udg_DES_Real1[Node]) then
                            
                                set Angle = Atan2(y - y2, x - x2)
                                //Check if the Orb is within absorbing range
                                if (TempReal > udg_DES_Real8[Node]) then
                                    call SetUnitX(udg_DES_Unit[TempNode], x2 + udg_DES_Real7[Node] * Cos(Angle))
                                    call SetUnitY(udg_DES_Unit[TempNode], y2 + udg_DES_Real7[Node] * Sin(Angle))
                                    
                                    //Make the Orb uninteractable
                                    if (udg_DES_Boolean2[TempNode] == false) then
                                        set udg_DES_Boolean2[TempNode] = true
                                    endif
                                    
                                else
                                    //Play Effects
                                    call DestroyEffect(udg_DES_CurrentEffect[TempNode])
                                    call DestroyEffect(AddSpecialEffectTarget(DES_PAbsorbEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint()))
                                    call UnitApplyTimedLife(udg_DES_Unit[TempNode], DES_TimedLifeID(), DES_EffectExpirationTimer())
                                    
                                    //Find what kind of Orb was absorbed
                                    //Then check if another can be added to the stack
                                    //If so, then add the Orb
                                    if (udg_DES_StageID[TempNode] == DES_CStageID()) then
                                        set udg_DES_Real4[Node] = udg_DES_Real4[Node] + udg_DES_Real1[TempNode]
                                        
                                        if (udg_DES_Real4[Node] >= udg_DES_Real3[Node]) then
                                            set udg_DES_Real4[Node] = udg_DES_Real4[Node] - udg_DES_Real3[Node]
                                            call DES_AddOrb(Node, DES_CStageID(), x, y, udg_DES_Real13[Node] * udg_DES_Integer2[Node], Angle)
                                            set udg_DES_Integer2[Node] = udg_DES_Integer2[Node] + 1
                                        endif
                                        
                                    elseif (udg_DES_StageID[TempNode] == DES_DStageID()) then
                                        set udg_DES_Real5[Node] = udg_DES_Real5[Node] + udg_DES_Real1[TempNode]
                                        
                                        if (udg_DES_Real5[Node] >= udg_DES_Real3[Node]) then
                                            set udg_DES_Real5[Node] = udg_DES_Real5[Node] - udg_DES_Real3[Node]
                                            call DES_AddOrb(Node, DES_DStageID(), x, y, udg_DES_Real13[Node] * udg_DES_Integer3[Node], Angle)
                                            set udg_DES_Integer3[Node] = udg_DES_Integer3[Node] + 1
                                        endif
                                        
                                    else
                                        call DES_SlowScan(TempNode)
                                        set udg_DES_Real6[Node] = udg_DES_Real6[Node] + udg_DES_Real1[TempNode]
                                        
                                        if (udg_DES_Real6[Node] >= udg_DES_Real3[Node]) then
                                            set udg_DES_Real6[Node] = udg_DES_Real6[Node] - udg_DES_Real3[Node]
                                            call DES_AddOrb(Node, DES_JStageID(), x, y, udg_DES_Real13[Node] * udg_DES_Integer4[Node], Angle)
                                            set udg_DES_Integer4[Node] = udg_DES_Integer4[Node] + 1
                                        endif
                                        
                                    endif
                                    
                                    //Recycle the Absorbed Orb
                                    call DES_Recycle(TempNode)
                                    set TempInt = TempInt - 1
                                    set TempInt2 = TempInt2 - 1
                                endif
                                
                            endif
                            
                        endif
                        
                    endloop
                    
                    //Get Units to Pull
                    loop
                        set u = FirstOfGroup(udg_DES_TempGroup)
                        exitwhen u == null
                        
                        if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                            
                            //Check if it's time to run a pull effect
                            if (udg_DES_Real11[Node] <= 0) then
                                call DestroyEffect(AddSpecialEffectTarget(DES_PPullEffect(), u, DES_AttachmentPoint()))
                            endif
                            
                            set x2 = GetUnitX(u)
                            set y2 = GetUnitY(u)
                            set Angle = Atan2(y - y2, x - x2)

                            //Check if there are trees to be absorbed
                            if (DES_DestroyTrees()) then
                                call DES_GetTrees(x2, y2)
                            endif
                            
                            //Pull Units
                            if (DES_ValidateLocation(x2, y2)) and (not(IsTerrainPathable(x2, y2, PATHING_TYPE_WALKABILITY))) then
                                call SetUnitX(u, x2 + udg_DES_Real7[Node] * Cos(Angle))
                                call SetUnitY(u, y2 + udg_DES_Real7[Node] * Sin(Angle))
                            endif
                            
                        endif
                        
                        call GroupRemoveUnit(udg_DES_TempGroup, u)
                    endloop
                    
                    if (udg_DES_Real11[Node] <= 0) then
                        set udg_DES_Real11[Node] = udg_DES_Real10[Node]
                    endif
                    
                else
                    
                    set TempInt2 = 0
                    set TempNode = 0
                    
                    //Find Orbs in proximity which were being pulled
                    //and now need to be released
                    loop
                        set TempInt2 = TempInt2 + 1
                        exitwhen TempInt2 > udg_DES_AbilityCounter
                        set TempNode = udg_DES_NextNode[TempNode]
                        if (not(udg_DES_Core[TempNode] == udg_DES_Unit[Node])) and (udg_DES_StageID[TempNode] <= DES_JStageID()) and (udg_DES_Boolean1[TempNode] == true) and (udg_DES_Boolean1[TempNode] == true) and (udg_DES_Boolean3[TempNode] == false) and (udg_DES_Boolean4[TempNode] == false) and (GetUnitTypeId(udg_DES_Unit[Node]) == DES_DummyID()) then
                            set x2 = GetUnitX(udg_DES_Unit[TempNode])
                            set y2 = GetUnitY(udg_DES_Unit[TempNode])
                            set TempReal = SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y))
                            
                            //Make the Orb Interactable
                            if (TempReal <= udg_DES_Real1[Node]) then
                                set udg_DES_Boolean2[TempNode] = false
                            endif
                            
                        endif
                        
                    endloop
                    
                    //Find out which effect to run
                    set udg_DES_Real1[Node] = udg_DES_Real3[Node] * udg_DES_Integer2[Node]
                    
                    if (udg_DES_Integer4[Node] == udg_DES_Integer3[Node]) and (udg_DES_Integer4[Node] == udg_DES_Integer2[Node]) then
                        //Divine Envoy Data
                        set udg_DES_Integer1[Node] = DES_UltimateDivineStartTypeID()
                        set udg_DES_Real2[Node] = (DES_PDivineAscensionTimeBase() + (udg_DES_Real1[Node] * DES_PDivineAscensionTimePerPowerLevel()))
                        set udg_DES_Real3[Node] = (DES_PDivineHeightIncreaseBase() + (udg_DES_Real1[Node] * DES_PDivineHeightIncreasePerPowerLevel()))
                        set udg_DES_Real4[Node] = (DES_PDivineSmallOrbsOffsetIncreaseBase() + (udg_DES_Real1[Node] * DES_PDivineSmallOrbsOffsetIncreasePerPowerLevel())) / (udg_DES_Real2[Node] / DES_TimerSpeed())
                        set udg_DES_Real5[Node] = GetUnitFlyHeight(udg_DES_Unit[Node])
                        set udg_DES_Real6[Node] = (((udg_DES_Real3[Node] + udg_DES_Real5[Node]) - ((udg_DES_Integer2[Node] * udg_DES_Real13[Node]))) / 2.) / (udg_DES_Real2[Node] / DES_TimerSpeed())
                        set udg_DES_Real3[Node] = udg_DES_Real3[Node] / (udg_DES_Real2[Node] / DES_TimerSpeed())
                    else
                    
                        set udg_DES_Real2[Node] = udg_DES_Real3[Node] * udg_DES_Integer3[Node]
                        set udg_DES_Real3[Node] = udg_DES_Real3[Node] * udg_DES_Integer4[Node]
                        
                        if (udg_DES_Integer3[Node] > udg_DES_Integer2[Node]) then
                        
                            if (udg_DES_Integer4[Node] > udg_DES_Integer3[Node]) then
                                //Countdown Data
                                call DES_UltimateCountStart(Node)
                            else
                                //Armageddon Data
                                set udg_DES_Integer1[Node] = DES_UltimateArmaTypeID()
                                set udg_DES_Real4[Node] = DES_PArmaAOEBase() + (udg_DES_Real1[Node] * DES_PArmaAOEPerPowerLevel())
                                set udg_DES_Real5[Node] = DES_PArmaProjectilesPerSecondBase() + (udg_DES_Real2[Node] * DES_PArmaProjectilesPerSecondPerPowerLevel())
                                set udg_DES_Real6[Node] = DES_PArmaDurationBase() + (udg_DES_Real3[Node] * DES_PArmaDurationPerPowerLevel())
                                set udg_DES_Real7[Node] = (DES_PArmaLaunchDelayBase() + (udg_DES_Real2[Node] * DES_PArmaLaunchDelayPerPowerLevel()))
                                set udg_DES_Real10[Node] = udg_DES_Real5[Node] / (udg_DES_Real7[Node] / DES_TimerSpeed())
                                set udg_DES_Real11[Node] = udg_DES_Real7[Node]
                            endif
                            
                        elseif (udg_DES_Integer2[Node] > udg_DES_Integer4[Node]) then
                            //Wild Growth Data
                            set udg_DES_Integer1[Node] = DES_UltimateWildTypeID()
                            set udg_DES_Real4[Node] = DES_PWildAOEBase() + (udg_DES_Real2[Node] * DES_PWildAOEPerPowerLevel())
                            set udg_DES_Real5[Node] = DES_PWildStartAOEBase() + (udg_DES_Real2[Node] * DES_PWildStartAOEPerPowerLevel())
                            set udg_DES_Real6[Node] = (udg_DES_Real4[Node] - udg_DES_Real5[Node]) / (DES_PWildExpandRingCountBase() + (udg_DES_Real2[Node] * DES_PWildExpandRingCountPerPowerLevel()))
                            set udg_DES_Real7[Node] = udg_DES_Real5[Node]
                            set udg_DES_Real10[Node] = DES_PWildTreantDurationBase() + (udg_DES_Real3[Node] * DES_PWildTreantDurationPerPowerLevel())
                            set udg_DES_Real11[Node] = DES_PWildTreantCountPerRingBase() + (udg_DES_Real1[Node] * DES_PWildTreantCountPerRingPerPowerLevel())
                            set udg_DES_Real1[Node] = DES_PWildTreantSpawnDelayBase() + (udg_DES_Real2[Node] * DES_PWildTreantSpawnDelayPerPowerLevel())
                            set udg_DES_Real13[Node] = udg_DES_Real1[Node]
                        else 
                            //Countdown Data
                            call DES_UltimateCountStart(Node)
                        endif
                    
                    endif
                    
                endif
                
            //Check if the ultimate is casting Wild Growth
            elseif (udg_DES_Integer1[Node] == DES_UltimateWildTypeID()) then
                
                //Check if it's time to spawn another ring
                if (udg_DES_Real13[Node] <= 0) then 
                
                    set udg_DES_Real13[Node] = udg_DES_Real1[Node]
                    set udg_DES_Real7[Node] = udg_DES_Real7[Node] + udg_DES_Real6[Node]
                    
                    //Check if the full size has been reached
                    if (udg_DES_Real7[Node] <= udg_DES_Real4[Node]) then

                        set iLoop = 0
                        set Angle = 0
                        set TempReal = (2 * bj_PI) / udg_DES_Real11[Node]
                        
                        //Spawn Treants
                        loop
                            set iLoop = iLoop + 1
                            exitwhen iLoop > udg_DES_Real11[Node]
                            set Angle = Angle + TempReal
                            
                            set x2 = x + udg_DES_Real7[Node] * Cos(Angle)
                            set y2 = y + udg_DES_Real7[Node] * Sin(Angle)
                            
                            set u = CreateUnit(udg_DES_Player[Node], DES_TreantID(), x2, y2, Angle * bj_RADTODEG)
                            call DestroyEffect(AddSpecialEffectTarget(DES_PWildSpawnEffect(), u, DES_AttachmentPoint()))
                            call UnitApplyTimedLife(u, DES_TimedLifeID(), udg_DES_Real10[Node])
                        endloop
                        
                    else
                        //Recycle
                        call DES_EndUltimate(Node)
                        set TempInt = TempInt - 1
                    endif
                    
                else
                    set udg_DES_Real13[Node] = udg_DES_Real13[Node] - DES_TimerSpeed()
                endif

            //Check if the ultimate is casting Armageddon   
            elseif (udg_DES_Integer1[Node] == DES_UltimateArmaTypeID()) then
                set udg_DES_Real6[Node] = udg_DES_Real6[Node] - DES_TimerSpeed()
                
                //Check if there's still time left
                if (udg_DES_Real6[Node] > 0) then
                
                    //Check if it's time to spawn a projectile
                    if (udg_DES_Real11[Node] <= 0) then
                        set udg_DES_Real11[Node] = udg_DES_Real7[Node]
                        set iLoop = 0
                        set z = GetUnitFlyHeight(udg_DES_Unit[Node])
                        
                        //Spawn Projectiles
                        loop
                            set iLoop = iLoop + 1
                            exitwhen iLoop >= udg_DES_Real10[Node]
                            
                            set TempReal = GetRandomReal(DES_PArmaMinAOE(), udg_DES_Real4[Node])
                            set Angle = GetRandomReal(-bj_PI, bj_PI)
                            set x2 = x + TempReal * Cos(Angle)
                            set y2 = y + TempReal * Sin(Angle)
                            set z2 = DES_GetZ(x2, y2)
                            
                            //set up data
                            set TempNode = DES_CreateNode()
                            set udg_DES_Real2[TempNode] = DES_PArmaProjectileAOEBase() + (udg_DES_Real1[Node] * DES_PArmaProjectileAOEPerPowerLevel())
                            set udg_DES_Real3[TempNode] = DES_PArmaProjectileHealthDamageBase() + (udg_DES_Real3[Node] * DES_PArmaProjectileHealthDamagePerPowerLevel())
                            set udg_DES_Real4[TempNode] = DES_PArmaProjectileManaDamageBase() + (udg_DES_Real3[Node] * DES_PArmaProjectileManaDamagePerPowerLevel())
                        
                            if (DES_PArmaTrueOrIncomingSpeed()) then
                                set udg_DES_Real5[TempNode] = DES_PArmaTrueSpeedBase() + (udg_DES_Real1[Node] * DES_PArmaTrueSpeedPerPowerLevel())
                            else
                                set udg_DES_Real5[TempNode] = TempReal / ((DES_PArmaIncomingTimeBase() + (udg_DES_Real1[Node] * DES_PArmaIncomingTimePerPowerLevel())) / DES_TimerSpeed())
                            endif

                            set TempReal = TempReal / udg_DES_Real5[TempNode]
                            set udg_DES_Real6[TempNode] = udg_DES_Real5[TempNode] * Cos(Angle)
                            set udg_DES_Real7[TempNode] = udg_DES_Real5[TempNode] * Sin(Angle)
                            set udg_DES_Real5[TempNode] = ((z2 - z) + ((DES_Gravity() * (TempReal) * (TempReal)) / 2)) / TempReal
                            set udg_DES_Boolean1[TempNode] = false
                            set udg_DES_Boolean2[TempNode] = false
                            set udg_DES_Boolean3[TempNode] = false
                            set udg_DES_Boolean4[TempNode] = false
                            set udg_DES_StageID[TempNode] = DES_PProjectileStageID()
                            set udg_DES_Caster[TempNode] = udg_DES_Caster[Node]
                            set udg_DES_Core[TempNode] = udg_DES_Caster[Node]
                            set udg_DES_Player[TempNode] = GetOwningPlayer(udg_DES_Caster[TempNode])
                        
                            //Set up Unit
                            set udg_DES_Unit[TempNode] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, Angle * bj_RADTODEG)
                            set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_PArmaProjectileEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint())
                            set udg_DES_SecondaryEffect[TempNode] = AddSpecialEffectTarget(DES_PArmaProjectileMoveEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint())
                            call SetUnitScale(udg_DES_Unit[TempNode], DES_PArmaProjectileScale(), 0, 0)

                            if UnitAddAbility(udg_DES_Unit[TempNode], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[TempNode], 'Amrf') then
                            endif
                            
                            call SetUnitFlyHeight(udg_DES_Unit[TempNode], z, 0.)
                        endloop
                        
                    else
                        set udg_DES_Real11[Node] = udg_DES_Real11[Node] - DES_TimerSpeed()
                    endif
                    
                else
                    //Recycle
                    call DES_EndUltimate(Node)
                    set TempInt = TempInt - 1
                endif
                
            //Check if the Ultimate is casting Countdown
            elseif (udg_DES_Integer1[Node] == DES_UltimateCountTypeID()) then
                set udg_DES_Real11[Node] = udg_DES_Real11[Node] - DES_TimerSpeed()
                
                //Check if there's still time left
                if (udg_DES_Real11[Node] > 0) then
                    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real4[Node], null)
                    
                    //Find nearby unaffected units
                    loop
                        set u = FirstOfGroup(udg_DES_TempGroup)
                        exitwhen u == null
                        
                        if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) or (DES_FriendlyTargetFilter(u, udg_DES_Player[Node])) then
                        
                            //Apply Countdown Data to unit
                            if (UnitAddAbility(u, DES_CountdownID())) then
                                set TempNode = DES_CreateNode()
                                set udg_DES_Unit[TempNode] = u
                                set udg_DES_Core[TempNode] = udg_DES_Unit[Node]
                                set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_PCountEffect(), u, DES_AttachmentPoint())
                                set udg_DES_Integer1[TempNode] = Node
                                set udg_DES_Boolean1[TempNode] = false
                                set udg_DES_Boolean2[TempNode] = false
                                set udg_DES_Boolean3[TempNode] = true
                                set udg_DES_Boolean4[TempNode] = false
                                set udg_DES_StageID[TempNode] = DES_UnitStageID()
                            endif
                            
                        endif
                        
                        call GroupRemoveUnit(udg_DES_TempGroup, u)
                    endloop
                    
                else
                    set TempNode = 0
                    set TempInt2 = 0
                    
                    //Check for affected units
                    loop
                        set TempInt2 = TempInt2 + 1
                        exitwhen TempInt2 > udg_DES_AbilityCounter
                        set TempNode = udg_DES_NextNode[TempNode]
                        
                        if (udg_DES_Core[TempNode] == udg_DES_Unit[Node]) and (udg_DES_Boolean3[TempNode] == true) and (udg_DES_StageID[TempNode] == DES_UnitStageID()) then
                            call UnitRemoveAbility(udg_DES_Unit[TempNode], DES_CountdownID())
                            call DestroyEffect(udg_DES_CurrentEffect[TempNode])
                            
                            //Damage enemies, heal allies
                            if (DES_EnemyTargetFilter(udg_DES_Unit[TempNode], udg_DES_Player[Node])) then
                                call DestroyEffect(AddSpecialEffectTarget(DES_PCountDamageEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint()))
                                call UnitDamageTarget(udg_DES_Caster[Node], udg_DES_Unit[TempNode], udg_DES_Real5[Node], false, false, DES_PAttackType(), DES_PDamageType(), DES_PWeaponType())
                                call SetUnitState(udg_DES_Unit[TempNode], UNIT_STATE_MANA, GetUnitState(udg_DES_Unit[TempNode], UNIT_STATE_MANA) - udg_DES_Real6[Node])
                            elseif (DES_FriendlyTargetFilter(udg_DES_Unit[TempNode], udg_DES_Player[Node])) then
                                call DestroyEffect(AddSpecialEffectTarget(DES_PCountHealEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint()))
                                call SetUnitState(udg_DES_Unit[TempNode], UNIT_STATE_LIFE, GetUnitState(udg_DES_Unit[TempNode], UNIT_STATE_LIFE) + udg_DES_Real7[Node])
                                call SetUnitState(udg_DES_Unit[TempNode], UNIT_STATE_MANA, GetUnitState(udg_DES_Unit[TempNode], UNIT_STATE_MANA) + udg_DES_Real8[Node])
                            endif
                            
                            call DES_Recycle(TempNode)
                            set TempInt2 = TempInt2 - 1
                        endif
                        
                    endloop
                    
                    //Recycle
                    call DES_EndUltimate(Node)
                    set TempInt = TempInt - 1
                endif
                
            //Check if the ultimate is casting Divine Envoy and is in the start phase
            elseif (udg_DES_Integer1[Node] == DES_UltimateDivineStartTypeID()) then
                set udg_DES_Real2[Node] = udg_DES_Real2[Node] - DES_TimerSpeed()
                
                //Check if it's done expanding
                if (udg_DES_Real2[Node] > 0) then
                    //expand ultimate
                    set udg_DES_Real5[Node] = udg_DES_Real5[Node] + udg_DES_Real3[Node]
                    set udg_DES_Real8[Node] = udg_DES_Real8[Node] + udg_DES_Real4[Node]
                    call SetUnitFlyHeight(udg_DES_Unit[Node], udg_DES_Real5[Node], 0.)
                else
                    //set up data for the next phase
                    set udg_DES_Integer1[Node] = DES_UltimateDivineStormTypeID()
                    set udg_DES_Real2[Node] = DES_PDivineStormAOEBase() + (udg_DES_Real1[Node] * DES_PDivineStormAOEPerPowerLevel())
                    set udg_DES_Real3[Node] = DES_PDivineStormAmountPerSecondBase() + (udg_DES_Real1[Node] * DES_PDivineStormAmountPerSecondPerPowerLevel())
                    set udg_DES_Real4[Node] = DES_PDivineStormDurationBase() + (udg_DES_Real1[Node] * DES_PDivineStormDurationPerPowerLevel())
                    set udg_DES_Real6[Node] = DES_PDivineStormHealthDamageBase() + (udg_DES_Real1[Node] * DES_PDivineStormHealthDamagePerPowerLevel())
                    set udg_DES_Real14[Node] = DES_PDivineStormManaDamageBase() + (udg_DES_Real1[Node] * DES_PDivineStormManaDamagePerPowerLevel())
                    set udg_DES_Real7[Node] = DES_PDivineStormHealthHealBase() + (udg_DES_Real1[Node] * DES_PDivineStormHealthHealPerPowerLevel())
                    set udg_DES_Real10[Node] = DES_PDivineStormManaHealBase() + (udg_DES_Real1[Node] * DES_PDivineStormManaHealPerPowerLevel())
                    set udg_DES_Real11[Node] = DES_PDivineStormDelayBase() + (udg_DES_Real1[Node] * DES_PDivineStormDelayPerPowerLevel())
                    set udg_DES_Real13[Node] = udg_DES_Real11[Node]
                    set udg_DES_Real15[Node] = DES_PDivineStormStrikeAOEBase() + (udg_DES_Real1[Node] * DES_PDivineStormStrikeAOEPerPowerLevel())
                    set udg_DES_Real16[Node] = DES_PDivineStormStrikeScaleBase() + (udg_DES_Real1[Node]* DES_PDivineStormStrikeScalePerPowerLevel())
                    set udg_DES_Real3[Node] = udg_DES_Real3[Node] * udg_DES_Real11[Node]
                endif
                
            //Check if the ultimate is casting Divine Envoy and is in the storm phrase
            elseif (udg_DES_Integer1[Node] == DES_UltimateDivineStormTypeID()) then
                set udg_DES_Real4[Node] = udg_DES_Real4[Node] - DES_TimerSpeed()
               
                //Check if there's still time left
                if (udg_DES_Real4[Node] > 0) then
                
                    //Check if it's time to create a lightning effect
                    if (udg_DES_Real13[Node] <= 0) then
                    
                        set udg_DES_Real13[Node] = udg_DES_Real11[Node]
                        set TempInt2 = 0
                    
                        //Create lightning effects
                        loop
                            set TempInt2 = TempInt2 + 1
                            exitwhen TempInt2 > udg_DES_Real3[Node]
                            set Angle = GetRandomReal(-bj_PI, bj_PI)
                            set TempReal = GetRandomReal(0, udg_DES_Real2[Node])
                            set x2 = x + TempReal * Cos(Angle)
                            set y2 = y + TempReal * Sin(Angle)
                            set TempReal = GetRandomReal(0, DES_PDivineStormLightningOffset())
                            set z = x +  TempReal * Cos(Angle)
                            set z2 = y + TempReal * Sin(Angle)
                            
                            //Set up Unit and Data
                            set TempNode = DES_CreateNode()
                            set udg_DES_Unit[TempNode] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x2, y2, Angle * bj_RADTODEG)
                            call SetUnitScale(udg_DES_Unit[TempNode], udg_DES_Real16[Node],0, 0)
                            set udg_DES_Lightning[TempNode] = AddLightningEx(DES_LightningID(), true, z, z2, udg_DES_Real5[Node] + DES_GetZ(z, z2), x2, y2, 0)
                            call SetLightningColor(udg_DES_Lightning[TempNode], DES_LightningRed(), DES_LightningGreen(), DES_LightningBlue(), DES_LightningAlpha())
                            call DestroyEffect(AddSpecialEffectTarget(DES_PDivineStormStrikeEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint()))
                            call UnitApplyTimedLife(udg_DES_Unit[TempNode], DES_TimedLifeID(), DES_EffectExpirationTimer())
                            set udg_DES_Real1[TempNode] = udg_DES_Real11[Node] + DES_TimerSpeed()
                            set udg_DES_StageID[TempNode] = DES_UltimateStageID()
                            set udg_DES_Integer1[TempNode] = DES_UltimateDivineLightningTypeID()
                            
                            call GroupEnumUnitsInRange(udg_DES_TempGroup, x2, y2, udg_DES_Real15[Node], null)
                            
                            //Damage Enemies, heal allies
                            loop
                                set u = FirstOfGroup(udg_DES_TempGroup)
                                exitwhen u == null
                                
                                if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                                    call DestroyEffect(AddSpecialEffectTarget(DES_PDivineStormDamageEffect(), u, DES_AttachmentPoint()))
                                    call UnitDamageTarget(udg_DES_Unit[Node], u, udg_DES_Real6[Node], false, false, DES_PAttackType(), DES_PDamageType(), DES_PWeaponType())
                                    call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - udg_DES_Real14[Node])
                                elseif (DES_FriendlyTargetFilter(u, udg_DES_Player[Node])) then
                                    call DestroyEffect(AddSpecialEffectTarget(DES_PDivineStormHealEffect(), u, DES_AttachmentPoint()))
                                    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + udg_DES_Real7[Node])
                                    call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) + udg_DES_Real10[Node])
                                endif
                                
                                call GroupRemoveUnit(udg_DES_TempGroup, u)
                            endloop
                            
                        endloop
                        
                    else
                        set udg_DES_Real13[Node] = udg_DES_Real13[Node] - DES_TimerSpeed()
                    endif
                //Create the Laser
                else
                    
                    //Set up Data
                    set TempNode = DES_CreateNode()
                    set udg_DES_Real1[TempNode] = DES_PDivineLaserAOEToScaleRatioBase() + (udg_DES_Real1[Node] * DES_PDivineLaserAOEToScaleRatioPerPowerLevel())
                    set udg_DES_Real2[TempNode] = DES_PDivineLaserStartScaleBase() + (udg_DES_Real1[Node] * DES_PDivineLaserStartScalePerPowerLevel())
                    set udg_DES_Real3[TempNode] = DES_PDivineLaserEndScaleBase() + (udg_DES_Real1[Node] * DES_PDivineLaserEndScalePerPowerLevel())
                    set udg_DES_Real4[TempNode] = DES_PDivineLaserHealthDamageBase() + (udg_DES_Real1[Node] * DES_PDivineLaserHealthDamagePerPowerLevel())
                    set udg_DES_Real5[TempNode] = DES_PDivineLaserManaDamageBase() + (udg_DES_Real1[Node] * DES_PDivineLaserManaDamagePerPowerLevel())
                    set udg_DES_Real6[TempNode] = DES_PDivineLaserHealthHealBase() + (udg_DES_Real1[Node] * DES_PDivineLaserHealthHealPerPowerLevel())
                    set udg_DES_Real7[TempNode] = DES_PDivineLaserManaHealBase() + (udg_DES_Real1[Node] * DES_PDivineLaserManaHealPerPowerLevel())
                    set udg_DES_Real8[TempNode] = DES_PDivineLaserKnockbackPowerBase() + (udg_DES_Real1[Node] * DES_PDivineLaserKnockbackPowerPerPowerLevel())
                    set udg_DES_Real9[TempNode] = DES_PDivineLaserKnockbackPowerCapBase() + (udg_DES_Real1[Node] * DES_PDivineLaserKnockbackPowerCapPerPowerLevel())
                    set udg_DES_Real10[TempNode] = (udg_DES_Real3[TempNode] - udg_DES_Real2[TempNode]) / ((DES_PDivineLaserTimerBase() + (udg_DES_Real1[Node] * DES_PDivineLaserTimerPerPowerLevel())) / DES_TimerSpeed())
                    set udg_DES_Boolean1[TempNode] = false
                    set udg_DES_Boolean2[TempNode] = false
                    set udg_DES_Boolean3[TempNode] = false
                    set udg_DES_Boolean4[TempNode] = true
                    set udg_DES_Integer1[TempNode] = DES_UltimateDivineLaserTypeID()
                    set udg_DES_Integer2[TempNode] = Node
                    set udg_DES_Integer3[TempNode] = 0
                    
                    //set up Unit
                    set udg_DES_Unit[TempNode] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, 0.)
                    set udg_DES_Core[TempNode] = udg_DES_Unit[Node]
                    set udg_DES_Caster[TempNode] = udg_DES_Caster[Node]
                    set udg_DES_Player[TempNode] = udg_DES_Player[Node]
                    set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_PDivineLaserEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint())
                    
                    if UnitAddAbility(udg_DES_Unit[TempNode], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[TempNode], 'Amrf') then
                    endif
                            
                    call SetUnitFlyHeight(udg_DES_Unit[TempNode], udg_DES_Real5[Node], 0.)
                    call SetUnitScale(udg_DES_Unit[TempNode], -udg_DES_Real2[TempNode], 0., 0.)
                    
                    set udg_DES_StageID[TempNode] = DES_UltimateStageID()
                    set udg_DES_Integer1[Node] = DES_UltimateWaitingTypeID()
                endif
                
            //Check if it is the Laser
            elseif (udg_DES_Integer1[Node] == DES_UltimateDivineLaserTypeID()) then
                set udg_DES_Real2[Node] = udg_DES_Real2[Node] + udg_DES_Real10[Node]
                
                //Check if the laser has finished expanding
                if (udg_DES_Real2[Node] < udg_DES_Real3[Node]) then
                    call SetUnitScale(udg_DES_Unit[Node], -udg_DES_Real2[Node], 0., 0.)
                    set x = GetUnitX(udg_DES_Unit[Node])
                    set y = GetUnitY(udg_DES_Unit[Node])
                    
                    call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node] * udg_DES_Real1[Node], null)
                    
                    //Find units
                    loop
                        set u = FirstOfGroup(udg_DES_TempGroup)
                        exitwhen u == null
                        
                        //Damage Enemies
                        if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                            //Player Effects
                            call DestroyEffect(AddSpecialEffectTarget(DES_PDivineLaserDamageEffect(), u, DES_AttachmentPoint()))
                            call UnitDamageTarget(udg_DES_Unit[Node], u, udg_DES_Real4[Node], false, false, DES_PAttackType(), DES_PDamageType(), DES_PWeaponType())
                            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - udg_DES_Real5[Node])
                            
                            set x2 = GetUnitX(u)
                            set y2 = GetUnitY(u)
                            set Angle = Atan2((y2 - y), (x2 - x))
                            set TempReal = SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y))
                            
                            //Limit the knockback strength
                            if (TempReal <= 0) then
                                set TempReal = udg_DES_Real9[Node]
                            else
                                set TempReal = udg_DES_Real8[Node] / TempReal
                                
                                if (TempReal >  udg_DES_Real9[Node]) then
                                    set TempReal = udg_DES_Real9[Node]
                                endif
                                
                            endif
                             
                            //Set up Data
                            set TempNode = DES_CreateNode()
                            set udg_DES_Unit[TempNode] = u
                            set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_KnockbackEffect(), u, DES_AttachmentPoint())
                            
                            set udg_DES_Real5[TempNode] = TempReal * Sin(DES_PDivineLaserKnockbackAngle())
                            set udg_DES_Real6[TempNode] = TempReal * Cos(DES_PDivineLaserKnockbackAngle()) * Cos(Angle)
                            set udg_DES_Real7[TempNode] = TempReal * Cos(DES_PDivineLaserKnockbackAngle()) * Sin(Angle)
                            set udg_DES_Boolean1[TempNode] = false
                            set udg_DES_Boolean2[TempNode] = false
                            set udg_DES_Boolean3[TempNode] = false
                            
                            if (DES_PDivineLaserKnockbackAngle() == 0.) then
                                set udg_DES_Boolean4[TempNode] = false
                            else
                                set udg_DES_Boolean4[TempNode] = true
                            endif
                            
                            //Set up Unit
                            set udg_DES_StageID[TempNode] = DES_UnitStageID()
                            set udg_DES_Caster[TempNode] = udg_DES_Caster[Node]
                            set udg_DES_Core[TempNode] = udg_DES_Unit[TempNode]
                            
                            if UnitAddAbility(udg_DES_Unit[TempNode], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[Node], 'Amrf') then
                            endif
                            
                        //Heal Allies
                        elseif (DES_FriendlyTargetFilter(u, udg_DES_Player[Node])) then
                            call DestroyEffect(AddSpecialEffectTarget(DES_PDivineLaserHealEffect(), u, DES_AttachmentPoint()))
                            call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + udg_DES_Real6[Node])
                            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) + udg_DES_Real7[Node])
                        endif
                        
                        call GroupRemoveUnit(udg_DES_TempGroup, u)
                    endloop
                            
                else
                    //Recycle
                    set udg_DES_StageID[Node] = DES_RecycleStageID()
                    call DES_EndUltimate(udg_DES_Integer2[Node])
                    set TempInt = TempInt - 1
                endif
            
            //Check if it's a lightning effect
            else
                set udg_DES_Real1[Node] = udg_DES_Real1[Node] - DES_TimerSpeed()
                
                //Check if it's time to remove the lightning
                if (udg_DES_Real1[Node] <= 0) then
                    call DestroyLightning(udg_DES_Lightning[Node])
                    //Recycle
                    call DES_Recycle(Node)
                    set TempInt = TempInt - 1
                endif
                
            endif
            
        //Check if it's a projectile from Armageddon
        elseif (udg_DES_StageID[Node] == DES_PProjectileStageID()) then
        
            //Move the projectile
            if (DES_ProjectileHandler(Node)) then
                set x = GetUnitX(udg_DES_Unit[Node])
                set y = GetUnitY(udg_DES_Unit[Node])
                call GroupEnumUnitsInRange(udg_DES_TempGroup, x, y, udg_DES_Real2[Node], null)
                
                //Damage Enemies
                loop
                    set u = FirstOfGroup(udg_DES_TempGroup)
                    exitwhen u == null
                    
                    if (DES_EnemyTargetFilter(u, udg_DES_Player[Node])) then
                        call DestroyEffect(AddSpecialEffectTarget(DES_PArmaDamageEffect(), u, DES_AttachmentPoint()))
                        call UnitDamageTarget(udg_DES_Caster[Node], u, udg_DES_Real3[Node], false, false, DES_PAttackType(), DES_PDamageType(), DES_PWeaponType())
                        call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - udg_DES_Real4[Node])
                    endif
                    
                    call GroupRemoveUnit(udg_DES_TempGroup, u)
                endloop
                
                //Play Effects
                call DestroyEffect(udg_DES_CurrentEffect[Node])
                call DestroyEffect(udg_DES_SecondaryEffect[Node])
                
                call UnitApplyTimedLife(udg_DES_Unit[Node], DES_TimedLifeID(), DES_EffectExpirationTimer())
                
                //Recycle
                call DES_Recycle(Node)
                set TempInt = TempInt - 1
            endif
            
        endif
        
    endloop
    
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to check that the ability being cast by a hero  //
//  is one of the abilities within the spellset, so that if it is //
//  the appropaite ability can begin                              //
////////////////////////////////////////////////////////////////////
function DES_OnCast takes nothing returns boolean

    //Sets up locals
    local unit u
    local integer Node
    local integer TempNode
    local integer iLevel
    local integer TempInt
    local integer TempInt2 = 0
    local real rLevel
    local real x
    local real x2
    local real x3
    local real y
    local real y2
    local real y3
    local real z
    local real z2
    local real AOE
    local real Angle = 0.
    local real Angle2
    local real Divider
    local real TempReal = 0.
    
    //Checks if the spell cast is the correct spell
    if (GetSpellAbilityId() == DES_CreationID()) then
        set u = GetTriggerUnit()
        set x = GetUnitX(u)
        set x2 = GetSpellTargetX()
        set y = GetUnitY(u)
        set y2 = GetSpellTargetY()
        set z = DES_GetZ(x, y) + GetUnitFlyHeight(u)
        set rLevel = I2R(GetUnitAbilityLevel(u, DES_CreationID()))
        set AOE = DES_CSpreadAOEBase() + (rLevel * DES_CSpreadAOEPerLevel())
        set Divider = (360 / (DES_COrbCountBase() + (rLevel * DES_COrbCountPerLevel())))
        
        //Create Orbs
        loop
            set Angle = Angle + Divider
            exitwhen Angle > 360
            set Angle2 = Angle * bj_DEGTORAD
            set x3 = x2 + AOE * Cos(Angle2)
            set y3 = y2 + AOE * Sin(Angle2)
            set z2 = DES_GetZ(x3, y3) + DES_GroundHeightLet()
            set TempReal = SquareRoot(((x3 - x) * (x3 - x)) + ((y3 - y) * (y3 - y)))
            set Angle2 = Atan2(y3 - y, x3 - x)
            
            //Set up Data
            set Node = DES_CreateNode()
            set udg_DES_Real1[Node] = DES_CPowerLevelBase() + (rLevel * DES_CPowerLevelPerLevel())
            set udg_DES_Real2[Node] = DES_CImpactAOEBase() + (udg_DES_Real1[Node] * DES_CImpactAOEPerPowerLevel())
            set udg_DES_Real3[Node] = DES_CImpactHealHealthBase() + (udg_DES_Real1[Node] * DES_CImpactHealHealthPerPowerLevel())
            set udg_DES_Real4[Node] = DES_CImpactHealManaBase() + (udg_DES_Real1[Node] * DES_CImpactHealManaPerPowerLevel())
            
            if (DES_CTrueOrIncomingSpeed()) then
                set udg_DES_Real5[Node] = DES_CTrueSpeedBase() + (udg_DES_Real1[Node] * DES_CTrueSpeedPerPowerLevel())
            else
                set udg_DES_Real5[Node] = TempReal / ((DES_CIncomingTimeBase() + (udg_DES_Real1[Node] * DES_CIncomingTimePerPowerLevel())) / DES_TimerSpeed())
            endif
            
            set udg_DES_Unit[Node] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, Angle2 * bj_RADTODEG)
            
            if (TempReal == 0.) then
                set udg_DES_Boolean1[Node] = true
                call UnitApplyTimedLife(udg_DES_Unit[Node], DES_TimedLifeID(), DES_CTimedLifeBase() * (udg_DES_Real1[Node] * DES_CTimedLifePerPowerLevel()))
            else
                set TempReal = TempReal / udg_DES_Real5[Node]
                set udg_DES_Real6[Node] = udg_DES_Real5[Node] * Cos(Angle2)
                set udg_DES_Real7[Node] = udg_DES_Real5[Node] * Sin(Angle2)
                set udg_DES_Real5[Node] = ((z2 - z) + ((DES_Gravity() * (TempReal) * (TempReal)) / 2)) / TempReal
                set udg_DES_Boolean1[Node] = false
                set udg_DES_SecondaryEffect[Node] = AddSpecialEffectTarget(DES_CMoveEffect(), udg_DES_Unit[Node], DES_AttachmentPoint())
            endif
            
            set udg_DES_Boolean2[Node] = false
            set udg_DES_Boolean3[Node] = false
            set udg_DES_Boolean4[Node] = false
            set udg_DES_StageID[Node] = DES_CStageID()
            set udg_DES_Caster[Node] = u
            set udg_DES_Core[Node] = udg_DES_Unit[Node]
            set udg_DES_Player[Node] = GetOwningPlayer(u)
            
            //Set up Unit
            set udg_DES_CurrentEffect[Node] = AddSpecialEffectTarget(DES_COrbEffect(), udg_DES_Unit[Node], DES_AttachmentPoint())
            call SetUnitScale(udg_DES_Unit[Node], DES_COrbScaleBase() + (udg_DES_Real1[Node] * DES_COrbScalePerPowerLevel()), 0, 0)
            
            if UnitAddAbility(udg_DES_Unit[Node], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[Node], 'Amrf') then
            endif

            call SetUnitFlyHeight(udg_DES_Unit[Node], GetUnitFlyHeight(u), 0.)
            
            //Start Timer
            if (udg_DES_AbilityCounter == 1) then
                call TimerStart(udg_DES_Timer, DES_TimerSpeed(), true, function DES_Loop)
            endif

        endloop

        set u = null
    elseif (GetSpellAbilityId() == DES_DestructionID()) then
        set u = GetTriggerUnit()
        set x = GetUnitX(u)
        set x2 = GetSpellTargetX()
        set y = GetUnitY(u)
        set y2 = GetSpellTargetY()   
        set z = DES_GetZ(x, y) + GetUnitFlyHeight(u)
        set z2 = DES_GetZ(x2, y2) + DES_GroundHeightLet()
        set iLevel = GetUnitAbilityLevel(u, DES_DestructionID())
        set rLevel = I2R(iLevel)
        set TempReal = SquareRoot(((x2 - x) * (x2 - x)) + ((y2 - y) * (y2 - y)))
        set Angle = Atan2(y2 - y, x2 - x)
        
        //Set up Data
        set Node = DES_CreateNode()
        set udg_DES_Real8[Node] = DES_DPowerLevelBase() + (rLevel * DES_DPowerLevelPerLevel())
        set udg_DES_Real1[Node] = (udg_DES_Real8[Node]) * (DES_LargeDPowerLevelMultiplyerBase() + (rLevel * DES_LargeDPowerLevelMultiplyerPerLevel()))
        set udg_DES_Real2[Node] = DES_DImpactAOEBase() + (udg_DES_Real1[Node] * DES_DImpactAOEPerPowerLevel())
        set udg_DES_Real3[Node] = DES_DImpactDamageHealthBase() + (udg_DES_Real1[Node] * DES_DImpactDamageHealthPerPowerLevel())
        set udg_DES_Real4[Node] = DES_DImpactDamageManaBase() + (udg_DES_Real1[Node] * DES_DImpactDamageManaPerPowerLevel())
        
        if (DES_DTrueOrIncomingSpeed()) then
            set udg_DES_Real5[Node] = DES_DTrueSpeedBase() + (udg_DES_Real1[Node] * DES_DTrueSpeedPerPowerLevel())
        else
            set udg_DES_Real5[Node] = TempReal / ((DES_DIncomingTimeBase() + (udg_DES_Real1[Node] * DES_DIncomingTimePerPowerLevel())) / DES_TimerSpeed())
        endif
        
        set TempReal = TempReal / udg_DES_Real5[Node]
        set udg_DES_Real6[Node] = udg_DES_Real5[Node] * Cos(Angle)
        set udg_DES_Real7[Node] = udg_DES_Real5[Node] * Sin(Angle)
        
        if (TempReal == 0.) then
            set udg_DES_Real5[Node] = 0
        else
            set udg_DES_Real5[Node] = ((z2 - z) + ((DES_Gravity() * (TempReal) * (TempReal)) / 2)) / TempReal
        endif
        
        set udg_DES_Integer1[Node] = DES_DOrbCountBase() + (iLevel * DES_DOrbCountPerLevel())
        set udg_DES_Boolean1[Node] = false
        set udg_DES_Boolean2[Node] = false
        set udg_DES_Boolean3[Node] = false
        set udg_DES_Boolean4[Node] = false
        set udg_DES_StageID[Node] = DES_LargeDStageID()
        set udg_DES_Caster[Node] = u
        set udg_DES_Player[Node] = GetOwningPlayer(u)
    
        //Set up Unit
        set udg_DES_Unit[Node] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, Angle * bj_RADTODEG)
        set udg_DES_Core[Node] = udg_DES_Unit[Node]
        set udg_DES_CurrentEffect[Node] = AddSpecialEffectTarget(DES_DOrbEffect(), udg_DES_Unit[Node], DES_AttachmentPoint())
        set udg_DES_SecondaryEffect[Node] = AddSpecialEffectTarget(DES_DMoveEffect(), udg_DES_Unit[Node], DES_AttachmentPoint())
        call SetUnitScale(udg_DES_Unit[Node], DES_DOrbScaleBase() + (udg_DES_Real1[Node] * DES_DOrbScalePerPowerLevel()), 0, 0)
        
        if UnitAddAbility(udg_DES_Unit[Node], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[Node], 'Amrf') then
        endif

        call SetUnitFlyHeight(udg_DES_Unit[Node], GetUnitFlyHeight(u), 0.)
        
        //Start Timer
        if (udg_DES_AbilityCounter == 1) then
            call TimerStart(udg_DES_Timer, DES_TimerSpeed(), true, function DES_Loop)
        endif
        
        set u = null
    elseif (GetSpellAbilityId() == DES_JusticeID()) then
        set u = GetTriggerUnit()
        set x = GetUnitX(u)
        set x2 = GetSpellTargetX()
        set y = GetUnitY(u)
        set y2 = GetSpellTargetY()  
        set iLevel = GetUnitAbilityLevel(u, DES_JusticeID())
        set rLevel = I2R(iLevel)
        
        set TempReal = (DES_JAngleAreaBase() + (rLevel * DES_JAngleAreaPerLevel()))
        set Angle = Atan2((y2 - y) , (x2 - x)) * bj_RADTODEG - (TempReal / 2)
        set Divider = TempReal / (DES_JOrbCountBase() + (rLevel * DES_JOrbCountPerLevel()))
        set TempReal = Angle + TempReal
        set Angle = Angle - (Divider / 2)
        
        //Create Orbs
        loop
            set Angle = Angle + Divider
            exitwhen Angle >= TempReal
            set Angle2 = Angle * bj_DEGTORAD
            //Set up Data
            set Node = DES_CreateNode()
            set udg_DES_Real1[Node] = DES_JPowerLevelBase() + (rLevel * DES_JPowerLevelPerLevel())
            set udg_DES_Real2[Node] = DES_JDamageAOEBase() + (udg_DES_Real1[Node] * DES_JDamageAOEPerPowerLevel())
            set udg_DES_Real3[Node] = DES_JDamageHealthBase() + (udg_DES_Real1[Node] * DES_JDamageHealthPerPowerLevel())
            set udg_DES_Real4[Node] = DES_JDamageManaBase() + (udg_DES_Real1[Node] * DES_JDamageManaPerPowerLevel())
            set udg_DES_Real5[Node] = SquareRoot(((x2 - x) * (x2 - x)) + ((y2 - y) * (y2 - y)))
            
            if (DES_JTrueOrIncomingSpeed()) then
                set udg_DES_Real8[Node] = DES_JTrueSpeedBase() + (udg_DES_Real1[Node] * DES_JTrueSpeedPerPowerLevel())
            else
                set udg_DES_Real8[Node] = udg_DES_Real5[Node] / ((DES_JIncomingTimeBase() + (udg_DES_Real1[Node] * DES_JIncomingTimePerPowerLevel())) / DES_TimerSpeed())
            endif
            
            set udg_DES_Unit[Node] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, Angle)
            
            if (udg_DES_Real5[Node] == 0.) then
                set udg_DES_Boolean3[Node] = false
                call UnitApplyTimedLife(udg_DES_Unit[Node], DES_TimedLifeID(), DES_JTimedLifeBase() * (udg_DES_Real1[Node] * DES_JTimedLifePerPowerLevel()))
            else
                set udg_DES_Real6[Node] = udg_DES_Real8[Node] * Cos(Angle2)
                set udg_DES_Real7[Node] = udg_DES_Real8[Node] * Sin(Angle2)
                set udg_DES_Real9[Node] = DES_JDamageManaburnRatioBase() + (udg_DES_Real1[Node] * DES_JDamageManaburnRatioPerPowerLevel())
                set udg_DES_Real10[Node] = DES_JDamageDelayBase() + (udg_DES_Real1[Node] * DES_JDamageDelayPerPowerLevel())
                set udg_DES_Real11[Node] = udg_DES_Real10[Node]
                set udg_DES_Boolean3[Node] = true
                set udg_DES_SecondaryEffect[Node] = AddSpecialEffectTarget(DES_JMoveEffect(), udg_DES_Unit[Node], DES_AttachmentPoint())
            endif
            
            set udg_DES_Boolean1[Node] = true
            set udg_DES_Boolean2[Node] = false
            set udg_DES_Boolean4[Node] = false
            set udg_DES_Integer2[Node] = iLevel
            
            //Set Up Unit
            set udg_DES_StageID[Node] = DES_JStageID()
            set udg_DES_Caster[Node] = u
            set udg_DES_Core[Node] = udg_DES_Unit[Node]
            set udg_DES_Player[Node] = GetOwningPlayer(u)
            set udg_DES_CurrentEffect[Node] = AddSpecialEffectTarget(DES_JOrbEffect(), udg_DES_Unit[Node], DES_AttachmentPoint())
            call SetUnitScale(udg_DES_Unit[Node], DES_JOrbScaleBase() + (udg_DES_Real1[Node] * DES_JOrbScalePerPowerLevel()), 0, 0)
            
            if UnitAddAbility(udg_DES_Unit[Node], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[Node], 'Amrf') then
            endif

            //Start Timer
            if (udg_DES_AbilityCounter == 1) then
                call TimerStart(udg_DES_Timer, DES_TimerSpeed(), true, function DES_Loop)
            endif
            
        endloop
        
        set u = null
    elseif (GetSpellAbilityId() == DES_PillarsID()) then
        set u = GetTriggerUnit()
        set x = GetSpellTargetX()
        set y = GetSpellTargetY()   
        set iLevel = GetUnitAbilityLevel(u, DES_PillarsID())
        set rLevel = I2R(iLevel)
        
        //Set up Data
        set Node = DES_CreateNode()
        set udg_DES_Real1[Node] = DES_PPullAOEBase() + (rLevel * DES_PPullAOEPerLevel())
        set udg_DES_Real2[Node] = DES_PPullDurationBase() + (rLevel * DES_PPullDurationPerLevel())
        set udg_DES_Real3[Node] = DES_PPowerForOrbBase() + (rLevel * DES_PPowerForOrbPerLevel())
        set udg_DES_Real4[Node] = DES_PCreationStartingPowerBase() + (rLevel * DES_PCreationStartingPowerPerLevel())
        set udg_DES_Real5[Node] = DES_PDestructionStartingPowerBase() + (rLevel * DES_PDestructionStartingPowerPerLevel())
        set udg_DES_Real6[Node] = DES_PJusticeStartingPowerBase() + (rLevel * DES_PJusticeStartingPowerPerLevel())
        set udg_DES_Real7[Node] = (DES_PPullStrengthBase() + (rLevel * DES_PPullStrengthPerLevel())) * DES_TimerSpeed()
        set udg_DES_Real8[Node] = DES_PSmallOrbOffsetBase() + (rLevel * DES_PSmallOrbOffsetPerLevel())
        
        if (DES_PSpinTrueOrIncomingSpeed()) then
            set udg_DES_Real9[Node] = DES_POrbTrueSpinSpeedBase() + (rLevel * DES_POrbTrueSpinSpeedPerLevel())
        else
            set udg_DES_Real9[Node] = 360. / ((DES_POrbSpinIncomingTimeBase() + (rLevel * DES_POrbSpinIncomingTimePerLevel())) / DES_TimerSpeed())
        endif
        
        set udg_DES_Real10[Node] = DES_PPullEffectDelayBase() + (rLevel * DES_PPullEffectDelayPerLevel())
        set udg_DES_Real11[Node] = udg_DES_Real10[Node]
        set udg_DES_Real12[Node] = 0.
        set udg_DES_Real13[Node] = DES_PSmallOrbsHeightOffsetBase() + (udg_DES_Real3[Node] * DES_PSmallOrbsHeightOffsetPerPowerLevel())
        set udg_DES_Boolean1[Node] = false
        set udg_DES_Boolean2[Node] = false
        set udg_DES_Boolean3[Node] = false
        set udg_DES_Boolean4[Node] = true
        
        set udg_DES_StageID[Node] = DES_UltimateStageID()
        set udg_DES_Integer1[Node] = DES_UltimatePullingTypeID()
        set udg_DES_Caster[Node] = u
        set udg_DES_Player[Node] = GetOwningPlayer(u)
        set z = DES_POrbHeightOffsetBase() + (rLevel * DES_POrbHeightOffsetPerLevel()) + (DES_PBoarderHeightOffsetAlterBase() + (rLevel * DES_PBoarderHeightOffsetAlterPerLevel()))
        
        //Set up Unit
        set udg_DES_Unit[Node] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, Angle)
        set udg_DES_Core[Node] = udg_DES_Unit[Node]
        set udg_DES_CurrentEffect[Node] = AddSpecialEffectTarget(DES_POrbEffect(), udg_DES_Unit[Node], DES_AttachmentPoint())
        call SetUnitScale(udg_DES_Unit[Node], DES_POrbScaleBase() + (rLevel * DES_POrbScalePerLevel()), 0, 0)
        
        if UnitAddAbility(udg_DES_Unit[Node], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[Node], 'Amrf') then
        endif
        
        call SetUnitFlyHeight(udg_DES_Unit[Node], z - (DES_PBoarderHeightOffsetAlterBase() + (rLevel * DES_PBoarderHeightOffsetAlterPerLevel())), 0.)
        call DestroyEffect(AddSpecialEffectTarget(DES_PSpawnEffect(), udg_DES_Unit[Node], DES_AttachmentPoint()))
        
        //Start Timer
        if (udg_DES_AbilityCounter == 1) then
            call TimerStart(udg_DES_Timer, DES_TimerSpeed(), true, function DES_Loop)
        endif
        
        //Create Boarder
        set AOE = DES_PBoarderOffsetBase() + (rLevel * DES_PBoarderOffsetPerLevel())
        set Divider = (360. / (DES_PBoarderCountBase() + (rLevel * DES_PBoarderCountPerLevel())))
        loop
            set Angle = Angle + Divider
            exitwhen Angle > 360.
            set Angle2 = Angle * bj_DEGTORAD
            
            set TempNode = DES_CreateNode()
            set udg_DES_Boolean1[TempNode] = false
            set udg_DES_Boolean2[TempNode] = false
            set udg_DES_Boolean3[TempNode] = true
            set udg_DES_Boolean4[TempNode] = true
            set udg_DES_StageID[TempNode] = DES_RecycleStageID()
            set udg_DES_Caster[TempNode] = u
            set udg_DES_Core[TempNode] = udg_DES_Unit[Node]
            set udg_DES_Unit[TempNode] = CreateUnit(DES_DummyPlayer(), DES_DummyID(), x, y, Angle)
            set udg_DES_CurrentEffect[TempNode] = AddSpecialEffectTarget(DES_PBoarderEffect(), udg_DES_Unit[TempNode], DES_AttachmentPoint())
            call SetUnitScale(udg_DES_Unit[TempNode], DES_PBoarderScaleBase() + (rLevel * DES_PBoarderScalePerLevel()), 0, 0)
            
            if UnitAddAbility(udg_DES_Unit[TempNode], 'Amrf') and UnitRemoveAbility(udg_DES_Unit[TempNode], 'Amrf') then
            endif
            
            call SetUnitFlyHeight(udg_DES_Unit[TempNode], z, 0.)    
        endloop
        
        set z2 = 0
        set udg_DES_Integer2[Node] = R2I(udg_DES_Real4[Node] / udg_DES_Real3[Node])
        set Divider = DES_PSmallOrbAngleOffset()
        set Angle = Divider
        set Angle2 = Angle * bj_DEGTORAD
        
        //Create Orbs of Creation
        loop
            set TempInt2 = TempInt2 + 1
            exitwhen TempInt2 > udg_DES_Integer2[Node]
            set TempReal = TempReal + z
            
            call DES_AddOrb(Node, DES_CStageID(), x, y, z2, Angle2)
            
            set z2 = z2 + udg_DES_Real13[Node]
        endloop
        
        set z2 = 0
        set TempInt2 = 0
        set udg_DES_Integer3[Node] = R2I(udg_DES_Real5[Node] / udg_DES_Real3[Node])
        set Angle = Angle + Divider
        set Angle2 = Angle * bj_DEGTORAD
        
        //Create Orbs of Destruction
        loop
            set TempInt2 = TempInt2 + 1
            exitwhen TempInt2 > udg_DES_Integer3[Node]
            set TempReal = TempReal + z
            
            call DES_AddOrb(Node, DES_DStageID(), x, y, z2, Angle2)
            
            set z2 = z2 + udg_DES_Real13[Node]
        endloop
        
        set z2 = 0
        set TempInt2 = 0 
        set udg_DES_Integer4[Node] = R2I(udg_DES_Real6[Node] / udg_DES_Real3[Node])
        set Angle = (Angle + Divider) * bj_DEGTORAD
        
        //Create Orbs of Justice
        loop
            set TempInt2 = TempInt2 + 1
            exitwhen TempInt2 > udg_DES_Integer4[Node]
            set TempReal = TempReal + z
            
            call DES_AddOrb(Node, DES_JStageID(), x, y, z2, Angle)
            
            set z2 = z2 + udg_DES_Real13[Node]
        endloop
        
        set udg_DES_Real4[Node] = 0.
        set udg_DES_Real5[Node] = 0.
        set udg_DES_Real6[Node] = 0.
        
        set u = null
    endif
    
    return false
endfunction

////////////////////////////////////////////////////////////////////
//  Initialisation trigger, applies the conditions to triggers    //
//  and sets up the global location used to get location Z's      //
//  as well as the map bounds                                     //
////////////////////////////////////////////////////////////////////
function InitTrig_Divine_Envoy_Spellset takes nothing returns nothing
    //Set up locals
    local trigger DE = CreateTrigger()
    local integer index = 0

    //Set up hero casting triggers
    loop
        //Applies the even to each player in turn
        call TriggerRegisterPlayerUnitEvent(DE, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop

    //Applies the function to check for each spell to the trigger
    call TriggerAddCondition(DE, Condition(function DES_OnCast))

    //Set up the location used to find Z heights
    set udg_DES_Loc = Location(0,0)
    //Set up the Timer used to run the loop
    set udg_DES_Timer = CreateTimer()
    
    //Set up the unit used to check if trees are nearby
    set udg_DES_TreeChecker = CreateUnit(DES_DummyPlayer(), DES_TreeCheckerID(), 0, 0 , 0)
    //Sets up the variables used to make sure a point is within the map area
    set udg_DES_MapMaxX = GetRectMaxX(bj_mapInitialPlayableArea)
    set udg_DES_MapMinX = GetRectMinX(bj_mapInitialPlayableArea)
    set udg_DES_MapMaxY = GetRectMaxY(bj_mapInitialPlayableArea)
    set udg_DES_MapMinY = GetRectMinY(bj_mapInitialPlayableArea)

endfunction
////////////////////////////////////////////////////////////////////
// End of the spellset                                            //
////////////////////////////////////////////////////////////////////
Last edited:
Top