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

Divine Envoy Spellset V1.01

[TD]Divine Envoy Spellset[/TD]
Winning entry of Zephyr Contest #12
Tooltips


When two Divine Orbs come into contact their stored power is released and combined resulting in an extra effect based on which types of Orb collided. The strength of the effect is increased the more power released

Creation + Destruction: Cycle of Life - Nearby enemies are damaged, a percentage of the total damage dealt is then restored to allies
Creation + Justice: Equaliser - All units in the nearby area have their mana drained, then their hitpoints are added up and divided equally among them
Destruction + Justice: Trial by Fire - Nearby enemy units are set on fire taking damage over time. If a unit dies when on fire additional damage is dealt to nearby enemies


Q Orbs of Creation
Launches Orbs of Creation with stored power at the target area, healing allies upon landing and continuing to passively heal every 2 seconds

Level 1 - 3 Orbs, 2.00 Stored power, 20.00 Active heal, 6.00 Passive heal, lasts 6 seconds
Level 2 - 6 Orbs, 2.50 Stored power, 22.50 Active heal, 7.00 Passive heal, lasts 7 seconds
Level 3 - 9 Orbs, 3.00 Stored power, 25.00 Active heal, 8.00 Passive heal, lasts 8 seconds


W Orbs of Destruction
Launches Orbs of Destruction with stored power at the target area, damaging enemies upon landing and continuing to passively damage every 2 seconds

Level 1 - 5 Orbs, 2.00 Stored power, 20.00 Active damage, 9.00 Passive damage, lasts 6 seconds
Level 2 - 7 Orbs, 2.50 Stored power, 22.50 Active damage, 10.00 Passive damage, lasts 7 seconds
Level 3 - 9 Orbs, 3.00 Stored power, 25.00 Active damage, 11.00 Passive damage, lasts 8 seconds


E Orbs of Justice
Launches Orbs of Justice with stored power at the target area in a cone, damaging and mana burning enemies they pass through and continuing to passively slow enemy units after they stop. a percentage of the mana destroyed is converted to health damage

Level 1 - 3 Orbs, 2.00 Stored power, 40% Slow, 24.00 Health damage, 24.00 Mana damage, 90% Convertion rate, lasts 6 seconds
Level 2 - 6 Orbs, 2.50 Stored power, 60% Slow, 25.00 Health damage, 25.00 Mana damage, 100% Convertion rate, lasts 7 seconds
Level 3 - 9 Orbs, 3.00 Stored power, 80% Slow, 26.00 Health damage, 26.00 Mana damage, 110% Convertion rate, lasts 8 seconds


R Pillars of Judgement
Calls down from the heavens Pillars of Judgement which pull nearby Orbs and enemies into them, collecting the power stored within. 10 seconds later a new effect activates based on which pillar collected the most power.

Creation: Wild Growth - Treants spawn rapidly around the pillars spreading across a large area, each treant lasting for a short duration
Destruction: Armageddon - Flames decimate the area around the pillars dealing heavy damage to enemies caught within the flames
Justice: Countdown - Nearby units are marked, after a short delay all marked enemies take damage and all marked allies are healed
Equilibrium: Divine Envoy - The pillars rise before striking the ground repeadetly with lightning dealing huge damage to enemies and healing allies. Judgement is then delivered as a beam of light dealing massive damage and blasting enemies back

Ultimate depenendencies


Different amounts of each Orb in the Pillar affects the attributes of whichever Ultimate is running (except Divine Envoy as all pillars are equal anyway when that runs, and thus all things are affected by the one attribute), this information is not included in the tooltip in order to prevent it becoming oversized and can also be considered a "hidden" feature for players to figure out or told externally (in example: a training level of a campaign)

Wild Growth:
- Effect of Orbs of Creation: Increases the amount of treants spawned
- Effect of Orbs of Destruction: Increases the total AOE of the ring spreading
- Effect of Orbs of Justice: Increases the duration of the timed lives

Armageddon:
- Effect of Orbs of Creation: Increases the AOE of each projectile
- Effect of Orbs of Destruction: Increases the amount of Projectiles launched by the pillar (attempts to entirely cover the area)
- Effects of Orbs of Justice: Increases the amount of damage each projectile deals

Countdown:
- Effect of Orbs of Creation: Decreases the Timer until the effect goes off
- Effect of Orbs of Destruction: Increases the Damage/Healing dealt by the ability
- Effect of Orbs of Justice: Increases the AOE of the ability

Code

JASS:
////////////////////////////////////////////////////////////////////
//                   DIVINE ENVOY SPELLSET V1.01                  //
//  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
    return (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)
   
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
    return (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)
   
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
    return (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)
   
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
    return ((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)))
   
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
    return (x < udg_DES_MapMaxX) and (x > udg_DES_MapMinX) and (y < udg_DES_MapMaxY) and (y > udg_DES_MapMinY)

endfunction

////////////////////////////////////////////////////////////////////
//  Function used to destroy trees which have been found close    //
//  to affected units (knockback and pull)                        //
////////////////////////////////////////////////////////////////////
function DES_TreeDestroy takes nothing returns nothing
    //Locate Trees
    local destructable Tree = GetEnumDestructable()
   
    if IssueTargetOrderById(udg_DES_TreeChecker, 852018, Tree) and IssueImmediateOrderById(udg_DES_TreeChecker, 851972) then
        //Destroy Tree
        call KillDestructable(Tree)
    endif
   
    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)
    set TempRect = null
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]) and not(udg_DES_Boolean3[TempNode]) 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())
   
    //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())
        exitwhen iLoop > BoarderCount
    endloop
   
    set u = null
       
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 = GetWidgetLife(u)
            call UnitDamageTarget(Caster, u, DamageHealth, false, false, DES_CycleAttackType(), DES_CycleDamageType(), DES_CycleWeaponType())
            set TotalDamageHealth = TotalDamageHealth + (TempReal - GetWidgetLife(u))
            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 SetWidgetLife(u, GetWidgetLife(u) + 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 + GetWidgetLife(u)
            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 SetWidgetLife(u, 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]) 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 not(udg_DES_Boolean1[Node]) 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 SetWidgetLife(u, GetWidgetLife(u) + 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 SetWidgetLife(u, GetWidgetLife(u) + 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 not(udg_DES_Boolean1[Node]) 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]) 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]) 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]) 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]) and not(udg_DES_Boolean3[TempNode]) and not(udg_DES_Boolean4[TempNode]) 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 not(udg_DES_Boolean2[TempNode]) 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]) and (udg_DES_Boolean1[TempNode]) and not(udg_DES_Boolean3[TempNode]) and not(udg_DES_Boolean4[TempNode]) 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]) 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 SetWidgetLife(udg_DES_Unit[TempNode], GetWidgetLife(udg_DES_Unit[TempNode]) + 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 SetWidgetLife(u, GetWidgetLife(u) + 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
                            set udg_DES_Boolean4[TempNode] = not(DES_PDivineLaserKnockbackAngle() == 0.)
                           
                            //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 SetWidgetLife(u, GetWidgetLife(u) + 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 integer spellID = GetSpellAbilityId()
    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 (spellID == 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 (spellID == 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 (spellID == 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 (spellID == 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                                            //
////////////////////////////////////////////////////////////////////

Spellset Information

- 4672 Lines of pure JASS
- Has an extensive Readme
- Can be imported into the vanilla WE
- None of the abilities interfere with the game scorescreens (increasing player's "units created" values)
- 11 Abilities included in the set (the initial stage of the ultimate is an ability)
- 387 configurables (that's a hell of a lot)
- Very High synergy
- Difficult to master, easy to learn
- Correctly arcs over uneven terrain
- Functions for ground and flying heros
- Most aspects of the abilities can be removed or added due to the configuration making them highly adaptable spells
- Designed to be attractive yet functional
- Correctly ignores magic immunes
- Easy-to-reach target filters for players who want to change what is and is not acceptable as a target
- 3D knockback
- Optional Tree destruction
- Only 48 variables to import for all 11 abilities
- Efficiently designed to reuse array variables whenever possible
- Serves as an entire hero set
- Can have the abilities distributed across many units and still functions (Orbs interact so long as they're owned by the same player)
- Abilities of different levels interact differently (different power levels) than two abilities of the same level
- Buffs for all status conditions (slows, burns, coundown)
- All buffs can serve as slows (based off slow aura)
- Mr Fluffy the flying test Hero is back
Tips and Tricks


- If the ability is using Incoming Time, Orbs of Justice does increased damage to singular enemies the shorter the range of the entire ability while not being cast at the point of the caster, where as if not the damage density is consistent, and thus most benefit is in using it at longer range
- If both Orbs of Creation and Destruction are using Incoming Time, then with a bit of luck, you can combo Orbs of Justice at the moment of impact for Orbs of Destruction giving your opponents less time to react, this is also a way of comboing even when the ultimate is pulling in Orbs (the same applies to Orbs of Creation, except that it is more predictable and does not require luck)
- It is technically possible to Combo Orbs of Creation and Destruction at their moment of impact, but this requires precise timing of launching and a bit of luck
- In a battle, try to get Orbs of creation to line up against the battle line or slightly into the enemies side, this means the counteract the effect the enemies will need to move further back to get out of the range of healing giving you more free hits
- In a battle due to Orbs of Destruction's unpredictability the only garunteed hit during battle is the initial big Orb, as such it makes sense to launch it at the priority Target
- Orbs of Destruction's damage has a higher density around the intiial casting point (due to the nature of how they spread out)
- The effects of Orbs of Destruction and Orbs of Creation Stack, while the effect of Orbs of Justice does not, making them generally more useful in extended combat (except for combo abilities)
- In individual conflicts, it typically makes sense to use only two of the three abilities if you lack the skill to properly control the combos, as you can easily get an unhelpful combo effect (Equaliser in particular when you're winning is very unhelpful)
- The most efficient method of using all 3 abilities while avoiding using equaliser during combat while utilising the other effects, is to use Orbs of Creation furthest away, Orbs of Desutruction on the boarder of Orbs of Creation and Orbs of Justice just shy of Orbs of Creation (so that they do not combo). This should be positioned on the battleline for most efficient usage, however is still one of the most inefficient ways of using each of the abilities independantly, conversely: If you flank the enemy units with the Hero first and then do this, it is one of the most efficient ways of using each of the abilities independantly but is unsafe for that Hero.


- Orbs of Judgement are by far easiest to set up combination attacks due to their sweeping nature, Orbs of Creation are second easiest, and Orbs of Destruction are hardest, it's recommended to use the abilities in the order of easiest to set up for the combination effects (i.e. always use Orbs of Destruction first if it is in the combination) Additionally, the slowing effect of Orbs of Judgement are helpful for keeping enemies within the target AOE for Equaliser and Trial by fire.
- Equaliser is hugely effective against low amounts of enemies with high HP when you are using large amounts of low HP units as it will heal them and take a higher chunk of the enemies health away, the more they have.
- Equaliser is also useful against full HP enemy armies without affecting your units if the enemy army has a couple of high HP units as it will pull them down before the battle even begins.
- Trial by Fire is hugely effective against high amounts of enemies with low HP as they are more likely to die when on fire and cause a chain reaction killing all enemies affected by it.
- Setting up an Equaliser to be quickly followed up by a Cycle of life can quickly turn around a situation - when losing a battle equaliser will heal your units putting you on an even plain and Cycle of life will push you ahead, be careful not to get this the wrong way around though as you may remove your advantage. This is also a great way to start a battle, if your army was already damaged.
- When low on Mana focussing usage on Cycle of Life is more effecient as Orbs of Judgement are less effective for damaging purposes (unless at melee range) and are more situational
- Leading a conflict with Trial by Fire is typically the best move as it does the highest amount of damage with Orbs of Justice aimed far back to move them out of the way as well as containing the enemy units, creating a space closer to the Hero which can be used to set up Cycle of Life (naturally if you want Orbs of Justice based combos, pulling them into the combo area is going to be a better idea)


- When using the ultimate always consider what effect you want/need in the situation as well as how many orbs of each type you will have available and their respective power levels, getting it wrong can result in a waste of the ultimate
- Using Orbs of Judgement on enemy units while the Ultimate is pulling them in is helpful as it makes it more difficult for them to escape the AOE (once they are within the effect area the pillar's own Orbs of Justice will slow them)
- Countdown is helpful in and out of combat as in pressing situations it is more difficult/risky to stay within the radius for the healing effect, using it during a peaceful moment can heal up an entire army (using only Orbs of Justice to increase AOE and Orbs of Destruction to increase the amount healed)
- During Countdown, using Orbs of Judgement to slow enemies helps you keep them within the radius to take the damage. (as opposed to before, as the pillar will potentially have pulled those orbs in and only effect those closest to the pillar) By the same merit, it is also helpful for setting up Wild Growth and Armaggedon depending on the type of usage of them you are attempting to achieve
- Consider the desired AOE when using Wild Growth, a small AOE gives a very high concentration of Treants which can be very helpful at the immediate area, and a high AOE puts them over a much wider area, more useful for surrounding and body blocking bigger groups of enemies
- Armageddon's effectiveness depends largely on the size of the enemy army - a large army scattered across the area will take more damage from a higher AOE, lower Damage Armageddon while a small army, close to the ultimate takes much more damage from a High damage, low AOE armageddon as the AOE effects how far the projectiles spread out and thus their damage distribution.
- Divine Envoy is by far the strongest form of the ultimate with higher reward for each unit of power placed into it, but requires a large amount of mana generally to use it effectively and can cause accidental combos when trying to set up which can result in the player failing to set it up correctly and getting one of the other effects.
- If you're trying to set up the ultimate, you should avoid creating combination abilities - attempt to keep things efficient but the order of casting should be reversed, with Orbs of judgement being cast first in order to minimise combos. It is also suggested to potentially waste an ability just to put more orbs on the battlefield before using the ultimate
- Launching abilities directly into the centre of the ultimate can quickly add the orbs to the stacks, this is particularly helpful when there is not much time left for gathering with the ultimate.

Helpful Files

- Variable Creator: Copy and paste into your map, you now have all the variables needed for the spell to run
  • Variable Creator
    • Events
    • Conditions
    • Actions
      • Set DES_AbilityCounter = 0
      • Set DES_Boolean1[0] = False
      • Set DES_Boolean2[0] = False
      • Set DES_Boolean3[0] = False
      • Set DES_Boolean4[0] = False
      • Set DES_Caster[0] = DES_Caster[0]
      • Set DES_Core[0] = DES_Core[0]
      • Set DES_CurrentEffect[0] = DES_CurrentEffect[0]
      • Set DES_Integer1[0] = 0
      • Set DES_Integer2[0] = 0
      • Set DES_Integer3[0] = 0
      • Set DES_Integer4[0] = 0
      • Set DES_LastNode = 0
      • Set DES_Lightning[0] = DES_Lightning[0]
      • Set DES_Loc = DES_Loc
      • Set DES_MapMaxX = 0.00
      • Set DES_MapMaxY = 0.00
      • Set DES_MapMinX = 0.00
      • Set DES_MapMinY = 0.00
      • Set DES_NextNode[0] = 0
      • Set DES_NodeNumber = 0
      • Set DES_Player[0] = DES_Player[0]
      • Set DES_PrevNode[0] = 0
      • Set DES_Real1[0] = 0.00
      • Set DES_Real10[0] = 0.00
      • Set DES_Real11[0] = 0.00
      • Set DES_Real12[0] = 0.00
      • Set DES_Real13[0] = 0.00
      • Set DES_Real14[0] = 0.00
      • Set DES_Real15[0] = 0.00
      • Set DES_Real16[0] = 0.00
      • Set DES_Real2[0] = 0.00
      • Set DES_Real3[0] = 0.00
      • Set DES_Real4[0] = 0.00
      • Set DES_Real5[0] = 0.00
      • Set DES_Real6[0] = 0.00
      • Set DES_Real7[0] = 0.00
      • Set DES_Real8[0] = 0.00
      • Set DES_Real9[0] = 0.00
      • Set DES_RecyclableNodes = 0
      • Set DES_RecycleNodes[0] = 0
      • Set DES_SecondaryEffect[0] = DES_SecondaryEffect[0]
      • Set DES_StageID[0] = 0
      • Set DES_TempGroup = DES_TempGroup
      • Set DES_TempGroup2 = DES_TempGroup2
      • Set DES_Timer = DES_Timer
      • Set DES_TreeChecker = DES_TreeChecker
      • Set DES_Unit[0] = DES_Unit[0]

Images

Orbs of Creation

Orbs of Destruction

Orbs of Justice

Cycle of Life

Equiliser

Trial by Fire

Pillars of Judgement

Wild Growth

Armageddon

Countdown

Divine Envoy

Other

Tooltip

GIF

Cast

Active Heal

Passive Heal

142813d1422138816-zephyr-contest-12-combo-orbs-creation-tooltip.png
142814d1422138816-zephyr-contest-12-combo-orbs-creation-gif.gif
142815d1422138816-zephyr-contest-12-combo-orbs-creation.png
142816d1422138816-zephyr-contest-12-combo-orbs-creation-active-heal.png
142817d1422138816-zephyr-contest-12-combo-orbs-creation-passive-heal.png

Tooltip

GIF

Cast

Mid

End

Active Damage

Passive Damage

142818d1422138896-zephyr-contest-12-combo-orbs-destruction-tooltip.png
142819d1422138896-zephyr-contest-12-combo-orbs-destruction-gif.gif
142820d1422138896-zephyr-contest-12-combo-orbs-destruction-start.png
142821d1422138896-zephyr-contest-12-combo-orbs-destruction-mid.png
142822d1422138896-zephyr-contest-12-combo-orbs-destruction-end.png
142823d1422138896-zephyr-contest-12-combo-orbs-destruction-active-damage.png
142824d1422138896-zephyr-contest-12-combo-orbs-destruction-passive-damage.png

Tooltip

GIF

Cast

Damage

Slow

142825d1422138896-zephyr-contest-12-combo-orbs-justice-tooltip.png
142826d1422138896-zephyr-contest-12-combo-orbs-justice-gif.gif
142827d1422138896-zephyr-contest-12-combo-orbs-justice.png
142828d1422138896-zephyr-contest-12-combo-orbs-justice-damage.png
142829d1422138896-zephyr-contest-12-combo-orbs-justice-slow.png

GIF

Image

142830d1422138896-zephyr-contest-12-combo-cycle-life-gif.gif
142831d1422138896-zephyr-contest-12-combo-cycle-life.png

GIF

Image

142832d1422138896-zephyr-contest-12-combo-equaliser-gif.gif
142833d1422138896-zephyr-contest-12-combo-equaliser.png

GIF

Activate

Burning & Explode

142834d1422138896-zephyr-contest-12-combo-trial-fire-gif.gif
142835d1422138896-zephyr-contest-12-combo-trial-fire.png
142853d1422139895-zephyr-contest-12-combo-trial-fire-burning-explode.png

Tooltip

Start

Gather

Absorb

142847d1422139675-zephyr-contest-12-combo-pillars-judgement-tooltip.png
142848d1422139747-zephyr-contest-12-combo-pillars-judgement-start.png
142849d1422139747-zephyr-contest-12-combo-pillars-judgement-gather.png
142850d1422139747-zephyr-contest-12-combo-pillars-judgement-absorb.png

GIF

Effect

142836d1422138896-zephyr-contest-12-combo-wild-growth-gif.gif
142837d1422138896-zephyr-contest-12-combo-pillars-judgement-wild-growth-run.png

GIF

Start

Running

142838d1422138896-zephyr-contest-12-combo-armageddon-gif.gif
142839d1422138896-zephyr-contest-12-combo-pillars-judgement-armageddon-start.png
142840d1422138896-zephyr-contest-12-combo-pillars-judgement-armageddon-run.png

GIF

Start

End

142841d1422138896-zephyr-contest-12-combo-countdown-gif.gif
142842d1422138896-zephyr-contest-12-combo-pillars-judgement-countdown-run.png
142843d1422138896-zephyr-contest-12-combo-pillars-judgement-countdown-end.png

GIF

Storm

Laser

142844d1422138896-zephyr-contest-12-combo-divine-envoy-gif.gif
142845d1422138896-zephyr-contest-12-combo-pillars-judgement-divine-envoy-storm.png
142846d1422138896-zephyr-contest-12-combo-pillars-judgement-divine-envoy-laser.png

Combo Explanations Tooltip

Terrain Demonstration Cliff

Terrain Demonstration Hill

Flying Terrain Demonstration

Combo Command Card

142851d1422139747-zephyr-contest-12-combo-combo-explanations-tooltip.png
142854d1422139895-zephyr-contest-12-combo-terrain-height-demonstration.png
142855d1422139895-zephyr-contest-12-combo-terrain-height-demonstration-2.png
142856d1422139895-zephyr-contest-12-combo-flyer-terrain-height-demonstration.png
142852d1422139747-zephyr-contest-12-combo-divine-envoy-spellset-command-card.png


Changelog


-=V1.00=-
- Initial Upload
-=V1.01=-
- Efficiency improvements (see: Icemanbo's post(s))

[tr]

Keywords:
Combo, Contest, Divine, Holy, Elemental, Absorb, Creation, Desutruction, Justice, Orb, Sphere, AOE, Burning, Fire, Gather, Stacks, Hero, Pack, Set.[/tr]
Contents

Divine Envoy Spellset (Map)

Reviews
Submission: Divine Envoy Spellset V1.01 Date: 11.07.2015 Status: Approved Rating: 5/5 Review Link Moderator: IcemanBo

Moderator

M

Moderator


Submission:
Divine Envoy Spellset V1.01

Date:
11.07.2015

Status:
Approved

Rating:
5/5

Review
Link

Moderator:
IcemanBo
 
Level 6
Joined
May 11, 2013
Messages
205
Haven't test it yet but since i know your skills with coding you have 5 rate from me
 
well naturally all the effects are configurable (including removal) - I don't tend to concern myself too much with how many effects are in the default product (I just configure them to my own tastes, which is rather on the heavy side) Indeed they could be reduced and that'd probably look better to many people. I appreciate the input and your 5 palms
 
I can't test the spellset by myself atm, because I don't have wc3 installed, but from the presentation in your thread it looks very nice.

But I can give some feedback on reading your posted code here:

For some config functions, like damage calculations, it could be helpful if they used a parameter integer level,
instead of using a second function to define a (constant) changement for each level of the ability.

function DES_ValidateLocation could directly return the expression.

The destroy tree function could be shortened:
JASS:
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
->
JASS:
function DES_TreeDestroy takes nothing returns nothing    
    if IssueTargetOrderById(udg_DES_TreeChecker, 852018, Tree) and IssueImmediateOrderById(udg_DES_TreeChecker, 851972) then
        call KillDestructable(GetEnumDestructable())
    endif
endfunction
The good thing is, that IssueOrder does return a boolean. So when the first one is true, it means it is a tree and then it will also fire the second check. (order "stop" order)
Or the "stop" order could also be done only once in the other function where you enum all destructibles.

In function DES_EndUltimate you have one == false comparison.
Could be replaced with not keyword before the expression.
Also the == true[/lass] I have found in function DES_SlowScan. And there are some more. Names like Boolean3, Boolean4 and so on is not descrptive at all. It's basicly the type of variable and a number to differ them. When you read code you have no idea what it should/could mean. It could be anything. In [icode=jass]function DES_ComboEffects you only have to null the u once in the end of the function.
Currently you do so once before loop and then in iteration of the loop. (redundant)

In function DES_CycleOfLife:
Using GetWidgetLife(u) is faster than GetUnitState(u, UNIT_STATE_LIFE).
And for set life, SetWidgetLife should be used.

If you potentialy pause the periodic timer in function DES_Recycle,
wouldn't it maybe logical if you potentialy start/continue it function DES_CreateNode? (true question)
 
I've made most of the changes (will be testing before updating) though some things I'll be keeping the same:

- I use the names Boolean[n], Real[n] etc. in order to minimise the variable usage, if I were to give them meaningful names then I would need to use well over 100 variables (perhaps over 200) as opposed to the 48 the current setup uses, this method also minimises the needs to have failsafes when recycling making it easier and simpler to use a single linked list for all spells (since there won't be spare variables with values from previous iterations which may impact on the new instance)

- I don't see much reason in passing an integer value to the constant functions (it would prevent them from being constant functions, it would not reduce the amount of calculations needed) it may make them more clear in terms of what they do but that's what the documentation is for

- I don't start/continue the loop in the create node section as a single iteration of the spell may create upwards of 100+ nodes all of which would then run this check as opposed to the single check per new cast I have now, it would be fewer lines of code but would lower performance
 
Could not find something critical errors by just reading the code.

But still some notes:

There could be used one system-global rect for EnumDestructablesInRect function.

set Health = Health + GetUnitState(u, UNIT_STATE_LIFE)
-> GetWidgetLife. :p

function DES_Loop
^Here, too, with life, more often.

JASS:
if (DES_PDivineLaserKnockbackAngle() == 0.) then
    set udg_DES_Boolean4[TempNode] = false
else
    set udg_DES_Boolean4[TempNode] = true
endif
->
set udg_DES_Boolean4[TempNode] = not(DES_PDivineLaserKnockbackAngle() == 0.)

onCast GetSpellAbilityId() could be stored into a variable onCast.
If there is a variable you also will use it for GetUnitAbilityLevel instead of the the function call.

All the constant "loop control" functions for correct StageIds
should not really be touched or? I mean it wouldn't make sense anyway.
If so, it should be moved out of config.

Sorry to ask, but will it currently deindex properly when caster was removed from game/died?
In damage functions the caster[node] is used as reference, so it should be.
(I saw some checks for dummy, but not for caster.)

DIVINE ENVOY SPELLSET V1.00
->
DIVINE ENVOY SPELLSET V1.01
:D

I think in general it looks fine, though I will let decission about approval to someone who has access to test map.:)
I prefer testings things when they are so big.
 
Cleaned up the rest of it as I saw fit from your post (I never manage to get ti right first try @GetUnitStates) Didn't change the version number this time though (consider this the "icemanbo corrections version")

The loop Control config is semi read only (there is possibly one or two cases where I can see somebody modifying them, for instance if you wanted to add another orb type of your own and wanted to copy the behaviour of the others or modify the existing ones to copy behaviour (incidentally doing this would also remove the combos without having to locate all the relevent code might need to change the setup part in the onCast though))

Testing it found it fine if the caster dies (since they can still be used as a damage source) can't say I've tried it with removed units (being non-channel abilities I'm not actually sure what the protocol in that situation would be - not something that's usually accounted for in the spell section)
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
I like your clean coding style, just wish you made less of these effect heavy spell variations :p

Also i do think there is such thing as too much documentation after a while, like is there really a need to comment on:

JASS:
////////////////////////////////////////////////////////////////////
//  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

I am sure anyone actually reading the code can tell what it does just by name alone :p
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
JASS:
function DES_TreeDestroy takes nothing returns nothing    
    if IssueTargetOrderById(udg_DES_TreeChecker, 852018, Tree) and IssueImmediateOrderById(udg_DES_TreeChecker, 851972) then
        call KillDestructable(GetEnumDestructable())
    endif
endfunction
Actually, you can also avoid ordering the dummy to stop by removing it's move ability on initialization. call UnitRemoveAbility(Dummy, 'Amov')

JASS:
function DES_TreeDestroy takes nothing returns nothing    
    if IssueTargetOrderById(udg_DES_TreeChecker, 852018, Tree) then
        call KillDestructable(GetEnumDestructable())
    endif
endfunction
 
A very great spellset.

I won't recap the concept, because it's done very lucidly and detailed in the thread already.
I can not sum it all in 1 sentence. :p

You allow the user a huge field of customization as always.
The code is written in very good JASS, efficient, and leakless.
I'm happy about the concept and don't miss any more features.
I tested the spell and didn't mention bugs.

You can see this almost as approved already, but I want to have a final check.
Expect an edit of this post some later or maybe tomorrow.

Edit:

In function DES_AddOrb there is a amount of redundant lines, that could be moved out of the if statement.
For example this happens in each case:
JASS:
set udg_DES_Boolean1[TempNode] = true
set udg_DES_Boolean2[TempNode] = true
set udg_DES_Boolean3[TempNode] = false
set udg_DES_Boolean4[TempNode] = true

In function DES_ComboEffects you would not need DEG, all could be done in RAD.
Also onCast actually.
onCast you you atm convert from DEG to RAD, but then forgot to forgot to convert to DEG sometimes when it comes to unit creation.
This does not really affect the spell, so I don't see it as critical, and I know you will fix it soon.

If I was you I would just write one custom IsUnitAlive function instead of doing always both checks on my onw.

JASS:
//Make the Orb Interactable
if (TempReal <= udg_DES_Real1[Node]) then
    set udg_DES_Boolean2[TempNode] = false
endif
can be shortened ->
set udg_DES_Boolean2[TempNode] = not((TempReal <= udg_DES_Real1[Node]))
:)

Index 0 can be used as well:).

I had to cry several times, because all this jumping around in huge code when reading up some functions just made me tired. :D

Even I mentioned some little things now, this is a huge code, and I haven't found anything critical.
I'm really proud there are still people who put so much effort into coding.
I secretly pray you switch to vJASS one day, but keep going, bro.

It is a good spell set.

5/5
Approved
 
Last edited:
I wrote it in JASS because I got tired of how inefficiently GUI handled things upon conversion (this is why I started publishing JASS works in general) - my spells tend to be long so it's better that they use as little as possible, though I kept them all vanilla compatiable and the readme should make configuring them no harder than if it were in GUI
also yeah, it's much faster to write
 
Level 5
Joined
Sep 7, 2014
Messages
94
What are you talking about crashing WE?
It doesn't crash at all.
You just have to copy and paste the code and the spells from the object editor and then change the spell id to fit the object editor.

Yes you're right, but if I edit the spell, although just changing the spell id, when I try to play the map, weirdly the map is unusable!
 
Top