• 🏆 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!

Zephyr Contest #14 - Unique Summoning

Status
Not open for further replies.
"judge if the spell fits" is judged in concept criteria. If the spell is much too overpowered, or something similar, it's usually would be mentioned there, in concept.

-------

The coding does still cover 50% of all score points. So it is still the most important criteria.
What happened is that the relation, specified for this theme, between visuals and concept has changed.
The visuals for the summoning also seems important here, so it's importance was increased a bit. :)
 
Last edited:
Level 9
Joined
Oct 14, 2013
Messages
238
Final Entry

Stone Integrity
Main Spell
Icon
PASBTNStoneIntegrity.png
Tooltip
233310-albums8885-picture108370.png
Merge (Golems Special Ability)
Icon
Untitled.png
Tooltip
233310-albums8885-picture108586.png
Codes/Triggers

Passively Used

Actively Used

Dropping Stones

Merging Golems

Dying Debug and Clear

Constants

  • Passively Used
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in SI_CoreGolemGroup and do (Actions)
        • Loop - Actions
          • -------- ############################ --------
          • -------- Adjusting the scaling value --------
          • -------- ############################ --------
          • Set SI_TempReal[1] = ((Percentage life of (Picked unit)) + SI_MinimumScale)
          • Animation - Change (Picked unit)'s size to (SI_TempReal[1]%, SI_TempReal[1]%, SI_TempReal[1]%) of its original size
          • -------- ############################ --------
          • -------- This part prevents the HP of the Core Golem from going higher than the Max Hp --------
          • -------- ############################ --------
          • Set SI_TempReal[1] = ((Max life of (Picked unit)) - (Load (Key HP Lost) of (Key (Picked unit)) from SI_Hashtable))
          • Set SI_TempReal[2] = (SI_TempReal[1] - (Load (Key Returned HP) of (Key (Picked unit)) from SI_Hashtable))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Life of (Picked unit)) Greater than or equal to SI_TempReal[1]
            • Then - Actions
              • Unit - Set life of (Picked unit) to (SI_TempReal[1] - 1.00)
            • Else - Actions
          • -------- ############################ --------
          • -------- This part is a bit difficult to explain but here it is: --------
          • -------- This part manages the HP returned from merging and whenever it is restored it gets subtracted from the "Returned" HP. --------
          • -------- On a side note: This is the HP returned to the Core Golem but it is marked "Returned", so it first needs to be restored before another stone can be formed out of it. --------
          • -------- ############################ --------
          • Set SI_TempReal[1] = (SI_TempReal[1] - 1.00)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Life of (Picked unit)) Greater than SI_TempReal[2]
            • Then - Actions
              • Set SI_TempReal[2] = (SI_TempReal[1] - (Life of (Picked unit)))
              • Hashtable - Save SI_TempReal[2] as (Key Returned HP) of (Key (Picked unit)) in SI_Hashtable
            • Else - Actions
          • -------- ############################ --------
          • -------- Checking all the criteria for a stone to drop: Some calculations to determine if the current HP is less than the Max HP minus Lost HP, minus Returned HP, and minus Threshold --------
          • -------- ############################ --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of Stone Integrity for (Picked unit)) Greater than 0
              • ((SI_TempReal[1] - (Load (Key Returned HP) of (Key (Picked unit)) from SI_Hashtable)) - (Life of (Picked unit))) Greater than or equal to SI_StoneDropHpThreshold[(Level of Stone Integrity for (Picked unit))]
              • (((Max life of (Picked unit)) - 1.00) - ((Load (Key Returned HP) of (Key (Picked unit)) from SI_Hashtable) + (Load (Key HP Lost) of (Key (Picked unit)) from SI_Hashtable))) Greater than or equal to (SI_CoreGolemBaseHP + SI_StoneDropHpThreshold[(Level of Stone Integrity for (Picked unit))])
            • Then - Actions
              • -------- ############################ --------
              • -------- Creating a golem results in the Core Golem losing its max HP by the amount of the Threshold --------
              • -------- ############################ --------
              • Set SI_TempReal[1] = ((Load (Key HP Lost) of (Key (Picked unit)) from SI_Hashtable) + SI_StoneDropHpThreshold[(Level of Stone Integrity for (Picked unit))])
              • Hashtable - Save SI_TempReal[1] as (Key HP Lost) of (Key (Picked unit)) in SI_Hashtable
              • Set SI_TempLocation[1] = (Position of (Picked unit))
              • -------- ############################ --------
              • -------- Random number for deciding what kind of stone is going to drop --------
              • -------- ############################ --------
              • Set SI_TempInteger[1] = (Random integer number between 1 and SI_MaximumGolemType)
              • -------- - --------
              • -------- $$$------------If you added a new type of stone, here you need to add a new condition with a new integer for that new stone type. (Don't forget to modify "Actively Used" trigger, as well) --------
              • -------- - --------
              • -------- ############################ --------
              • -------- Creating stones and their SE according to the random number just specified - The stone's facing angle is random --------
              • -------- ############################ --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_TempInteger[1] Equal to 1
                • Then - Actions
                  • Unit - Create 1 Broken Rock for (Owner of (Picked unit)) at SI_TempLocation[1] facing (Random angle) degrees
                  • Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Weapons\GyroCopter\GyroCopterImpact.mdl
                  • Special Effect - Destroy (Last created special effect)
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_TempInteger[1] Equal to 2
                • Then - Actions
                  • Unit - Create 1 Broken Fire Stone for (Owner of (Picked unit)) at SI_TempLocation[1] facing (Random angle) degrees
                  • Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                  • Special Effect - Destroy (Last created special effect)
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_TempInteger[1] Equal to 3
                • Then - Actions
                  • Unit - Create 1 Broken Icy Stone for (Owner of (Picked unit)) at SI_TempLocation[1] facing (Random angle) degrees
                  • Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Weapons\FrostWyrmMissile\FrostWyrmMissile.mdl
                  • Special Effect - Destroy (Last created special effect)
                • Else - Actions
              • -------- - --------
              • -------- $$$------------END --------
              • -------- - --------
              • -------- ############################ --------
              • -------- The level of the ability is saved as the level of the stone for further uses --------
              • -------- ############################ --------
              • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Level of Stone Integrity for (Picked unit)) Equal to (Integer A)
                    • Then - Actions
                      • Hashtable - Save (Integer A) as (Key Level) of (Key (Last created unit)) in SI_Hashtable
                    • Else - Actions
              • -------- ############################ --------
              • -------- The Caster is saved for further uses (When the golem wants to return to its caster or the caster dies or etc.) --------
              • -------- ############################ --------
              • Hashtable - Save Handle Of(Picked unit) as (Key Minion) of (Key (Last created unit)) in SI_Hashtable
              • -------- ############################ --------
              • -------- Random distance that the stone is going to travel before hitting the ground --------
              • -------- ############################ --------
              • Set SI_TempReal[1] = (Random real number between SI_DroppedStoneDistanceMinimum and SI_DroppedStoneDistanceMaximum)
              • Hashtable - Save SI_TempReal[1] as (Key Distance) of (Key (Last created unit)) in SI_Hashtable
              • Animation - Change (Last created unit)'s animation speed to 20.00% of its original speed
              • -------- ############################ --------
              • -------- Adjust the flying height --------
              • -------- ############################ --------
              • Animation - Change (Last created unit) flying height to (SI_DroppedStoneHeight1 + 10.00) at 0.00
              • -------- ############################ --------
              • -------- This is the time it takes til the stone hits the ground --------
              • -------- ############################ --------
              • Hashtable - Save SI_DroppedStoneImpactTime as (Key Dropping Time) of (Key (Last created unit)) in SI_Hashtable
              • -------- ############################ --------
              • -------- Adds the stone to the SI_DroppedStoneGroup in order to get animated --------
              • -------- ############################ --------
              • Unit Group - Add (Last created unit) to SI_DroppedStoneGroup
              • Custom script: call RemoveLocation (udg_SI_TempLocation[1])
            • Else - Actions
  • Actively Used
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Stone Integrity
    • Actions
      • -------- ############################ --------
      • -------- Checking to see if there is enough HP remaining for a stone to be dropped --------
      • -------- ############################ --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Life of (Triggering unit)) Greater than or equal to ((SI_CoreGolemBaseHP - 1.00) + SI_StoneDropHpThreshold[(Level of (Ability being cast) for (Triggering unit))])
        • Then - Actions
          • -------- ############################ --------
          • -------- The rest is similar to the "Passively Used" trigger --------
          • -------- ############################ --------
          • Set SI_TempReal[3] = ((Load (Key HP Lost) of (Key (Triggering unit)) from SI_Hashtable) + SI_StoneDropHpThreshold[(Level of (Ability being cast) for (Triggering unit))])
          • Unit - Set life of (Triggering unit) to ((Life of (Triggering unit)) - SI_StoneDropHpThreshold[(Level of (Ability being cast) for (Triggering unit))])
          • Hashtable - Save SI_TempReal[3] as (Key HP Lost) of (Key (Triggering unit)) in SI_Hashtable
          • Set SI_TempLocation[2] = (Position of (Triggering unit))
          • Set SI_TempInteger[2] = (Random integer number between 1 and SI_MaximumGolemType)
          • -------- - --------
          • -------- $$$------------If you added a new type of stone, here you need to add a new condition with a new integer for that new stone type. (Don't forget to modify "Passively Used" trigger, as well) --------
          • -------- - --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SI_TempInteger[2] Equal to 1
            • Then - Actions
              • Unit - Create 1 Broken Rock for (Owner of (Triggering unit)) at SI_TempLocation[2] facing (Random angle) degrees
              • Special Effect - Create a special effect attached to the chest of (Triggering unit) using Abilities\Weapons\GyroCopter\GyroCopterImpact.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SI_TempInteger[2] Equal to 2
            • Then - Actions
              • Unit - Create 1 Broken Fire Stone for (Owner of (Triggering unit)) at SI_TempLocation[2] facing (Random angle) degrees
              • Special Effect - Create a special effect attached to the chest of (Triggering unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SI_TempInteger[2] Equal to 3
            • Then - Actions
              • Unit - Create 1 Broken Icy Stone for (Owner of (Triggering unit)) at SI_TempLocation[2] facing (Random angle) degrees
              • Special Effect - Create a special effect attached to the chest of (Triggering unit) using Abilities\Weapons\FrostWyrmMissile\FrostWyrmMissile.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
          • -------- - --------
          • -------- $$$------------END --------
          • -------- - --------
          • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of (Ability being cast) for (Triggering unit)) Equal to (Integer A)
                • Then - Actions
                  • Hashtable - Save (Integer A) as (Key Level) of (Key (Last created unit)) in SI_Hashtable
                • Else - Actions
          • Hashtable - Save Handle Of(Triggering unit) as (Key Minion) of (Key (Last created unit)) in SI_Hashtable
          • Set SI_TempReal[3] = (Random real number between SI_DroppedStoneDistanceMinimum and SI_DroppedStoneDistanceMaximum)
          • Hashtable - Save SI_TempReal[3] as (Key Distance) of (Key (Last created unit)) in SI_Hashtable
          • Animation - Change (Last created unit)'s animation speed to 20.00% of its original speed
          • Animation - Change (Last created unit) flying height to (SI_DroppedStoneHeight1 + 10.00) at 0.00
          • Hashtable - Save SI_DroppedStoneImpactTime as (Key Dropping Time) of (Key (Last created unit)) in SI_Hashtable
          • Unit Group - Add (Last created unit) to SI_DroppedStoneGroup
          • Custom script: call RemoveLocation (udg_SI_TempLocation[2])
        • Else - Actions
          • -------- ############################ --------
          • -------- The only thing new here is this part where if there is no more stones available, the mana used for the cast will be returned to the caster --------
          • -------- ############################ --------
          • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Stone Integrity for (Triggering unit)) Equal to (Integer A)
                • Then - Actions
                  • Unit - Set mana of (Triggering unit) to ((Mana of (Triggering unit)) + SI_Mana[(Integer A)])
                • Else - Actions
  • Dropping Stones
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • -------- ############################ --------
      • -------- Here the dropped stone is animated each 0.03 seconds of time --------
      • -------- ############################ --------
      • Unit Group - Pick every unit in SI_DroppedStoneGroup and do (Actions)
        • Loop - Actions
          • -------- ############################ --------
          • -------- Distance --------
          • -------- ############################ --------
          • Set SI_TempLocation[3] = (Position of (Picked unit))
          • Set SI_TempReal[4] = (((Load (Key Distance) of (Key (Picked unit)) from SI_Hashtable) / SI_DroppedStoneImpactTime) / 33.33)
          • Set SI_TempLocation[4] = (SI_TempLocation[3] offset by SI_TempReal[4] towards (Facing of (Picked unit)) degrees)
          • Unit - Move (Picked unit) instantly to SI_TempLocation[4]
          • -------- ############################ --------
          • -------- Height - Height is divided into three parts: (1) From starting height to the second height (2) From second height to the starting height (3) From the starting height to the ground --------
          • -------- ############################ --------
          • Set SI_TempReal[4] = (SI_DroppedStoneHeight2 - (SI_DroppedStoneHeight1 + 10.00))
          • Set SI_TempReal[5] = (Load (Key Dropping Time) of (Key (Picked unit)) from SI_Hashtable)
          • -------- ############################ --------
          • -------- Height - (1) --------
          • -------- ############################ --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SI_TempReal[5] Greater than or equal to (2.00 x (SI_DroppedStoneImpactTime / 3.00))
            • Then - Actions
              • Animation - Change (Picked unit) flying height to ((Current flying height of (Picked unit)) + ((SI_TempReal[4] / (SI_DroppedStoneImpactTime / 3.00)) / 33.33)) at 0.00
            • Else - Actions
          • -------- ############################ --------
          • -------- Height - (2) --------
          • -------- If the first height is specified higher than the second height, this part debugs it --------
          • -------- ############################ --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SI_TempReal[5] Less than (2.00 x (SI_DroppedStoneImpactTime / 3.00))
              • SI_TempReal[5] Greater than or equal to (SI_DroppedStoneImpactTime / 3.00)
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_TempReal[4] Less than 0.00
                • Then - Actions
                  • Animation - Change (Picked unit) flying height to ((Current flying height of (Picked unit)) + ((SI_TempReal[4] / (SI_DroppedStoneImpactTime / 3.00)) / 33.33)) at 0.00
                • Else - Actions
                  • Animation - Change (Picked unit) flying height to ((Current flying height of (Picked unit)) - ((SI_TempReal[4] / (SI_DroppedStoneImpactTime / 3.00)) / 33.33)) at 0.00
            • Else - Actions
          • -------- ############################ --------
          • -------- Height - (3) --------
          • -------- ############################ --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SI_TempReal[5] Less than (SI_DroppedStoneImpactTime / 3.00)
            • Then - Actions
              • Animation - Change (Picked unit) flying height to ((Current flying height of (Picked unit)) - ((SI_DroppedStoneHeight1 / (SI_DroppedStoneImpactTime / 3.00)) / 33.33)) at 0.00
            • Else - Actions
          • Set SI_TempReal[5] = (Load (Key Dropping Time) of (Key (Picked unit)) from SI_Hashtable)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SI_TempReal[5] Less than or equal to 0.00
            • Then - Actions
              • -------- ############################ --------
              • -------- This is where the distance is travelled and the stone hits the ground --------
              • -------- ############################ --------
              • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
              • -------- ############################ --------
              • -------- Removing this stone from this group, since it's no longer needed in this group --------
              • -------- ############################ --------
              • Unit Group - Remove (Picked unit) from SI_DroppedStoneGroup
              • -------- ############################ --------
              • -------- Adding the stone to SI_GroundedStonesGroup for vibration animation --------
              • -------- ############################ --------
              • Unit Group - Add (Picked unit) to SI_GroundedStonesGroup
              • -------- ############################ --------
              • -------- Adding the stun ability and casting it along with its SE --------
              • -------- ############################ --------
              • Unit - Add SI_DroppedStoneAbility[(Load (Key Level) of (Key (Picked unit)) from SI_Hashtable)] to (Picked unit)
              • Unit - Order (Picked unit) to Orc Tauren Chieftain - War Stomp
              • Special Effect - Create a special effect at SI_TempLocation[3] using Abilities\Spells\Orc\WarStomp\WarStompCaster.mdl
              • Special Effect - Destroy (Last created special effect)
              • -------- ############################ --------
              • -------- Cutting trees (If you need additional destructibles to be killed, add them here) --------
              • -------- ############################ --------
              • Destructible - Pick every destructible within SI_DroppedStoneImpactArea of SI_TempLocation[3] and do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Destructible-type of (Picked destructible)) Equal to Summer Tree Wall
                    • Then - Actions
                      • Destructible - Kill (Picked destructible)
                    • Else - Actions
              • -------- ############################ --------
              • -------- Position is saved for the center of vibratiion --------
              • -------- ############################ --------
              • Hashtable - Save Handle Of(Position of (Picked unit)) as (Key Resting Place) of (Key (Picked unit)) in SI_Hashtable
              • -------- ############################ --------
              • -------- The time that this stone is going to spend on the ground, vibrating --------
              • -------- ############################ --------
              • Hashtable - Save SI_GroundedStonesTime as (Key Resting Time) of (Key (Picked unit)) in SI_Hashtable
              • -------- ############################ --------
              • -------- Initial vibration intensity is saved for further use --------
              • -------- ############################ --------
              • Hashtable - Save SI_VibrationIntensityMinimum as (Key Vibration Intensity) of (Key (Picked unit)) in SI_Hashtable
              • -------- ############################ --------
              • -------- Removing the previously added stun ability --------
              • -------- ############################ --------
              • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
                • Loop - Actions
                  • Unit - Remove SI_DroppedStoneAbility[(Integer A)] from (Picked unit)
              • -------- ############################ --------
              • -------- The special effect when the stone is on the ground (Fire and cold air effects) --------
              • -------- ############################ --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of (Picked unit)) Equal to Broken Fire Stone
                • Then - Actions
                  • Special Effect - Create a special effect at SI_TempLocation[4] using Environment\LargeBuildingFire\LargeBuildingFire1.mdl
                  • Hashtable - Save Handle Of(Last created special effect) as (Key Effect) of (Key (Picked unit)) in SI_Hashtable
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of (Picked unit)) Equal to Broken Icy Stone
                • Then - Actions
                  • Special Effect - Create a special effect at SI_TempLocation[4] using Abilities\Weapons\FrostWyrmMissile\FrostWyrmMissile.mdl
                  • Hashtable - Save Handle Of(Last created special effect) as (Key Effect) of (Key (Picked unit)) in SI_Hashtable
                • Else - Actions
            • Else - Actions
              • -------- ############################ --------
              • -------- Reducing the travel time remaining by 0.03 seconds and saving it --------
              • -------- ############################ --------
              • Set SI_TempReal[5] = (SI_TempReal[5] - 0.03)
              • Hashtable - Save SI_TempReal[5] as (Key Dropping Time) of (Key (Picked unit)) in SI_Hashtable
          • Custom script: call RemoveLocation (udg_SI_TempLocation[3])
          • Custom script: call RemoveLocation (udg_SI_TempLocation[4])
      • -------- ############################ --------
      • -------- This part is for vibration animation and creating the golem --------
      • -------- ############################ --------
      • Unit Group - Pick every unit in SI_GroundedStonesGroup and do (Actions)
        • Loop - Actions
          • -------- ############################ --------
          • -------- Increasing the vibration intensity by a fraction: The number added equals to (Range of vibration intensity/time to spend on the grouund) --------
          • -------- ############################ --------
          • Set SI_TempReal[4] = (Load (Key Vibration Intensity) of (Key (Picked unit)) from SI_Hashtable)
          • Set SI_TempReal[5] = (SI_TempReal[4] + (((SI_VibrationIntensityMaximum - SI_VibrationIntensityMinimum) / SI_GroundedStonesTime) / 33.33))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SI_TempReal[5] Less than SI_VibrationIntensityMaximum
            • Then - Actions
              • Hashtable - Save SI_TempReal[5] as (Key Vibration Intensity) of (Key (Picked unit)) in SI_Hashtable
            • Else - Actions
              • Set SI_TempReal[4] = SI_VibrationIntensityMaximum
              • Hashtable - Save SI_TempReal[4] as (Key Vibration Intensity) of (Key (Picked unit)) in SI_Hashtable
          • -------- ############################ --------
          • -------- Moving the stone to random points around its center to give a vibration effect --------
          • -------- ############################ --------
          • Set SI_TempLocation[3] = ((Load (Key Resting Place) of (Key (Picked unit)) in SI_Hashtable) offset by SI_TempReal[4] towards (Random angle) degrees)
          • Unit - Move (Picked unit) instantly to SI_TempLocation[3]
          • -------- ############################ --------
          • -------- Checking to see if the time for spending on the ground is over or not --------
          • -------- ############################ --------
          • Set SI_TempReal[4] = (Load (Key Resting Time) of (Key (Picked unit)) from SI_Hashtable)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SI_TempReal[4] Less than or equal to 0.00
            • Then - Actions
              • -------- ############################ --------
              • -------- If the time is over the Golem is created and added to the SI_TinyGolemGroup and the stone is removed --------
              • -------- ############################ --------
              • Unit Group - Remove (Picked unit) from SI_GroundedStonesGroup
              • -------- ############################ --------
              • -------- Checking the level saved for creating a golem of that level --------
              • -------- ############################ --------
              • Set SI_TempInteger[3] = (Load (Key Level) of (Key (Picked unit)) from SI_Hashtable)
              • -------- ############################ --------
              • -------- An algorithm that decides the type of the Golem to be created and its level - Check the "Constants" trigger for more info --------
              • -------- ############################ --------
              • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
                • Loop - Actions
                  • For each (Integer B) from 1 to SI_MaximumGolemType, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Integer A) Equal to SI_TempInteger[3]
                          • (Unit-type of (Picked unit)) Equal to SI_StoneType[(Integer B)]
                        • Then - Actions
                          • Unit - Create 1 SI_TinyGolemType[((((Integer A) - 1) x SI_MaximumGolemType) + (Integer B))] for (Owner of (Picked unit)) at (Load (Key Resting Place) of (Key (Picked unit)) in SI_Hashtable) facing (Random angle) degrees
                          • -------- - --------
                          • -------- @@@------------If you added a new type of golem, here you need to add a new condition with a new integer for its type, and you can add special effects to it. --------
                          • -------- - --------
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Integer B) Equal to 1
                            • Then - Actions
                              • Special Effect - Create a special effect at (Load (Key Resting Place) of (Key (Picked unit)) in SI_Hashtable) using Abilities\Weapons\GyroCopter\GyroCopterImpact.mdl
                              • Special Effect - Destroy (Last created special effect)
                              • Special Effect - Create a special effect at (Load (Key Resting Place) of (Key (Picked unit)) in SI_Hashtable) using Abilities\Weapons\GyroCopter\GyroCopterImpact.mdl
                              • Special Effect - Destroy (Last created special effect)
                              • Special Effect - Create a special effect at (Load (Key Resting Place) of (Key (Picked unit)) in SI_Hashtable) using Abilities\Weapons\GyroCopter\GyroCopterImpact.mdl
                              • Special Effect - Destroy (Last created special effect)
                              • Sound - Play RockGolemBirthSound <gen> at 100.00% volume, located at (Load (Key Resting Place) of (Key (Picked unit)) in SI_Hashtable) with Z offset 0.00
                              • Hashtable - Save (Integer B) as (Key Type) of (Key (Last created unit)) in SI_Hashtable
                            • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Integer B) Equal to 2
                            • Then - Actions
                              • Special Effect - Create a special effect attached to the chest of (Last created unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                              • Hashtable - Save Handle Of(Last created special effect) as 1 of (Key (Last created unit)) in (Last created hashtable)
                              • Special Effect - Create a special effect attached to the right hand of (Last created unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                              • Hashtable - Save Handle Of(Last created special effect) as 2 of (Key (Last created unit)) in (Last created hashtable)
                              • Special Effect - Create a special effect attached to the left hand of (Last created unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                              • Hashtable - Save Handle Of(Last created special effect) as 3 of (Key (Last created unit)) in (Last created hashtable)
                              • Special Effect - Create a special effect attached to the head of (Last created unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                              • Hashtable - Save Handle Of(Last created special effect) as 4 of (Key (Last created unit)) in (Last created hashtable)
                              • Hashtable - Save (Integer B) as (Key Type) of (Key (Last created unit)) in SI_Hashtable
                            • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Integer B) Equal to 3
                            • Then - Actions
                              • Special Effect - Create a special effect attached to the chest of (Last created unit) using Abilities\Weapons\FrostWyrmMissile\FrostWyrmMissile.mdl
                              • Hashtable - Save Handle Of(Last created special effect) as 1 of (Key (Last created unit)) in (Last created hashtable)
                              • Special Effect - Create a special effect attached to the right hand of (Last created unit) using Abilities\Weapons\SpiritOfVengeanceMissile\SpiritOfVengeanceMissile.mdl
                              • Hashtable - Save Handle Of(Last created special effect) as 2 of (Key (Last created unit)) in (Last created hashtable)
                              • Special Effect - Create a special effect attached to the left hand of (Last created unit) using Abilities\Weapons\SpiritOfVengeanceMissile\SpiritOfVengeanceMissile.mdl
                              • Hashtable - Save Handle Of(Last created special effect) as 3 of (Key (Last created unit)) in (Last created hashtable)
                              • Special Effect - Create a special effect attached to the head of (Last created unit) using Abilities\Weapons\SpiritOfVengeanceMissile\SpiritOfVengeanceMissile.mdl
                              • Hashtable - Save Handle Of(Last created special effect) as 4 of (Key (Last created unit)) in (Last created hashtable)
                              • Hashtable - Save (Integer B) as (Key Type) of (Key (Last created unit)) in SI_Hashtable
                            • Else - Actions
                          • -------- - --------
                          • -------- @@@------------END --------
                          • -------- - --------
                          • -------- ############################ --------
                          • -------- Adding the Golem to SI_TinyGolemGroup --------
                          • -------- ############################ --------
                          • Unit Group - Add (Last created unit) to SI_TinyGolemGroup
                          • -------- ############################ --------
                          • -------- Transferring the caster ID and level ID from the stone to the golem and removing the stone --------
                          • -------- ############################ --------
                          • Set SI_TempUnit[1] = (Load (Key Minion) of (Key (Picked unit)) in SI_Hashtable)
                          • Special Effect - Destroy (Load (Key Effect) of (Key (Picked unit)) in SI_Hashtable)
                          • Set SI_TempLocation[4] = (Load (Key Resting Place) of (Key (Picked unit)) in SI_Hashtable)
                          • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in SI_Hashtable
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • ((Picked unit) is selected by (Owner of (Picked unit))) Equal to True
                            • Then - Actions
                              • Selection - Add (Last created unit) to selection for (Owner of (Picked unit))
                            • Else - Actions
                          • Unit - Remove (Picked unit) from the game
                          • Hashtable - Save Handle OfSI_TempUnit[1] as (Key Minion) of (Key (Last created unit)) in SI_Hashtable
                          • Hashtable - Save SI_TempInteger[3] as (Key Level) of (Key (Last created unit)) in SI_Hashtable
                          • Custom script: call RemoveLocation (udg_SI_TempLocation[4])
                        • Else - Actions
            • Else - Actions
              • -------- ############################ --------
              • -------- If the time is not over the time is reduced and gets saved --------
              • -------- ############################ --------
              • Set SI_TempReal[4] = (SI_TempReal[4] - 0.03)
              • Hashtable - Save SI_TempReal[4] as (Key Resting Time) of (Key (Picked unit)) in SI_Hashtable
          • Custom script: call RemoveLocation (udg_SI_TempLocation[3])
  • Merging Golems
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
    • Actions
      • -------- ############################ --------
      • -------- Merging Golems with each other to form a Greater Golem --------
      • -------- ############################ --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Merge (Tiny Golem)
        • Then - Actions
          • -------- ############################ --------
          • -------- Checking if the merging golems are of the same level and if they belong to the same caster --------
          • -------- ############################ --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Target unit of ability being cast) is in SI_TinyGolemGroup) Equal to True
              • (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable) Equal to (Load (Key Minion) of (Key (Target unit of ability being cast)) in SI_Hashtable)
              • (Load (Key Level) of (Key (Triggering unit)) from SI_Hashtable) Equal to (Load (Key Level) of (Key (Target unit of ability being cast)) from SI_Hashtable)
            • Then - Actions
              • -------- ############################ --------
              • -------- Both golems get removed from their group --------
              • -------- ############################ --------
              • Unit Group - Remove (Triggering unit) from SI_TinyGolemGroup
              • Unit Group - Remove (Target unit of ability being cast) from SI_TinyGolemGroup
              • -------- ############################ --------
              • -------- Their types are stored --------
              • -------- ############################ --------
              • Set SI_TempInteger[4] = (Load (Key Type) of (Key (Triggering unit)) from SI_Hashtable)
              • Set SI_TempInteger[5] = (Load (Key Type) of (Key (Target unit of ability being cast)) from SI_Hashtable)
              • -------- ############################ --------
              • -------- Their level is stored --------
              • -------- ############################ --------
              • Set SI_TempInteger[6] = (Load (Key Level) of (Key (Triggering unit)) from SI_Hashtable)
              • -------- ############################ --------
              • -------- The greater golem's position and facing angle will match the ones for the target golem of ability being cast --------
              • -------- ############################ --------
              • Set SI_TempLocation[5] = (Position of (Target unit of ability being cast))
              • Set SI_TempReal[6] = (Facing of (Target unit of ability being cast))
              • -------- ############################ --------
              • -------- storing the caster ID for transferring from the Tiny Golems to the Greater Golem --------
              • -------- ############################ --------
              • Set SI_TempUnit[2] = (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)
              • -------- ############################ --------
              • -------- Destroying all the special Effects --------
              • -------- ############################ --------
              • For each (Integer A) from 1 to 4, do (Actions)
                • Loop - Actions
                  • Special Effect - Destroy (Load (Integer A) of (Key (Triggering unit)) in SI_Hashtable)
                  • Special Effect - Destroy (Load (Integer A) of (Key (Target unit of ability being cast)) in SI_Hashtable)
              • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in SI_Hashtable
              • Hashtable - Clear all child hashtables of child (Key (Target unit of ability being cast)) in SI_Hashtable
              • -------- ############################ --------
              • -------- This part is for selection adjustments - If the player has one of the merging golems in selection, the new Greater Golem will be added to the selection --------
              • -------- ############################ --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • ((Triggering unit) is selected by (Owner of (Triggering unit))) Equal to True
                      • ((Target unit of ability being cast) is selected by (Owner of (Triggering unit))) Equal to True
                • Then - Actions
                  • Set SI_TempBoolean = True
                • Else - Actions
                  • Set SI_TempBoolean = False
              • -------- ############################ --------
              • -------- The current HP for both Golems are stored for the Greater Golem --------
              • -------- ############################ --------
              • Set SI_TempReal[7] = ((Life of (Triggering unit)) + (Life of (Target unit of ability being cast)))
              • -------- ############################ --------
              • -------- Removal of the Tiny Golems --------
              • -------- ############################ --------
              • Unit - Remove (Target unit of ability being cast) from the game
              • Unit - Remove (Triggering unit) from the game
              • -------- ############################ --------
              • -------- Creating the Greater Golem --------
              • -------- ############################ --------
              • Unit - Create 1 SI_GreaterGolemType[SI_TempInteger[6]] for (Owner of (Triggering unit)) at SI_TempLocation[5] facing SI_TempReal[6] degrees
              • Custom script: call RemoveLocation (udg_SI_TempLocation[5])
              • -------- ############################ --------
              • -------- Transferring the caster ID and level ID for the Greater Golem --------
              • -------- ############################ --------
              • Hashtable - Save Handle OfSI_TempUnit[2] as (Key Minion) of (Key (Last created unit)) in SI_Hashtable
              • Hashtable - Save SI_TempInteger[6] as (Key Level) of (Key (Last created unit)) in SI_Hashtable
              • -------- ############################ --------
              • -------- Adding the created golem to SI_GreaterGolemGroup --------
              • -------- ############################ --------
              • Unit Group - Add (Last created unit) to SI_GreaterGolemGroup
              • -------- ############################ --------
              • -------- Assigning different abilities and different special effects based on the types of the merging golems --------
              • -------- ############################ --------
              • -------- - --------
              • -------- @@@------------If you added a new type of golem, here you must configure its combination with other types of golems. --------
              • -------- - --------
              • -------- - --------
              • -------- )))(((------------If you added new abilities for Grater Golems, you can assign the abilities here. Just supply the class number to the Add Ability commands like this: ((Class Number - 1) x SI_MaxLevel) + (Integer A) --------
              • -------- - --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_TempInteger[4] Equal to 1
                  • SI_TempInteger[5] Equal to 1
                • Then - Actions
                  • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • SI_TempInteger[6] Equal to (Integer A)
                        • Then - Actions
                          • Unit - Add SI_GreaterGolemAbility[((6 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Unit - Add SI_GreaterGolemAbility[((5 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                        • Else - Actions
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • And - All (Conditions) are true
                        • Conditions
                          • SI_TempInteger[4] Equal to 1
                          • SI_TempInteger[5] Equal to 2
                      • And - All (Conditions) are true
                        • Conditions
                          • SI_TempInteger[4] Equal to 2
                          • SI_TempInteger[5] Equal to 1
                • Then - Actions
                  • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • SI_TempInteger[6] Equal to (Integer A)
                        • Then - Actions
                          • Unit - Add SI_GreaterGolemAbility[((4 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Special Effect - Create a special effect attached to the right hand of (Last created unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                          • Hashtable - Save Handle Of(Last created special effect) as 1 of (Key (Last created unit)) in SI_Hashtable
                        • Else - Actions
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_TempInteger[4] Equal to 2
                  • SI_TempInteger[5] Equal to 2
                • Then - Actions
                  • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • SI_TempInteger[6] Equal to (Integer A)
                        • Then - Actions
                          • Unit - Add SI_GreaterGolemAbility[((4 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Unit - Add SI_GreaterGolemAbility[((3 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Unit - Add SI_GreaterGolemAbility[((7 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Special Effect - Create a special effect attached to the right hand of (Last created unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                          • Hashtable - Save Handle Of(Last created special effect) as 1 of (Key (Last created unit)) in SI_Hashtable
                          • Special Effect - Create a special effect attached to the left hand of (Last created unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                          • Hashtable - Save Handle Of(Last created special effect) as 2 of (Key (Last created unit)) in SI_Hashtable
                        • Else - Actions
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_TempInteger[4] Equal to 3
                  • SI_TempInteger[5] Equal to 3
                • Then - Actions
                  • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • SI_TempInteger[6] Equal to (Integer A)
                        • Then - Actions
                          • Unit - Add SI_GreaterGolemAbility[((1 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Unit - Add SI_GreaterGolemAbility[((0 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Special Effect - Create a special effect attached to the right hand of (Last created unit) using Abilities\Weapons\FrostWyrmMissile\FrostWyrmMissile.mdl
                          • Hashtable - Save Handle Of(Last created special effect) as 1 of (Key (Last created unit)) in SI_Hashtable
                          • Special Effect - Create a special effect attached to the left hand of (Last created unit) using Abilities\Weapons\FrostWyrmMissile\FrostWyrmMissile.mdl
                          • Hashtable - Save Handle Of(Last created special effect) as 2 of (Key (Last created unit)) in SI_Hashtable
                        • Else - Actions
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • And - All (Conditions) are true
                        • Conditions
                          • SI_TempInteger[4] Equal to 2
                          • SI_TempInteger[5] Equal to 3
                      • And - All (Conditions) are true
                        • Conditions
                          • SI_TempInteger[4] Equal to 3
                          • SI_TempInteger[5] Equal to 2
                • Then - Actions
                  • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • SI_TempInteger[6] Equal to (Integer A)
                        • Then - Actions
                          • Unit - Add SI_GreaterGolemAbility[((6 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Unit - Add SI_GreaterGolemAbility[((2 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Special Effect - Create a special effect attached to the right hand of (Last created unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                          • Hashtable - Save Handle Of(Last created special effect) as 1 of (Key (Last created unit)) in SI_Hashtable
                          • Special Effect - Create a special effect attached to the left hand of (Last created unit) using Abilities\Weapons\FrostWyrmMissile\FrostWyrmMissile.mdl
                          • Hashtable - Save Handle Of(Last created special effect) as 2 of (Key (Last created unit)) in SI_Hashtable
                        • Else - Actions
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • And - All (Conditions) are true
                        • Conditions
                          • SI_TempInteger[4] Equal to 1
                          • SI_TempInteger[5] Equal to 3
                      • And - All (Conditions) are true
                        • Conditions
                          • SI_TempInteger[4] Equal to 3
                          • SI_TempInteger[5] Equal to 1
                • Then - Actions
                  • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • SI_TempInteger[6] Equal to (Integer A)
                        • Then - Actions
                          • Unit - Add SI_GreaterGolemAbility[((1 x SI_MaxLevel) + (Integer A))] to (Last created unit)
                          • Special Effect - Create a special effect attached to the left hand of (Last created unit) using Abilities\Weapons\FrostWyrmMissile\FrostWyrmMissile.mdl
                          • Hashtable - Save Handle Of(Last created special effect) as 1 of (Key (Last created unit)) in SI_Hashtable
                        • Else - Actions
                • Else - Actions
              • -------- - --------
              • -------- @@@------------END --------
              • -------- - --------
              • -------- - --------
              • -------- )))(((------------END --------
              • -------- - --------
              • -------- ############################ --------
              • -------- Merging SE --------
              • -------- ############################ --------
              • Special Effect - Create a special effect attached to the origin of (Last created unit) using Abilities\Spells\Other\Charm\CharmTarget.mdl
              • Special Effect - Destroy (Last created special effect)
              • -------- ############################ --------
              • -------- Setting the HP of the Greater Golem to the sum of HPs for the Tiny Golems --------
              • -------- ############################ --------
              • Unit - Set life of (Last created unit) to SI_TempReal[7]
              • -------- ############################ --------
              • -------- Adding (or not adding) the Greater Golem to the selection --------
              • -------- ############################ --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_TempBoolean Equal to True
                • Then - Actions
                  • Selection - Add (Last created unit) to selection for (Owner of (Last created unit))
                • Else - Actions
            • Else - Actions
        • Else - Actions
      • -------- ############################ --------
      • -------- Merging Golems with the Core Golem --------
      • -------- ############################ --------
      • -------- ############################ --------
      • -------- Checking if the Tiny/Greater Golem belongs to the Core Golem --------
      • -------- ############################ --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • (Ability being cast) Equal to Merge (Tiny Golem)
              • (Ability being cast) Equal to Merge (Greater Golem)
          • (Target unit of ability being cast) Equal to (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)
        • Then - Actions
          • -------- ############################ --------
          • -------- This part is the same as before --------
          • -------- ############################ --------
          • Unit Group - Remove (Triggering unit) from SI_TinyGolemGroup
          • Unit Group - Remove (Triggering unit) from SI_GreaterGolemGroup
          • Set SI_TempInteger[4] = (Load (Key Level) of (Key (Triggering unit)) from SI_Hashtable)
          • -------- ############################ --------
          • -------- Returning to the Core Golem the Lost Max HP as an HP marked as "Returned" which needs to be restored before it can form a new stone (The Returned HP is Based on the level of the Tiny/Greate Golem) --------
          • -------- ############################ --------
          • Set SI_TempReal[7] = ((Load (Key HP Lost) of (Key (Target unit of ability being cast)) from SI_Hashtable) - SI_StoneDropHpThreshold[SI_TempInteger[4]])
          • Set SI_TempReal[6] = ((Load (Key Returned HP) of (Key (Target unit of ability being cast)) from SI_Hashtable) + SI_StoneDropHpThreshold[SI_TempInteger[4]])
          • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_GreaterGolemType[(Integer A)] Equal to (Unit-type of (Triggering unit))
                • Then - Actions
                  • Set SI_TempReal[7] = (SI_TempReal[7] - SI_StoneDropHpThreshold[SI_TempInteger[4]])
                  • Set SI_TempReal[6] = (SI_TempReal[6] + SI_StoneDropHpThreshold[SI_TempInteger[4]])
                • Else - Actions
          • Hashtable - Save SI_TempReal[7] as (Key HP Lost) of (Key (Target unit of ability being cast)) in SI_Hashtable
          • Hashtable - Save SI_TempReal[6] as (Key Returned HP) of (Key (Target unit of ability being cast)) in SI_Hashtable
          • -------- ############################ --------
          • -------- Healing the life of the Core Golem by a percent of the Tiny/Greater Golem's HP --------
          • -------- ############################ --------
          • Set SI_TempReal[6] = ((Life of (Triggering unit)) x SI_HealthPercentReturned)
          • Unit - Set life of (Target unit of ability being cast) to ((Life of (Target unit of ability being cast)) + SI_TempReal[6])
          • -------- ############################ --------
          • -------- SE removal --------
          • -------- ############################ --------
          • For each (Integer A) from 1 to SI_GolemsSpecialEffectNumber, do (Actions)
            • Loop - Actions
              • Special Effect - Destroy (Load (Integer A) of (Key (Triggering unit)) in SI_Hashtable)
          • -------- ############################ --------
          • -------- Merging SE --------
          • -------- ############################ --------
          • Special Effect - Create a special effect attached to the origin of (Target unit of ability being cast) using Abilities\Spells\Other\Charm\CharmTarget.mdl
          • Special Effect - Destroy (Last created special effect)
          • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in SI_Hashtable
          • -------- ############################ --------
          • -------- Tiny/Greater Golem removal --------
          • -------- ############################ --------
          • Unit - Remove (Triggering unit) from the game
        • Else - Actions
  • Dying Debug and Clear
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • -------- ############################ --------
      • -------- This trigger has nothing special - Whenever a summoned stone/golem dies, it gets removed and the Lost Hp is returned to the hero just like the previous trigger --------
      • -------- ############################ --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Triggering unit) is in SI_DroppedStoneGroup) Equal to True
        • Then - Actions
          • Unit Group - Remove (Triggering unit) from SI_DroppedStoneGroup
          • Set SI_TempInteger[7] = (Load (Key Level) of (Key (Triggering unit)) from SI_Hashtable)
          • Set SI_TempReal[9] = ((Load (Key HP Lost) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) from SI_Hashtable) - SI_StoneDropHpThreshold[SI_TempInteger[7]])
          • Set SI_TempReal[8] = ((Load (Key Returned HP) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) from SI_Hashtable) + SI_StoneDropHpThreshold[SI_TempInteger[7]])
          • Hashtable - Save SI_TempReal[9] as (Key HP Lost) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) in SI_Hashtable
          • Hashtable - Save SI_TempReal[8] as (Key Returned HP) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) in SI_Hashtable
          • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in SI_Hashtable
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Triggering unit) is in SI_GroundedStonesGroup) Equal to True
        • Then - Actions
          • Unit Group - Remove (Triggering unit) from SI_GroundedStonesGroup
          • Set SI_TempLocation[6] = (Load (Key Resting Place) of (Key (Triggering unit)) in SI_Hashtable)
          • Special Effect - Destroy (Load (Key Effect) of (Key (Triggering unit)) in SI_Hashtable)
          • Custom script: call RemoveLocation (udg_SI_TempLocation[6])
          • Set SI_TempInteger[7] = (Load (Key Level) of (Key (Triggering unit)) from SI_Hashtable)
          • Set SI_TempReal[9] = ((Load (Key HP Lost) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) from SI_Hashtable) - SI_StoneDropHpThreshold[SI_TempInteger[7]])
          • Set SI_TempReal[8] = ((Load (Key Returned HP) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) from SI_Hashtable) + SI_StoneDropHpThreshold[SI_TempInteger[7]])
          • Hashtable - Save SI_TempReal[9] as (Key HP Lost) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) in SI_Hashtable
          • Hashtable - Save SI_TempReal[8] as (Key Returned HP) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) in SI_Hashtable
          • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in SI_Hashtable
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • ((Triggering unit) is in SI_GreaterGolemGroup) Equal to True
              • ((Triggering unit) is in SI_TinyGolemGroup) Equal to True
        • Then - Actions
          • Unit Group - Remove (Triggering unit) from SI_GreaterGolemGroup
          • Unit Group - Remove (Triggering unit) from SI_TinyGolemGroup
          • For each (Integer A) from 1 to SI_GolemsSpecialEffectNumber, do (Actions)
            • Loop - Actions
              • Special Effect - Destroy (Load (Integer A) of (Key (Triggering unit)) in SI_Hashtable)
          • Set SI_TempInteger[7] = (Load (Key Level) of (Key (Triggering unit)) from SI_Hashtable)
          • Set SI_TempReal[9] = ((Load (Key HP Lost) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) from SI_Hashtable) - SI_StoneDropHpThreshold[SI_TempInteger[7]])
          • Set SI_TempReal[8] = ((Load (Key Returned HP) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) from SI_Hashtable) + SI_StoneDropHpThreshold[SI_TempInteger[7]])
          • For each (Integer A) from 1 to SI_MaxLevel, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SI_GreaterGolemType[(Integer A)] Equal to (Unit-type of (Triggering unit))
                • Then - Actions
                  • Set SI_TempReal[9] = (SI_TempReal[9] - SI_StoneDropHpThreshold[SI_TempInteger[7]])
                  • Set SI_TempReal[8] = (SI_TempReal[8] + SI_StoneDropHpThreshold[SI_TempInteger[7]])
                • Else - Actions
          • Hashtable - Save SI_TempReal[9] as (Key HP Lost) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) in SI_Hashtable
          • Hashtable - Save SI_TempReal[8] as (Key Returned HP) of (Key (Load (Key Minion) of (Key (Triggering unit)) in SI_Hashtable)) in SI_Hashtable
          • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in SI_Hashtable
        • Else - Actions
      • -------- ############################ --------
      • -------- And if the dying unit is the Core Golem itself, all the stones/golems belonging to it die and the hero is removed from SI_CoreGolemGroup --------
      • -------- ############################ --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Triggering unit) is in SI_CoreGolemGroup) Equal to True
        • Then - Actions
          • Unit Group - Remove (Triggering unit) from SI_CoreGolemGroup
          • Unit Group - Pick every unit in SI_GroundedStonesGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Triggering unit) Equal to (Load (Key Minion) of (Key (Picked unit)) in SI_Hashtable)
                • Then - Actions
                  • Unit - Kill (Picked unit)
                • Else - Actions
          • Unit Group - Pick every unit in SI_DroppedStoneGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Triggering unit) Equal to (Load (Key Minion) of (Key (Picked unit)) in SI_Hashtable)
                • Then - Actions
                  • Unit - Kill (Picked unit)
                • Else - Actions
          • Unit Group - Pick every unit in SI_GreaterGolemGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Triggering unit) Equal to (Load (Key Minion) of (Key (Picked unit)) in SI_Hashtable)
                • Then - Actions
                  • Unit - Kill (Picked unit)
                • Else - Actions
          • Unit Group - Pick every unit in SI_TinyGolemGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Triggering unit) Equal to (Load (Key Minion) of (Key (Picked unit)) in SI_Hashtable)
                • Then - Actions
                  • Unit - Kill (Picked unit)
                • Else - Actions
          • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in SI_Hashtable
        • Else - Actions
  • Constants
  • Constants
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set SI_Hashtable = (Last created hashtable)
      • -------- - --------
      • -------- - --------
      • -------- Each level you specify for "Stone Integrity" you need to specify the amount of mana that is used by that level to these index-enhanced variables --------
      • -------- These variables are needed for the situation where you cast the spell but there is no more stones available to drop, thus returning the mana back to the caster --------
      • Set SI_Mana[1] = 50.00
      • Set SI_Mana[2] = 60.00
      • Set SI_Mana[3] = 70.00
      • -------- ----------------------------------------And also you should specify the max level of "Stone Integrity" that you want to use here, for the sake of enumerations --------
      • Set SI_MaxLevel = 3
      • -------- ----------------------------------------The number of different types of golems are specified here, again for the sake of enumeration --------
      • Set SI_MaximumGolemType = 3
      • -------- ----------------------------------------If you increase the number of types you should specify them to the following constants --------
      • -------- ----------------------------------------The number of indexes should be like this: (SI_MaxLevel x SI_MaximumGolemType) --------
      • -------- ----------------------------------------The order is important! Look at the pattern that I used and follow the same pattern --------
      • -------- -----------------------------------------------------------------------------------------------------Rock-Fire-Ice/Rock-Fire-Ice/Rock-Fire-Ice --------
      • -------- WARNING-------------If you increase the types you increase the number of combinations for their merging ability --------
      • -------- WARNING-------------And for that matter you should add some code in the "Dropping Stones" and "Merging Golems" triggers where you see this sign: @@@ --------
      • Set SI_TinyGolemType[1] = Tiny Rock Golem - Level 01
      • Set SI_TinyGolemType[2] = Tiny Fire Golem - Level 01
      • Set SI_TinyGolemType[3] = Tiny Ice Golem - Level 01
      • Set SI_TinyGolemType[4] = Tiny Rock Golem - Level 02
      • Set SI_TinyGolemType[5] = Tiny Fire Golem - Level 02
      • Set SI_TinyGolemType[6] = Tiny Ice Golem - Level 02
      • Set SI_TinyGolemType[7] = Tiny Rock Golem - Level 03
      • Set SI_TinyGolemType[8] = Tiny Fire Golem - Level 03
      • Set SI_TinyGolemType[9] = Tiny Ice Golem - Level 03
      • -------- ----------------------------------------These are the types of stones that drop (You just need to specify one type for all the levels) --------
      • -------- -----------------------------------------One type of stone is needed for every new Tiny Golem type that you add --------
      • -------- ----------------------------------------The number of its indexes are equal to SI_MaximumGolemType --------
      • -------- ----------------------------------------If you add new types, refer to triggers "Passively Used" and "Actively Used" for modifications. Look for this sign: $$$ --------
      • Set SI_StoneType[1] = Broken Rock
      • Set SI_StoneType[2] = Broken Fire Stone
      • Set SI_StoneType[3] = Broken Icy Stone
      • -------- ----------------------------------------These are the types of Greater Golems created out of merging Tiny Golems with each other (You just need one type for each level) --------
      • -------- ----------------------------------------The number of its indexes are equal to SI_MaxLevel --------
      • Set SI_GreaterGolemType[1] = Greater Golem - Level 01
      • Set SI_GreaterGolemType[2] = Greater Golem - Level 02
      • Set SI_GreaterGolemType[3] = Greater Golem - Level 03
      • -------- - --------
      • -------- - --------
      • -------- This is the max HP you specify for your Core Golem. If releasing a stone would make the max HP of the caster go below this amount, it won't be cast --------
      • Set SI_CoreGolemBaseHP = 250.00
      • -------- - --------
      • -------- The minimum Scale of the caster - When the caster's HP reaches near zero, this will be his/her scale --------
      • Set SI_MinimumScale = 80.00
      • -------- - --------
      • -------- This is the percent of the Tiny/Greater Golem HP that is restored for the Core Golem when the golem merges with the core --------
      • Set SI_HealthPercentReturned = 0.50
      • -------- - --------
      • -------- This is the amount that is reduced from Core Golem's max HP when a stone is dropped - The higher the value, the fewer rocks to drop --------
      • -------- WARNING-------------It's better not to set the HP of the Tiny Golems more than their threshold (Same goes for the Greater Golems except that they can have up to double the amount) --------
      • -------- ------------------------------And if you do, make sure that the percent restored for the Core Golem will not exceed the amount of threshold --------
      • -------- ------------------------------Because It opens the way for abusing the system --------
      • -------- WARNING-------------And never restore the Core Golem's HP equal or more than the threshold - Because again it opens the way for abusing the system --------
      • Set SI_StoneDropHpThreshold[1] = 200.00
      • Set SI_StoneDropHpThreshold[2] = 180.00
      • Set SI_StoneDropHpThreshold[3] = 160.00
      • -------- - --------
      • -------- Minimum and maximum distance for the dropped stones --------
      • Set SI_DroppedStoneDistanceMinimum = 200.00
      • Set SI_DroppedStoneDistanceMaximum = 400.00
      • -------- And this is the stun ability when the hit the ground for each level- Number of Indexes should be equal to the SI_MaxLevel --------
      • Set SI_DroppedStoneAbility[1] = Stun (Dropping Stone) (Level 01)
      • Set SI_DroppedStoneAbility[2] = Stun (Dropping Stone) (Level 02)
      • Set SI_DroppedStoneAbility[3] = Stun (Dropping Stone) (Level 03)
      • -------- - --------
      • -------- This is the time that takes until the stone hits the ground --------
      • Set SI_DroppedStoneImpactTime = 0.50
      • -------- - --------
      • -------- The time that takes until the grounded stone turn into a Tiny Golem, vibrating the whole time with increasing intensity --------
      • Set SI_GroundedStonesTime = 5.00
      • -------- - --------
      • -------- This is just for visuals to give the stone a sense of arcish projection. --------
      • -------- ---------------------------------------------------------------------------------------------------------Height1 = The first Height that the spawned stone is set to. --------
      • -------- ---------------------------------------------------------------------------------------------------------Height2 = The height that the stone rises before going twards the ground --------
      • -------- ---------------------------------------------------------------------------------------------------------Try to set them close to each other to prevent abrubt changes in direction because it's not an arc --------
      • Set SI_DroppedStoneHeight1 = 150.00
      • Set SI_DroppedStoneHeight2 = 200.00
      • -------- ---------------------------------------------------------------------------------------------------------Set the maximum number of special effects that you want to attach to your golems. --------
      • Set SI_GolemsSpecialEffectNumber = 4
      • -------- ---------------------------------------------------------------------------------------------------------Set the impact radius of the dropped stone for cutting trees (The real effect needs to be changed through the stone's stun ability = War stomp) --------
      • Set SI_DroppedStoneImpactArea = 200.00
      • -------- --------------------------------------------------------------------------And these are the minimum and maximum vibration intensities (Setting the max intensity to more than 9 would give harsh visuals) --------
      • Set SI_VibrationIntensityMinimum = 0.00
      • Set SI_VibrationIntensityMaximum = 7.00
      • -------- - --------
      • -------- OPTIONAL ABILITIES --------
      • -------- - --------
      • -------- These are optional abilities that you can specify for your Greater Golems. Each combination of Tiny Golems gives the created Greater Golem some of these abilities --------
      • -------- You can add whatever amount of abilities you like, but their levels for each ability should be equal to SI_MaxLevel --------
      • -------- If you add new ones, you need to modify them on your own in the "Merging Golems" trigger where you see this sign: )))((( --------
      • -------- If you increase the amount of abilities, follow the same pattern that I used here - That way you'll only need to change just one number to apply the changes, that's it! --------
      • -------- Here there is 8 classes: Now for the case of enumeration, the class you want is subtracted by 1 and then multiplied by the SI_MaxLevel and added by the level of the Tiny Golem --------
      • -------- That will give you the ability you want. You just need to set that class number and the rest of it is set automatically. --------
      • -------- Class1 --------
      • Set SI_GreaterGolemAbility[1] = Freezing Aura (Level 01)
      • Set SI_GreaterGolemAbility[2] = Freezing Aura (Level 02)
      • Set SI_GreaterGolemAbility[3] = Freezing Aura (Level 03)
      • -------- Class2 --------
      • Set SI_GreaterGolemAbility[4] = Frost Nova (Level 01)
      • Set SI_GreaterGolemAbility[5] = Frost Nova (Level 02)
      • Set SI_GreaterGolemAbility[6] = Frost Nova (Level 03)
      • -------- Class3 --------
      • Set SI_GreaterGolemAbility[7] = Hardened Skin (Level 01)
      • Set SI_GreaterGolemAbility[8] = Hardened Skin (Level 02)
      • Set SI_GreaterGolemAbility[9] = Hardened Skin (Level 03)
      • -------- Class4 --------
      • Set SI_GreaterGolemAbility[10] = Lava Splash (Level 01)
      • Set SI_GreaterGolemAbility[11] = Lava Splash (Level 02)
      • Set SI_GreaterGolemAbility[12] = Lava Splash (Level 03)
      • -------- Class5 --------
      • Set SI_GreaterGolemAbility[13] = Fire Wave (Level 01)
      • Set SI_GreaterGolemAbility[14] = Fire Wave (Level 02)
      • Set SI_GreaterGolemAbility[15] = Fire Wave (Level 03)
      • -------- Class6 --------
      • Set SI_GreaterGolemAbility[16] = Boulder Slam (Level 01)
      • Set SI_GreaterGolemAbility[17] = Boulder Slam (Level 02)
      • Set SI_GreaterGolemAbility[18] = Boulder Slam (Level 03)
      • -------- Class7 --------
      • Set SI_GreaterGolemAbility[19] = Armor Bonus (Level 01)
      • Set SI_GreaterGolemAbility[20] = Armor Bonus (Level 02)
      • Set SI_GreaterGolemAbility[21] = Armor Bonus (Level 03)
      • -------- Class8 --------
      • Set SI_GreaterGolemAbility[22] = Immolation (Level 01)
      • Set SI_GreaterGolemAbility[23] = Immolation (Level 02)
      • Set SI_GreaterGolemAbility[24] = Immolation (Level 03)
Images

Hero Scales

Cast Sequence

Golem Types (3)

Different Combinations (3!) = (3x2x1)

233310-albums8885-picture108362.png

1

2

3

233310-albums8885-picture108366.png
233310-albums8885-picture108367.png
233310-albums8885-picture108368.png
233310-albums8885-picture108363.png

Same Golems

Different Golems

233310-albums8885-picture108365.png
233310-albums8885-picture108364.png
---------------------------------------------------
[Extra Feature]-Optional
Detect Golems
This extra spell is used for finding all the golems belonging to each one Core Golem, in case one player has more than one Core Golem.
Detect Golems
Icon
Untitled2.png
Code
  • Detect Golems
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Detect Golems
    • Actions
      • Unit Group - Pick every unit in SI_GroundedStonesGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load (Key Minion) of (Key (Picked unit)) in SI_Hashtable) Equal to (Triggering unit)
            • Then - Actions
              • Selection - Add (Picked unit) to selection for (Owner of (Triggering unit))
            • Else - Actions
      • Unit Group - Pick every unit in SI_DroppedStoneGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load (Key Minion) of (Key (Picked unit)) in SI_Hashtable) Equal to (Triggering unit)
            • Then - Actions
              • Selection - Add (Picked unit) to selection for (Owner of (Triggering unit))
            • Else - Actions
      • Unit Group - Pick every unit in SI_TinyGolemGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load (Key Minion) of (Key (Picked unit)) in SI_Hashtable) Equal to (Triggering unit)
            • Then - Actions
              • Selection - Add (Picked unit) to selection for (Owner of (Triggering unit))
            • Else - Actions
      • Unit Group - Pick every unit in SI_GreaterGolemGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load (Key Minion) of (Key (Picked unit)) in SI_Hashtable) Equal to (Triggering unit)
            • Then - Actions
              • Selection - Add (Picked unit) to selection for (Owner of (Triggering unit))
            • Else - Actions
 

Attachments

  • Loner-Magixxar_Stone Integrity.w3x
    283.6 KB · Views: 97
Last edited:
Level 9
Joined
Oct 14, 2013
Messages
238
Didn't really understand the reasons for your withdrawal anyway, tbh.
I apologize for my occasionally rash behaviors. Sometimes some things can set me off really bad. Especially when the case is an unexpected problem caused by a simple matter which can ruin everything. a similar issue happened to me in Zephyr #12, And this time it felt somewhat deja vu to me and it triggered me even worse. So I'm sorry.
 
Level 4
Joined
Apr 28, 2016
Messages
33
That is awesome skill you've got, Loner-Magixxar! I want to post my final entries too, how to make a separate column for each spell level like others did?
 
Level 4
Joined
Sep 13, 2014
Messages
106
Does the spell have to be designed for an RTS? How do you know if your spell is "overpowered"? And what if it is an ultimate? Does it still need 3 or more levels?
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
One of the conest rules state "If a submission does not follow the Spell Submission Rules the creator may/will be disqualified." So that means:

Does the spell have to be designed for an RTS?
I think the Spell Submission rules will answer this question:
Spells must mimic in-game mechanics; for example, damaging spells must give bounty when they kill enemies.

How do you know if your spell is "overpowered"?
Common sense. Not meant to be offensive by the way.

And what if it is an ultimate? Does it still need 3 or more levels?
Spell Submission rules answer this question:
Users have to be able to configure your spell to their liking. Don't make spells that are hard-coded and only work in one configuration.
 
Level 33
Joined
Apr 24, 2012
Messages
5,113
Does the spell have to be designed for an RTS?
Zephyr doesn't focus on what genre the spell is meant to be made. What Zephyr focuses on is how it fits all the genre (because that's how Spell Section works)
How do you know if your spell is "overpowered"?
As what KILLCIDE said : Common Sense. If your spell stuns units for 10+ seconds, that is deemed overpowered. Something whose values are unbelievable
And what if it is an ultimate? Does it still need 3 or more levels?
Yes. Spell Section, Zephyr or let's say the Spell Rules requires you to provide multiple levels on your spell to demonstrate the configurability.


Its gonna ruin my score?

Both of you and Chaosy made a spell that doesn't have an specific unit. IDK if that's going to affect your score.
 
Level 4
Joined
Apr 28, 2016
Messages
33
Final Entries

Summon Ectoplasm
Main Spell

Normal

with Aghanim's Scepter

Icon
attachment.php
Tooltip
attachment.php
Icon
attachment.php
Tooltip
attachment.php
Secondary Spell
Ectoplasm Mode

Taking Form

Formless

Spell Immunity


Icon
attachment.php
Tooltip
attachment.php
Icon
attachment.php
Tooltip
attachment.php
This spell grants ectoplasm formless which makes the unit has formless buff.
Icon
attachment.php
Tooltip
attachment.php

Newform Mode

Ecto-Blast

Ecto-Virus

Icon
attachment.php
Tooltip
When dies, deals 100/200/300 damage to enemy units on radius 400/1000* AOE.
Icon
attachment.php
Tooltip
When dies, deals 60 DPS to enemy units on radius 400/1000* AOE for 5/7* seconds.

*= with Aghanim's Scepter
Triggers

Summoning Ectoplasm

Summoning Effect

Taking Form

Damage Blast'n'Virus

Aghanim Acquires

  • Summoning
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
    • Actions
      • -------- ----------------------------------------------------------------- --------
      • -------- ------------- NORMAL MODE ------------- --------
      • -------- ----------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Ability being cast) Equal to Summon Ectoplasm ) and ((Level of Summon Ectoplasm for (Casting unit)) Greater than 0)
        • Then - Actions
          • Set SummonCaster = (Casting unit)
          • Set SummonTargetPoint = (Target point of ability being cast)
          • Set LevelAbility[1] = (Level of Summon Ectoplasm for SummonCaster)
          • Unit - Set life of SummonCaster to ((Life of SummonCaster) x (0.80 - (0.10 x (Real(LevelAbility[1])))))
          • Unit - Create 1 dummy 3 (satan ring) for (Owner of SummonCaster) at SummonTargetPoint facing Default building facing degrees
          • Set dummyeffect[1] = (Last created unit)
          • Unit - Create 1 dummy 2 (soul effect) for (Owner of SummonCaster) at SummonTargetPoint facing (Position of dummyeffect[1])
          • Set dummyeffect[2] = (Last created unit)
          • Custom script: call RemoveLocation(udg_SummonTargetPoint)
          • Unit - Add Summon Ecto (dummy) to dummyeffect[2]
          • Unit - Set level of Summon Ecto (dummy) for dummyeffect[2] to LevelAbility[1]
          • Unit - Order dummyeffect[2] to Human Archmage - Summon Water Elemental
          • Unit - Add a 1.00 second Generic expiration timer to dummyeffect[1]
          • Unit - Add a 2.00 second Generic expiration timer to dummyeffect[2]
        • Else - Actions
      • -------- ----------------------------------------------------------------- --------
      • -------- ------------- AGHANIM MODE ------------- --------
      • -------- ----------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Ability being cast) Equal to Summon Ectoplasm (aghanim)) and ((Level of Summon Ectoplasm (aghanim) for (Casting unit)) Greater than 0)
        • Then - Actions
          • Set SummonCaster = (Casting unit)
          • Set SummonTargetPoint = (Target point of ability being cast)
          • Set LevelAbility[5] = (Level of Summon Ectoplasm (aghanim) for SummonCaster)
          • Unit - Set life of SummonCaster to ((Life of SummonCaster) x (0.90 - (0.10 x (Real(LevelAbility[5])))))
          • Unit - Create 1 dummy 3 (satan ring) for (Owner of SummonCaster) at SummonTargetPoint facing Default building facing degrees
          • Set dummyeffect[3] = (Last created unit)
          • Unit - Create 1 dummy 2 (soul effect) for (Owner of SummonCaster) at SummonTargetPoint facing (Position of dummyeffect[3])
          • Set dummyeffect[4] = (Last created unit)
          • Custom script: call RemoveLocation(udg_SummonTargetPoint)
          • Unit - Add Summon Ecto (dummy)(AS) to dummyeffect[4]
          • Unit - Set level of Summon Ecto (dummy)(AS) for dummyeffect[4] to LevelAbility[5]
          • Unit - Order dummyeffect[4] to Human Archmage - Summon Water Elemental
          • Unit - Add a 1.00 second Generic expiration timer to dummyeffect[3]
          • Unit - Add a 2.00 second Generic expiration timer to dummyeffect[4]
        • Else - Actions
  • Sum Eff
    • Events
      • Unit - A unit Spawns a summoned unit
    • Conditions
    • Actions
      • -------- ----------------------------------------------------------------- --------
      • -------- ------------- NORMAL MODE ------------- --------
      • -------- ----------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Summoned unit)) Equal to Ectoplasm
        • Then - Actions
          • Set SummonTarget = (Summoned unit)
          • Set LevelAbility[2] = (Level of Summon Ecto (dummy) for (Summoning unit))
          • Unit - Add Taking Form to SummonTarget
          • Unit - Set level of Taking Form for SummonTarget to LevelAbility[2]
        • Else - Actions
      • -------- ----------------------------------------------------------------- --------
      • -------- ------------- AGHANIM MODE ------------- --------
      • -------- ----------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Summoned unit)) Equal to Ectoplasm (AS)
        • Then - Actions
          • Set SummonTarget = (Summoned unit)
          • Set LevelAbility[6] = (Level of Summon Ecto (dummy)(AS) for (Summoning unit))
          • Unit - Add Taking Form (aghanim) to SummonTarget
          • Unit - Set level of Taking Form (aghanim) for SummonTarget to LevelAbility[6]
        • Else - Actions
  • Taking Form
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • ((Casting unit) has buff Formless ) Equal to True
    • Actions
      • -------- ----------------------------------------------------------------- --------
      • -------- ------------- NORMAL MODE ------------- --------
      • -------- ----------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Taking Form
        • Then - Actions
          • Set TakingCaster = (Triggering unit)
          • Set TakingTarget = (Target unit of ability being cast)
          • Set LevelAbility[3] = (Level of Taking Form for TakingCaster)
          • Unit - Replace TakingCaster with a (Unit-type of TakingTarget) using The new unit's default life and mana
          • Set TakingNewForm = (Last replaced unit)
          • -------- ----------------------------------------------------------------- --------
          • -------- Taking a new form for ectoplasm --------
          • -------- ----------------------------------------------------------------- --------
          • Unit - Add Ecto-Blast to TakingNewForm
          • Unit - Add Ecto-Virus to TakingNewForm
          • Unit - Set level of Ecto-Blast for TakingNewForm to LevelAbility[3]
          • Selection - Add TakingNewForm to selection for (Owner of TakingCaster)
        • Else - Actions
      • -------- ----------------------------------------------------------------- --------
      • -------- ------------- AGHANIM MODE ------------- --------
      • -------- ----------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Taking Form (aghanim)
        • Then - Actions
          • Set TakingCaster = (Triggering unit)
          • Set TakingTarget = (Target unit of ability being cast)
          • Set LevelAbility[7] = (Level of Taking Form (aghanim) for TakingCaster)
          • Unit - Replace TakingCaster with a (Unit-type of TakingTarget) using The new unit's default life and mana
          • Set TakingNewForm = (Last replaced unit)
          • -------- ----------------------------------------------------------------- --------
          • -------- Taking a new form for ectoplasm --------
          • -------- ----------------------------------------------------------------- --------
          • Unit - Add Ecto-Blast (aghanim) to TakingNewForm
          • Unit - Add Ecto-Virus (aghanim) to TakingNewForm
          • Unit - Set level of Ecto-Blast (aghanim) for TakingNewForm to LevelAbility[7]
          • Selection - Add TakingNewForm to selection for (Owner of TakingCaster)
        • Else - Actions
      • -------- ----------------------------------------------------------------- --------
      • -------- Color for ectoplasm new form --------
      • -------- ----------------------------------------------------------------- --------
      • If ((Owner of TakingTarget) Equal to Player 1 (Red)) then do (Unit - Change color of TakingNewForm to Red) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 2 (Blue)) then do (Unit - Change color of TakingNewForm to Blue) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 3 (Teal)) then do (Unit - Change color of TakingNewForm to Teal) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 4 (Purple)) then do (Unit - Change color of TakingNewForm to Purple) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 5 (Yellow)) then do (Unit - Change color of TakingNewForm to Yellow) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 6 (Orange)) then do (Unit - Change color of TakingNewForm to Orange) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 7 (Green)) then do (Unit - Change color of TakingNewForm to Green) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 8 (Pink)) then do (Unit - Change color of TakingNewForm to Pink) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 9 (Gray)) then do (Unit - Change color of TakingNewForm to Gray) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 10 (Light Blue)) then do (Unit - Change color of TakingNewForm to Light Blue) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 11 (Dark Green)) then do (Unit - Change color of TakingNewForm to Dark Green) else do (Do nothing)
      • If ((Owner of TakingTarget) Equal to Player 12 (Brown)) then do (Unit - Change color of TakingNewForm to Brown) else do (Do nothing)
      • If (((Owner of TakingTarget) Equal to Neutral Hostile) or (((Owner of TakingTarget) Equal to Neutral Victim) or (((Owner of TakingTarget) Equal to Neutral Extra) or ((Owner of TakingTarget) Equal to Neutral Passive)))) then do (Unit - Change color of TakingNewForm to Black) else do (Do nothing)
      • -------- ----------------------------------------------------------------- --------
      • -------- Finishing effect --------
      • -------- ----------------------------------------------------------------- --------
      • Special Effect - Create a special effect attached to the origin of TakingNewForm using Abilities\Spells\Items\TomeOfRetraining\TomeOfRetrainingCaster.mdl
      • Set SEffect[1] = (Last created special effect)
      • Special Effect - Destroy SEffect[1]
      • Unit - Add a 40.00 second Generic expiration timer to TakingNewForm
  • Damage
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • -------- ----------------------------------------------------------------- --------
      • -------- ------------- NORMAL MODE ------------- --------
      • -------- ----------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Ecto-Blast for (Triggering unit)) Greater than 0
        • Then - Actions
          • -------- ----------------------------------------------------------------- --------
          • -------- Damage for ecto blast on each level --------
          • -------- ----------------------------------------------------------------- --------
          • Set EctoDyingCasterUnit = (Dying unit)
          • Set EctoDyingCasterPoint = (Position of EctoDyingCasterUnit)
          • Set LevelAbility[4] = (Level of Ecto-Blast for EctoDyingCasterUnit)
          • Set EctoDyingTargetGroup[1] = (Units within 400.00 of EctoDyingCasterPoint matching ((((Matching unit) belongs to an ally of (Owner of EctoDyingCasterUnit)) Not equal to True) and ((((Matching unit) belongs to an enemy of (Owner of EctoDyingCasterUnit)) Equal to True) and ((((Matching uni
          • Unit Group - Pick every unit in EctoDyingTargetGroup[1] and do (Unit - Cause EctoDyingCasterUnit to damage (Picked unit), dealing (100.00 x (Real(LevelAbility[2]))) damage of attack type Spells and damage type Normal)
          • Special Effect - Create a special effect at EctoDyingCasterPoint using LightningNova.mdx
          • Set SEffect[2] = (Last created special effect)
          • Special Effect - Destroy SEffect[2]
          • Special Effect - Create a special effect at EctoDyingCasterPoint using ArcaneExplosion.mdx
          • Set SEffect[3] = (Last created special effect)
          • Special Effect - Destroy SEffect[3]
          • Custom script: call DestroyGroup(udg_EctoDyingTargetGroup[1])
          • Custom script: call RemoveLocation(udg_EctoDyingCasterPoint)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Ecto-Virus for (Triggering unit)) Greater than 0
        • Then - Actions
          • -------- ----------------------------------------------------------------- --------
          • -------- Damage on ecto virus for 5 seconds --------
          • -------- ----------------------------------------------------------------- --------
          • Set EctoDyingCasterPoint = (Position of (Dying unit))
          • Set EctoDyingTargetGroup[2] = (Units within 400.00 of EctoDyingCasterPoint matching ((((Matching unit) belongs to an enemy of (Owner of EctoDyingCasterUnit)) Equal to True) and (((Matching unit) is alive) Equal to True)))
          • Unit Group - Pick every unit in EctoDyingTargetGroup[2] and do (Actions)
            • Loop - Actions
              • Unit - Create 1 dummy (.mdl) for (Owner of EctoDyingCasterUnit) at EctoDyingCasterPoint facing Default building facing degrees
              • Set dummycaster = (Last created unit)
              • Unit - Add a 1.00 second Generic expiration timer to dummycaster
              • Unit - Add Infection (dummy) to dummycaster
              • Unit - Order dummycaster to Night Elf Warden - Shadow Strike (Picked unit)
          • Custom script: call DestroyGroup(udg_EctoDyingTargetGroup[2])
          • Custom script: call RemoveLocation(udg_EctoDyingCasterPoint)
        • Else - Actions
      • -------- ----------------------------------------------------------------- --------
      • -------- ------------- AGHANIM MODE ------------- --------
      • -------- ----------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Ecto-Blast (aghanim) for (Triggering unit)) Greater than 0
        • Then - Actions
          • -------- ----------------------------------------------------------------- --------
          • -------- Damage for ecto blast on each level --------
          • -------- ----------------------------------------------------------------- --------
          • Set EctoDyingCasterUnit = (Dying unit)
          • Set EctoDyingCasterPoint = (Position of EctoDyingCasterUnit)
          • Set LevelAbility[8] = (Level of Ecto-Blast (aghanim) for EctoDyingCasterUnit)
          • Set EctoDyingTargetGroup[3] = (Units within 1000.00 of EctoDyingCasterPoint matching ((((Matching unit) belongs to an ally of (Owner of EctoDyingCasterUnit)) Not equal to True) and ((((Matching unit) belongs to an enemy of (Owner of EctoDyingCasterUnit)) Equal to True) and ((((Matching un
          • Unit Group - Pick every unit in EctoDyingTargetGroup[3] and do (Unit - Cause EctoDyingCasterUnit to damage (Picked unit), dealing (100.00 x (Real(LevelAbility[8]))) damage of attack type Spells and damage type Normal)
          • Special Effect - Create a special effect at EctoDyingCasterPoint using LightningNova.mdx
          • Set SEffect[4] = (Last created special effect)
          • Special Effect - Destroy SEffect[4]
          • Unit - Create 1 dummy 4 (aghanim effect) for (Owner of EctoDyingCasterUnit) at EctoDyingCasterPoint facing Default building facing degrees
          • Set dummyeffect[5] = (Last created unit)
          • Unit - Add a 0.50 second Generic expiration timer to dummyeffect[5]
          • Custom script: call DestroyGroup(udg_EctoDyingTargetGroup[3])
          • Custom script: call RemoveLocation(udg_EctoDyingCasterPoint)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Ecto-Virus (aghanim) for (Triggering unit)) Greater than 0
        • Then - Actions
          • -------- ----------------------------------------------------------------- --------
          • -------- Damage on ecto virus for 5 seconds --------
          • -------- ----------------------------------------------------------------- --------
          • Set EctoDyingCasterPoint = (Position of (Dying unit))
          • Set EctoDyingTargetGroup[4] = (Units within 1000.00 of EctoDyingCasterPoint matching ((((Matching unit) belongs to an enemy of (Owner of EctoDyingCasterUnit)) Equal to True) and (((Matching unit) is alive) Equal to True)))
          • Unit Group - Pick every unit in EctoDyingTargetGroup[4] and do (Actions)
            • Loop - Actions
              • Unit - Create 1 dummy (.mdl) for (Owner of EctoDyingCasterUnit) at EctoDyingCasterPoint facing Default building facing degrees
              • Set dummycaster = (Last created unit)
              • Unit - Add a 1.00 second Generic expiration timer to dummycaster
              • Unit - Add Infection (dummy)(AS) to dummycaster
              • Unit - Order dummycaster to Night Elf Warden - Shadow Strike (Picked unit)
          • Custom script: call DestroyGroup(udg_EctoDyingTargetGroup[4])
          • Custom script: call RemoveLocation(udg_EctoDyingCasterPoint)
        • Else - Actions
  • Acquires
    • Events
      • Unit - A unit Acquires an item
    • Conditions
    • Actions
      • Set AghanimAcquire = (Triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of AghanimAcquire) Equal to Black Magician
          • (Item-type of (Item being manipulated)) Equal to Aghanim's Scepter
        • Then - Actions
          • Item - Remove (Item being manipulated)
          • Hero - Create Aghanim's Scepter (Magician) and give it to AghanimAcquire
        • Else - Actions
Images (gif and jpg)

Summoning Ectoplasm

Taking Form

Color Changing

Damage Blast'n'Virus

Hero Appearance

attachment.php
attachment.php
attachment.php

Normal Mode

Aghanim Mode

attachment.php
attachment.php

Normal Mode

Aghanim Mode

attachment.php
attachment.php
Extra Files

Imported Files

Variables

attachment.php


Credits to:
GrandAura = JetFangInferno, Rightfield
PoisonStingTarget = JetFangInferno
Blue Pemtagram Aura2 = Skizzik
Arcane Explosion = JesusHipster
Lightning Nova = dhguardianes
Stomp = nGy
attachment.php
=============================================
If there any files are incomplete or incorrect, please tell me because i'm new here > <
 

Attachments

  • Ecto_plus_aghanim.png
    Ecto_plus_aghanim.png
    38.6 KB · Views: 262
  • BTNSummonEctoplasm.jpg
    BTNSummonEctoplasm.jpg
    2.5 KB · Views: 247
  • Summon_Ectoplasm_Tooltip_Normal.jpg
    Summon_Ectoplasm_Tooltip_Normal.jpg
    193.3 KB · Views: 308
  • Summon_Ectoplasm_Tooltip_Aghanim.jpg
    Summon_Ectoplasm_Tooltip_Aghanim.jpg
    171.7 KB · Views: 296
  • 1.gif
    1.gif
    760.7 KB · Views: 312
  • 2a.gif
    2a.gif
    643.4 KB · Views: 321
  • 2b.gif
    2b.gif
    1.3 MB · Views: 292
  • BTNTakingForm.jpg
    BTNTakingForm.jpg
    4.5 KB · Views: 243
  • Taking_Form.jpg
    Taking_Form.jpg
    47.9 KB · Views: 285
  • 3a.gif
    3a.gif
    2.7 MB · Views: 322
  • Hero_Appearance_Normal.jpg
    Hero_Appearance_Normal.jpg
    318.3 KB · Views: 265
  • Hero_Appearance_Aghanim.jpg
    Hero_Appearance_Aghanim.jpg
    243.1 KB · Views: 275
  • 3b.gif
    3b.gif
    3.2 MB · Views: 346
  • Formless.jpg
    Formless.jpg
    44.6 KB · Views: 261
  • Spell_Immunity.jpg
    Spell_Immunity.jpg
    32.7 KB · Views: 235
  • PASBTNGenericSpellImmunity.jpg
    PASBTNGenericSpellImmunity.jpg
    2.3 KB · Views: 347
  • PASBTNMagicalSentry.jpg
    PASBTNMagicalSentry.jpg
    3.3 KB · Views: 347
  • PASBTNEcto-Blast.jpg
    PASBTNEcto-Blast.jpg
    1.7 KB · Views: 328
  • PASBTNEcto-Virus.jpg
    PASBTNEcto-Virus.jpg
    1.5 KB · Views: 332
  • Import_Icons_and_Models.jpg
    Import_Icons_and_Models.jpg
    141.3 KB · Views: 290
  • Variables_01.jpg
    Variables_01.jpg
    43.2 KB · Views: 280
  • crabas_sakti+Summon Ectoplasm.w3x
    341.9 KB · Views: 100
Last edited:
Level 4
Joined
Sep 13, 2014
Messages
106
My point was that a spell that is overpowered in one map might not be overpowered in another map, due to the differences in game mechanics. For example, my spell might not be very good in an RTS situation, but it might be a lot stronger in a tug-of-war style map.

But I guess it should be designed to be used just as an extra spell in the ordinary game then.

Although I'm not sure that any of these spells are anywhere near anything that would actually have been implemented in the ordinary game.

Also, could you quote where it says that 3 levels are required? But ok.
 
Last edited:
Level 33
Joined
Apr 24, 2012
Messages
5,113
Well, if you ask me, defining the spell overpowered is not just by values.
Judges will not define it as overpowered, all of the spells are not overpowered. UNLESS the values there are hardcoded, meaning it was intended not to be touched.

Balancing here is not the issue, it is still the code. I regret telling that the term "overpowered" can reduce the points.

Balancing is the job for Hero Contest :V
 
ZerGreenOne, don't focus too much that your spell must exactly match in a classic RTS game genre - for strategic game situations, etc.
The contest is more for creativly creating something awesome. The entry must be warcraft related... but if you keep to our set theme, you won't do much wrong.

And yeh, as was mentioned... what may lead to overpowered spells, is e.g. hardcoding.
Allow the user to modify as many aspects as you can, so he can perfectly adapt the product in a map.
Providing level-insanceability is one aspect for making a more adaptable spell, because the user has the chance to choose between one level, or multiple ones.
Though it's always up to you, what exactly will be implemented, and what not.
----
Of course something like "Pick All Enemies - Kill PickedUnit" is something boring and total overpowered, as well.

If important questions were ignored, please ask again.
If you can't find your entry or so in Tank - Commander's table, then please VM/PM him with a link, so he easily can fix it.
__________________

\Iceman out
 
Level 10
Joined
Oct 5, 2008
Messages
355
Well, haven't visited the Hiveworkshop for a long time only to see that a Zephir contest is up and only 9 days left... Hopefully i gonna finish something within the next few days or so (btw. how does it go with WIP when i begin to code my spell within a small duration?)

Anyway, this will be my concept. The Idea should be orginally an ultimate of one of my heros for my custom map, but since the concept is around the other 20 hero concepts which are waiting to be added to the map, it perfectly fits as "warmup" for this contest:

Spell: Nether rift

Description:
(Channeling)
Conjures a portal to the nether world, binding a powerfull demon onto the battlefield. The initial duration of the nether lord is equal to 5 seconds while also increasing by 1 second for each second the nether lord stays inside the range of the portal instead of going down. This duration is also freezed for as long the nether lord stays inside the range of the portal.

Stage 1:
Channeling time: 15 seconds
Range: 300
Stage 2:
Channeling time: 30 seconds
Range: 500
Stage 3:
Channeling time: 45 seconds
Range: 700

Edit: While i was looking at the other spells that were submitted, i probably gonna try to spice it up, although i like simple but deep designs...
 
Level 4
Joined
Apr 28, 2016
Messages
33
Yesterday i downloaded the 1.27 warcraft 3 patch, but it gave me an error. If i just change version of w3l.exe (i have 1.26), world editor cannot save custom map.

Where can i download the real patch that can works on me? I will send the screenshot later, maybe anyone here know where things i got wrong :/
 
Level 4
Joined
Apr 28, 2016
Messages
33
Better post that in the help zone instead of here.

I already fix it, now my Warcraft 3 on version 1.27. Beside that, thanks for the help. Do i need re-upload the map that i re-save in v1.27 WE on my final entries or not? If yes, is it allow to me to edit my post (only for re-upload map) after my entries has done?
 
Level 4
Joined
Sep 13, 2014
Messages
106
One spell can be OP because you can't alter numbers.

If you have a spell which swaps hp with the enemy, you can go to a large mob with 100% hp while you got 1% and use the skill to one-shot it while healing yourself to full.
You can't nerf this by changing numbers, you need to change the code itself in one way or another.

LOL http://dota2.gamepedia.com/Terrorblade So OP. But there is a restriction that some HP must remain. Is 25% not a number?
 

Kyrbi0

Arena Moderator
Level 44
Joined
Jul 29, 2008
Messages
9,487
Welp, now that things have settled down, and since I failed to finish my Techtree Contest entry, I think I'll reuse a cool idea I had for this. One week should leave me oodles of time leftover for testing (hahahahahahahahahaha....); alright, well, enough to finish. My spells are never very complex; I'm a big believer in "would you see this in a standard Wc3 game/race/hero/unit/etc".

So I went to the trouble to read through the whole topic... *sigh*... And my question was only partially answered. Basically, what's the "uniqueness" we're going for here; "uniquely summoned" or "unique summons"? The former is accomplished as long as it's not a "click-boom" ability (e.g. sacrifice target to summon, do some complicated gesture to summon, achieve some objective, etc), and the latter by merely mixing & matching abilities & such on the summon.

The reason the confusion exists lies, I believe, in using "Pocket Factory" as the 'archetypal' example in the very first post: Pocket Factory is only mildly interesting in *how* it's summoned (#1) (i.e. point-target, summons @ point, woohoo), but it's a pretty creative summon *itself* (#2) (i.e. stationary building instead of mobile unit, constantly pumps out controllable suicidal mech-goblins who Kaboom stuff)

Whereas something like the Blood Mage's Phoenix is essentially a boring-old summon in it's summoning (#1: click-boom), but it's a pretty unique/creative summon in it's own self (#2: lots of AoE DoT, flying, Neg HP Regen so it's constantly dying but then turns into an egg & back into a Phoenix if not killed, indefinitely self-resurrecting).

I'm not sure I can think of an ability that is good at both things, honestly. (Ok, maaaaaybe Pocket Factory. Doom? Black Arrow?). But "creative" and "original" are always tricky buzzwords, and I fear in a circumstance like this they will be quite... narrow.

Just some thoughts.

Summoning units doesn't need to be controllable or killable.

Locust Swarm already proved that ;)
Yeah, I'm with IcemanBo; Locust Swarm is no summon. It's got little dudes that come out, but they are specially designed with a unique ability custom-made by Blizzard to make them, essentially, dummy units (i.e. the incredibly-useful 'Locust' ability). If you replaced the Locusts with random SFX, it's basically still the same spell; "drain life from nearby enemies & use it to heal the caster".
 
Level 33
Joined
Apr 24, 2012
Messages
5,113
Yeah, I'm with IcemanBo; Locust Swarm is no summon. It's got little dudes that come out, but they are specially designed with a unique ability custom-made by Blizzard to make them, essentially, dummy units (i.e. the incredibly-useful 'Locust' ability). If you replaced the Locusts with random SFX, it's basically still the same spell; "drain life from nearby enemies & use it to heal the caster".

We have already settled to that :)
 

Kyrbi0

Arena Moderator
Level 44
Joined
Jul 29, 2008
Messages
9,487
Lava spawns has a unique behavior too.
That's a really interesting discussion, because if you take a look at it, it actually has 0% to do with the summon (Lava Spawn) and 100% to do with the ability ("Summon Lava Spawn"); all the pertinent data fields for that interaction (the "spawn more after so many attacks" one) are in the actually summoning ability itself, not anywhere on the Lava Spawn.

I should know; I've been studying SLS for some nefarious plans of mine. >:p
 
Level 14
Joined
Jul 1, 2008
Messages
1,314
Good luck to everyone!

I dont have the courage yet to enter a terraining contest but this one here animates my creativty, so I guess I will enter as well.

If I am able to finish it, my summoning spell will be based on chicken.

EDIT: Sry did not see that question by looking through: Are custom imports allowed?
 
Last edited:
Level 22
Joined
Feb 6, 2014
Messages
2,466
Entry: Flux - Aerial Aid

[TD]Entry Post: Flux - Aerial Aid[/TD]
Tooltip

Icon
icons_16231_btn.jpg
Aerial Aid [Q]
Calls for an air support containing goblin paratrooper soldiers. The Plane is equipped with guns which fires at enemy units in its field of sight targeting heroes and units with lower hitpoints. Upon activation, 'Aerial Aid' is replaced by the sub-skill 'Deploy Paratroopers' which commands your backup soldiers to parachute from the Plane.

Level 1
Plane: HP: 300 / Damage: 5 / Armor: +2 / Guns: 2
Paratrooper: HP: 150 / Damage: 3 / Armor: +1 / Qty: 4
Level 2
Plane: HP: 400 / Damage: 6 / Armor: +3 / Guns: 3
Paratrooper: HP: 200 / Damage: 4 / Armor: +2 / Qty: 5
Level 3
Plane: HP: 500 / Damage: 7 / Armor: +4 / Guns: 4
Paratrooper: HP: 250 / Damage: 5 / Armor: +3 / Qty: 6

Cooldown: 50/45/40

Code

JASS:
scope AerialAid/*

    *************************** Aerial Aid v1.01 *****************************
                                    by Flux
    
  SPELL DESCRIPTION:
    Calls for an air support containing goblin paratrooper soldiers. The Plane
    is equipped with 2/3/4 guns which fires at enemy units in its field of sight
    targeting heroes and units with lower hitpoints. Upon activation, 'Aerial Aid' 
    is replaced by the sub-skill 'Deploy Paratroopers' which commands your backup
    soldiers to parachute from the Plane.
  
  REQUIRES:
      (nothing)  
  
  OPTIONALLY REQUIRES:
      - BonusMod and SetUnitMaxState
          If not found, it will generate it's own object editor data to manipulate the
          stats per level. 
          Recommended if your other spells uses BonusMod or SetUnitMaxState as optional
          requirement, avoiding redundant functions and object editor abilities.
      - DummyRecycler/MissileRecycler
          If not found, it will create new units for all the dummy units needed
          everytime the spell is cast. Dummy units are used as Parachute, Visual Effects 
          and Bullet Projectile. 
          Strongly recommended because this spell creates a lot of units.
      - SpellEffectEvent
          If not found, it will create another trigger with 'A unit Starts the effect of an 
          ability' event. 
          Strongly recommended for maps with huge number of spells.
      - Table
          If not found, this spell will require 1 hashtable. Hashtable is limited to 256
          per map. 
          Recommended if you used a lot of hashtable in your map to avoid reaching the 
          hashtable limit.
      - WorldBounds
          If not found, this spell will create 4 more variables for the map boundary parameters.
          Recommended if your other spells uses WorldBounds as optional requirement, avoiding 
          redundant variables.
      
      
  ---------------------------------- CREDITS: --------------------------------------------
      OPTIONAL SYSTEMS:
      Bribe                       - MissileRecycler, SpellEffectEvent, Table
      Earth-Fury                  - BonusMod, SetUnitMaxState
      Flux                        - DummyRecycler
      Magtheridon96               - RegisterPlayerUnitEvent
      Nestharus                   - WorldBounds
      
      MODELS:
      Anitarf, iNfraNe, Vexorian  - Attachable Dummy Model with Pitch Animation
      WILL THE ALMIGHTY           - Goblin Scout, Goblin Soldier
      NatDis                      - Dwarven Air Force DF 35 Fighter
      Fingolfin                   - Parachute
      Grey Knight                 - Bullet
      Tranquil                    - Snipe Target Effect (edited)
      
      
      ICONS:
      Sin'dorei300                - BTNGoblinRifleman, BTNGoblinFireworker
      Marcos DAB                  - BTNGoblinHeroAviator
      
      SKINS:
      Erkki2                      - Blue Laser
  -----------------------------------------------------------------------------------------*/


    native UnitAlive takes unit u returns boolean
    
    //====================================================================================
    //============================== CONFIGURATION =======================================
    //====================================================================================
    
    globals
        //Rawcodes
        private constant integer SPELL_ID = 'Aaid'
        private constant integer SPELL_ID_DEPLOY = 'Adpy'
        private constant integer TOGGLE_ID = 'AAtg'
        
        //Dummy Unit Properties
        private constant integer DUMMY_ID = 'dumi'
        private constant player DUMMY_OWNER = Player(14)
        
        //Summoned Units
        private constant integer PARATROOPER_AIR_ID = 'pair'
        private constant integer PLANE_ID = 'plne'
        private constant integer TRANSFORM_ID = 'AaTF'
        
        //Periodic Timing of the Spell (Plane and Paratrooper timing)
        private constant real TIMEOUT = 0.03125
        
        //Visual Effects
        private constant string PARACHUTE_MODEL = "war3mapImported\\Parachute.mdl"
        private constant string TARGET_MODEL = "war3mapImported\\Target.mdl"
        private constant string TARGET_ATTACHMENT = "overhead"
        private constant string LASER_CODE = "LASR"     //Laser string code as configured in LightningData.slk
        private constant real LASER_DISTANCE = 50       //Max Distance of straight laser lightning in the curve
        private constant string BULLET_MODEL = "war3mapImported\\Bullet.mdl"

        
        //Attack and Damage types of Plane Gun
        private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
        private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
        private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
        
        //Preload abilities at Map Loading Screen to avoid lag spike the first time it is cast?
        private constant boolean PRELOAD = true
        
        
        //************************************************************************************
        //**************************** PLANE CONFIGURATION ***********************************
        //************************************************************************************
        private constant real PLANE_HEIGHT_INITIAL = 1200
        
        private constant real PLANE_HEIGHT = 600
        
        private constant real PLANE_FALL_SPEED = 700   
        
        //************************************************************************************
        //***************************** GUN CONFIGURATION ************************************
        //************************************************************************************
        //When the absolute z difference between the plane and target is PLANE_HEIGHT, the
        //plane can't hit units under this range.
        //When the absolute z difference between the plane and target is 0, the
        //plane can hit units directly in front of it even at close range.
        private constant real MIN_HIT_DISTANCE = 500
        
        //Conic Radius for the Plane Gun (degrees)
        private constant real PLANE_SIGHT_ANGLE = 40
        
        //Plane Gun will prioritize targeting hero
        private constant boolean PRIORITIZE_HERO = true
        
        //Speed of Gun bullets (displacement per second)
        private constant real BULLET_SPEED = 3200
        //Is the BULLET_SPEED considered a 3D speed? If false, it will be considered as a 2D speed
        //meaning the horizontal (ground) speed is constant.
        private constant boolean BULLET_SPEED_3D = true
        
        //An optional different TIMEOUT for the Bullet projectiles just in case
        private constant real BULLET_TIMEOUT = TIMEOUT
        
        //Collision Size of Bullet
        private constant real BULLET_COLLISION = 110
        
        //Gun Field of Sight visible to enemy? Recommended to be set to false
        private constant boolean VISIBLE_LASER = false
        
        //************************************************************************************
        //************************ PARATROOPER CONFIGURATION *********************************
        //************************************************************************************
        
        //When the Paratrooper's height is below GND_HEIGHT, it is now targeted
        //as a ground unit
        private constant real GND_HEIGHT = 100
        
        //Does the Paratroopers have a Timed Life?
        private constant boolean APPLY_TIMED_LIFE = false
        
        //Is the Paratrooper vulnerable while on air?
        private constant boolean CAN_BE_HIT = true
        
        //When the current height of the Paratrooper is less than PARACHUTE_ACTIVATE, it will
        //activate its parachute
        private constant real PARACHUTE_ACTIVATE = 400
        
        //How fast Paratroopers accelerates when their parachute is not yet used (speed per second)
        private constant real PARATROOPER_GRAVITY = 150
        
        //How fast Paratroopers will fall upon using their parachute (displacement per second)
        private constant real PARACHUTE_FALL_SPEED = 180
        
        //When the Paratrooper hits the ground at this z-speed (displacement per second), it will die!
        private constant real SPEED_WITH_DAMAGE = 400
        
        //The lower the values, the greater the friction (for calculation simplicity)
        private constant real DRAG_COEFFICIENT = 0.3
        
    endglobals
    
    //************************************************************************************
    //*************************** PLANE CONFIGURATION ************************************
    //************************************************************************************
    //Plane Hitpoints per level
    private function PlaneLife takes integer lvl returns real
        return 200.0 + 100.0*lvl    //300, 400, 500
    endfunction
    
    //Plane Bonus armor per level.
    private function PlaneArmor takes integer lvl returns integer
        return 1 + 1*lvl       //2, 3, 4
    endfunction
    
    //How fast the Plane moves (displacement per second)
    private function PlaneSpeed takes integer lvl returns real
        return 350.0 + 0.0*lvl
    endfunction
    
    //How long the Plane will last
    private function Duration takes integer lvl returns real
        return 8.0 + 0.0*lvl    //0.0*lvl exist to make the function inline
    endfunction
    
    //************************************************************************************
    //***************************** GUN CONFIGURATION ************************************
    //************************************************************************************
    
    //Search radius for gun target
    private function GunRadius takes integer lvl returns real
        return 1400 + 0.0*lvl
    endfunction
    
    //How fast the gun fires
    private function GunFiringRate takes integer lvl returns real
        return 0.1 + 0.0*lvl             //Every 0.1 second, each Plane gun will fire
    endfunction 
    
    //Damage per gun bullet
    private function GunDamage takes integer lvl returns real
        return 4.0 + 1.0*lvl        //5, 6, 7    
    endfunction
    
    //Number of Plane's gun per level
    private function GunCount takes integer lvl returns integer
        return 1 + lvl              //2, 3, 4
    endfunction
    
    //What gets hit by the Gun
    private function TargetFilter takes unit u, player owner returns boolean
        return UnitAlive(u) and IsUnitEnemy(u, owner)
    endfunction
    
    //Position of Guns with reference to the Plane's center when the Plane is facing 0 degrees.
    //gunNumber starts at 1
    private function GunOffsetX takes integer gunNumber, integer totalGunNumber returns real
        return 0. + 0*gunNumber + 0*totalGunNumber    //All guns will belong to the same x-axis of the Plane
    endfunction
    
    private function GunOffsetY takes integer gunNumber, integer totalGunNumber returns real
        if totalGunNumber == 2 then
            return -150. + gunNumber*100   //-50, 50
        elseif totalGunNumber == 3 then
            return -100. + gunNumber*50   //-50, 0, 50
        elseif totalGunNumber == 4 then
            return -100. + gunNumber*40   //-60, -20, 20, 60
        endif
        return 0.
    endfunction
    
    //************************************************************************************
    //************************** PARATROOPER CONFIGURATION *******************************
    //************************************************************************************
    
    //Paratrooper Hitpoints per level
    private function ParatrooperLife takes integer lvl returns real
        return 100.0 + 50.0*lvl         //150, 200, 250
    endfunction
    
    //Paratrooper Bonus Damage per level (See also Attack Cooldown of Paratrooper to balance)
    private function ParatrooperAttackDamage takes integer lvl returns integer
        return 2 + lvl            //3, 4, 5
    endfunction
    
    //Paratrooper Bonus Armor per level
    private function ParatrooperArmor takes integer lvl returns integer
        return lvl                 //1, 2, 3
    endfunction
    
    //Paratrooper Spawnrate (second)
    private function SpawnRate takes integer lvl returns real
        return 1.0 - 0.2*lvl       //Every 0.8/0.6/0.4 second, a Paratrooper will spawn
    endfunction
    
    //The maximum number of paratroopers the spell can spawn
    private function MaxSpawnCount takes integer lvl returns integer
        return 3 + lvl            //4, 5, 6
    endfunction
    
    static if APPLY_TIMED_LIFE then
        //Only applicable if APPLY_TIMED_LIFE = true
        //Determines how long each Paratrooper last.
        private function TimedLife takes integer lvl returns real
            return 7.0 + 1.0*lvl
        endfunction
    endif
    
    //====================================================================================
    //============================ END CONFIGURATION =====================================
    //====================================================================================
    
    static if not LIBRARY_BonusMod then
        
        //For the static if to work, the variables must be a static member of a struct
        private struct S1 extends array
            static constant integer BONUS_ARMOR = 0
            static constant integer BONUS_DAMAGE = 1
            static integer array pow2
            static integer array bonusAbility
        endstruct

        private function UnitSetBonus2 takes unit u, integer bonusType, integer amount returns boolean
            local integer i = 7
            loop
                if amount >= S1.pow2[i] then
                    call UnitAddAbility(u, S1.bonusAbility[bonusType*8 + i])
                    call UnitMakeAbilityPermanent(u, true, S1.bonusAbility[bonusType*7 + i])
                    set amount = amount - S1.pow2[i]
                endif
                set i = i - 1
                exitwhen i < 0 or amount == 0
            endloop
            return true
        endfunction
        
        private function BonusMod_Init takes nothing returns nothing
            local integer i = 0
            static if PRELOAD then
                local unit u = CreateUnit(DUMMY_OWNER, PARATROOPER_AIR_ID, 0, 0, 0)
            endif
            
            // Bonus Mod - Armor abilitys
            set S1.bonusAbility[i + 0]  = 'ZxA0' // +1
            set S1.bonusAbility[i + 1]  = 'ZxA1' // +2
            set S1.bonusAbility[i + 2]  = 'ZxA2' // +4
            set S1.bonusAbility[i + 3]  = 'ZxA3' // +8
            set S1.bonusAbility[i + 4]  = 'ZxA4' // +16
            set S1.bonusAbility[i + 5]  = 'ZxA5' // +32
            set S1.bonusAbility[i + 6]  = 'ZxA6' // +64
            set S1.bonusAbility[i + 7]  = 'ZxA7' // +128
            // Bonus Mod - Damage abilitys
            set i = 8
            set S1.bonusAbility[i + 0]  = 'ZxB0' // +1
            set S1.bonusAbility[i + 1]  = 'ZxB1' // +2
            set S1.bonusAbility[i + 2]  = 'ZxB2' // +4
            set S1.bonusAbility[i + 3]  = 'ZxB3' // +8
            set S1.bonusAbility[i + 4]  = 'ZxB4' // +16
            set S1.bonusAbility[i + 5]  = 'ZxB5' // +32
            set S1.bonusAbility[i + 6]  = 'ZxB6' // +64
            set S1.bonusAbility[i + 7]  = 'ZxB7' // +128
            //Initialize cached power of 2
            set S1.pow2[0] = 1
            set i = 1
            loop
                set S1.pow2[i] = 2*S1.pow2[i - 1]
                set i = i + 1
                exitwhen i == 8
            endloop
            //Preload
            static if PRELOAD then
                set i = 0
                loop
                    exitwhen i > 15
                    call UnitAddAbility(u, S1.bonusAbility[i])
                    set i = i + 1
                endloop
                call RemoveUnit(u)
                set u = null
            endif
        endfunction
    endif
    
    static if not LIBRARY_SetUnitMaxState then
        
        private struct S2 extends array
            static integer array pow2
        endstruct
        
        private function SetUnitMaxState2 takes unit u, unitstate state, real newValue returns nothing
            local integer newVal = R2I(newValue)
            local integer i = 8
            local integer offset
            
            set newVal = newVal - R2I(GetUnitState(u, state))
            
            if newVal > 0 then
                set offset = 11
            elseif newVal < 0 then
                set offset = 2
                set newVal = -newVal
            else
                return
            endif
            
            loop
                exitwhen newVal == 0 or i < 0
                if newVal >= S2.pow2[i] then
                    call UnitAddAbility(u, 'Zx01')
                    call SetUnitAbilityLevel(u, 'Zx01', offset + i)
                    call UnitRemoveAbility(u, 'Zx01')
                    set newVal = newVal - S2.pow2[i]
                else
                    set i = i - 1
                endif
            endloop
        endfunction
        
        private function SetUnitMaxState_Init takes nothing returns nothing
            local integer i = 1
            static if PRELOAD then
                local unit u = CreateUnit(DUMMY_OWNER, PARATROOPER_AIR_ID, 0, 0, 0)
            endif
            
            set S2.pow2[0] = 1
            loop
                set S2.pow2[i] = 2*S2.pow2[i - 1]
                set i = i + 1
                exitwhen i == 11
            endloop
            static if PRELOAD then
                call UnitAddAbility(u, 'Zx01')
                call RemoveUnit(u)
                set u = null
            endif
        endfunction
    endif
    
    static if not LIBRARY_WorldBounds then
        //Uses a private struct WorldBounds2
        private struct WorldBounds2 extends array
        
            readonly static real maxX
            readonly static real maxY
            readonly static real minX
            readonly static real minY
            
            private static method onInit takes nothing returns nothing
                local rect map = GetWorldBounds()
                set thistype.maxX = GetRectMaxX(map)
                set thistype.maxY = GetRectMaxY(map)
                set thistype.minX = GetRectMinX(map)
                set thistype.minY = GetRectMinY(map)
                call RemoveRect(map)
                set map = null
            endmethod
            
        endstruct
    endif
    
    globals
        private location l = Location(0, 0)
        private real playMinX
        private real playMaxX
        private real playMinY
        private real playMaxY
    endglobals
    
    private struct Paratrooper
        
        private unit soldier
        private unit parachute
        private effect parachuteModel
        private boolean activated 
        private boolean transformed
        private integer damage //bonus damage is lost upon transformation
                               //that's why this needs to be stored
        //Movement
        private real z
        private real dz 
        
        private thistype next
        private thistype prev
        
        private static timer t = CreateTimer()
        
        //constants to avoid repeating calculations
        //constants to fill in the TIMEOUT
        private static constant real GRAVITY = -PARATROOPER_GRAVITY*TIMEOUT
        private static constant real SPEED_DAMAGE = SPEED_WITH_DAMAGE*TIMEOUT
        private static constant real TERMINAL_VELOCITY = -PARACHUTE_FALL_SPEED*TIMEOUT
        
        static if not LIBRARY_BonusMod then
            private static constant integer BONUS_ARMOR = 0
            private static constant integer BONUS_DAMAGE = 1
        endif
        
        //Calls when the soldier landed
        private method destroy takes nothing returns nothing
            //Remove from List
            set .prev.next = .next
            set .next.prev = .prev
            if thistype(0).next == 0 then
                call PauseTimer(t)
            endif

            //Remove Parachute
            call DestroyEffect(.parachuteModel)
            static if LIBRARY_DummyRecycler then
                call DummyAddRecycleTimer(.parachute, 3.0)
            elseif LIBRARY_MissileRecycler then
                call RecycleMissile(.parachute)
            else
                call UnitApplyTimedLife(.parachute, 'BTLF', 3.0)
            endif
            set .parachuteModel = null
            set .soldier = null
            set .parachute = null
            call .deallocate()
        endmethod
        
        //! textmacro AERIAL_AID_PARATROOPER_UPDATE
            set .z = .z + .dz
            if .activated then
                if .dz < TERMINAL_VELOCITY then
                    //Apply drag (air-resistance)
                    set .dz = .dz*DRAG_COEFFICIENT
                    if .dz > TERMINAL_VELOCITY then
                        set .dz = TERMINAL_VELOCITY
                    endif
                else
                    //increase speed due to gravity until it reaches terminal velocity
                    set .dz = .dz + GRAVITY
                endif
                call SetUnitX(.parachute, GetUnitX(.soldier))
                call SetUnitY(.parachute, GetUnitY(.soldier))
            else
                set .dz = .dz + GRAVITY
                if .z < PARACHUTE_ACTIVATE then
                    set .activated = true
                    //Create the Parachute
                    static if LIBRARY_DummyRecycler then
                        set .parachute = GetRecycledDummy(GetUnitX(.soldier), GetUnitY(.soldier), .z, GetRandomReal(0, 360))
                    elseif LIBRARY_MissileRecycler then
                        set .parachute = GetRecycledMissile(GetUnitX(.soldier), GetUnitY(.soldier), .z, GetRandomReal(0, 360))
                    else
                        set .parachute = CreateUnit(DUMMY_OWNER, DUMMY_ID, GetUnitX(.soldier), GetUnitY(.soldier), GetRandomReal(0, 360))
                        call SetUnitFlyHeight(.parachute, .z, 0)
                    endif
                    set .parachuteModel = AddSpecialEffectTarget(PARACHUTE_MODEL, .parachute, "origin")
                endif
            endif
            if .z <= 0 then
                call SetUnitFlyHeight(.parachute, .z, 0)
                //For realism effect
                if .dz < -SPEED_DAMAGE then
                    call KillUnit(.soldier)
                endif
                call .destroy()
            else
                if .activated then
                    call SetUnitFlyHeight(.parachute, .z, 0)
                endif
                if .z < GND_HEIGHT and not .transformed then
                    call UnitAddAbility(.soldier, TRANSFORM_ID)
                    call UnitRemoveAbility(.soldier, TRANSFORM_ID)
                    set .transformed = true
                    static if LIBRARY_BonusMod then
                        call UnitSetBonus(.soldier, BONUS_DAMAGE, .damage)
                    else
                        call UnitSetBonus2(.soldier, BONUS_DAMAGE, .damage)
                    endif
                endif
                call SetUnitFlyHeight(.soldier, .z, 0)
            endif
        //! endtextmacro
        
        private static method pickAll takes nothing returns nothing
            local thistype this = thistype(0).next
            local real x
            local real y
            loop
                exitwhen this == 0
                //Using a textmacro to save a function call per paratrooper instance
                //! runtextmacro AERIAL_AID_PARATROOPER_UPDATE()
                set this = .next
            endloop
        endmethod
        
        static method create takes player owner, integer lvl, real x, real y, real z returns thistype
            local thistype this = .allocate()
            local real spd = 0

            //Paratrooper Initialization
            set .transformed = false
            set .activated = false
            set .z = z
            set .dz = 0
            
            //Create the soldier
            set .soldier = CreateUnit(owner, PARATROOPER_AIR_ID, x, y, GetRandomReal(0, 360))
            static if APPLY_TIMED_LIFE then
                call UnitApplyTimedLife(.soldier, 'BTLF', TimedLife(lvl))
            endif
            call MoveLocation(l, x, y)
            call SetUnitFlyHeight(.soldier, .z - GetLocationZ(l), 0)
            static if not CAN_BE_HIT then
                call UnitAddAbility(.soldier, 'Avul')
            endif
            
            //Stats
            set .damage = ParatrooperAttackDamage(lvl)
            static if LIBRARY_BonusMod then
                call UnitSetBonus(.soldier, BONUS_DAMAGE, .damage)
                call UnitSetBonus(.soldier, BONUS_ARMOR, ParatrooperArmor(lvl))
            else
                call UnitSetBonus2(.soldier, BONUS_DAMAGE, .damage)
                call UnitSetBonus2(.soldier, BONUS_ARMOR, ParatrooperArmor(lvl))
            endif
            static if LIBRARY_SetUnitMaxState then
                call SetUnitMaxState(.soldier, UNIT_STATE_MAX_LIFE, ParatrooperLife(lvl))
            else
                call SetUnitMaxState2(.soldier, UNIT_STATE_MAX_LIFE, ParatrooperLife(lvl))
            endif
            
            //Linked-list
            set .next = 0
            set .prev = thistype(0).prev
            set .next.prev = this
            set .prev.next = this
            if .prev == 0 then
                call TimerStart(t, TIMEOUT, true, function thistype.pickAll)
            endif
            return this
        endmethod
        
    endstruct

    private struct Bullet
    
        private player owner
        private unit source
        private unit u
        private effect bulletModel
        private real damage
        private boolean lineCollision
        
        private real x
        private real y
        private real z
        
        private real dx
        private real dy
        private real dz
        private real dxy
        private real dxyz
        
        private thistype next
        private thistype prev
        
        private static timer t = CreateTimer()
        private static group g = CreateGroup()
        
        method destroy takes nothing returns nothing
            //Remove from List
            set .prev.next = .next
            set .next.prev = .prev
            if thistype(0).next == 0 then
                call PauseTimer(t)
            endif
            //Clean handles
            static if LIBRARY_DummyRecycler then
                call DummyAddRecycleTimer(.u, 1.0)
            elseif LIBRARY_MissileRecycler then
                call RecycleMissile(.u)
            else
                call UnitApplyTimedLife(.u, 'BTLF', 1.0)
            endif
            call DestroyEffect(.bulletModel)
            set .u = null
            set .source = null
            set .bulletModel = null
            call .deallocate()
        endmethod
        
        private static constant real BULLET_COLLISION2 = BULLET_COLLISION*BULLET_COLLISION
        
        //! textmacro AERIAL_AID_BULLET_LOCALS
            local real x
            local real y
            local real z
            local real dx
            local real dy
            local real dz
            local real height
            local real dist
            local real checkDist
            local unit u
            local unit hit
            local boolean withinBound
        
            //line data for line collision
            local real xPrev
            local real yPrev
            local real zPrev
            local real radius
            local real dxL
            local real dyL
            local real dzL
            local real projection
        //! endtextmacro
        
        //! textmacro AERIAL_AID_BULLET_UPDATE
            if .lineCollision then
                //Store last position
                set xPrev = .x
                set yPrev = .y
                set zPrev = .z
                set radius = 0.5*.dxy
            endif
            
            //Initially no one is hit
            set hit = null
            
            //Update position
            set .x = .x + .dx
            set .y = .y + .dy
            set .z = .z + .dz
            call MoveLocation(l, .x, .y)
            set height = .z - GetLocationZ(l)
            static if LIBRARY_WorldBounds then
                set withinBound = .x > WorldBounds.minX and .x < WorldBounds.maxX and .y > WorldBounds.minY and .y < WorldBounds.maxY
            else
                set withinBound = .x > WorldBounds2.minX and .x < WorldBounds2.maxX and .y > WorldBounds2.minY and .y < WorldBounds2.maxY
            endif
            if withinBound then
                call SetUnitX(.u, .x)
                call SetUnitY(.u, .y)
                call SetUnitFlyHeight(.u, height, 0)
            endif
            
            //Check Collision
            if .lineCollision then  //when bullet moves to fast
                set dxL = .x - xPrev
                set dyL = .y - yPrev
                set dzL = .z - zPrev
                set checkDist = (.dxyz + BULLET_COLLISION)*(.dxyz + BULLET_COLLISION)
                call GroupEnumUnitsInRange(g, xPrev + 0.5*.dx, yPrev + 0.5*.dy, radius + 2*BULLET_COLLISION, null)
                loop
                    set u = FirstOfGroup(g)
                    exitwhen u == null
                    call GroupRemoveUnit(g, u)
                    
                    set x = GetUnitX(u)
                    set y = GetUnitY(u)
                    call MoveLocation(l, x, y)
                    set z = GetLocationZ(l) + GetUnitFlyHeight(u) 
                    set dx = x - xPrev
                    set dy = y - yPrev
                    set dz = z - zPrev
                    //Scalar Projection of vector (xPrev -> x, yPrev -> y) on line (xPrev -> x, yPrev -> y)
                    set projection = (dx*dxL + dy*dyL + dz*dzL)/(.dxyz)
                    set dist = dx*dx + dy*dy + dz*dz    //distance of target to line point1
                    //dist - projection*projection = 3D distance of the picked unit to the line
                    if dist - projection*projection <= BULLET_COLLISION2 then
                        if TargetFilter(u, .owner) then
                            if dist < checkDist then    //if it is closer to the line point1
                                set checkDist = dist
                                set hit = u
                            endif
                        endif
                    endif
                endloop
            else
                set checkDist = BULLET_COLLISION2
                call GroupEnumUnitsInRange(g, .x, .y, BULLET_COLLISION, null)
                loop
                    set u = FirstOfGroup(g)
                    exitwhen u == null
                    call GroupRemoveUnit(g, u)
                    
                    set x = GetUnitX(u)
                    set y = GetUnitY(u)
                    call MoveLocation(l, x, y)
                    set z = GetLocationZ(l) + GetUnitFlyHeight(u)
                    set dx = x - .x
                    set dy = y - .y
                    set dz = z - .z
                    //Check if it collides in 3D
                    set dist = dx*dx + dy*dy + dz*dz    //distance of target to bullet
                    if dist <= checkDist then
                        if TargetFilter(u, .owner) then
                            set checkDist = dist
                            set hit = u
                        endif
                    endif
                endloop
            endif
            
            if hit != null then
                call UnitDamageTarget(.source, hit, .damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
                call .destroy()
                set hit = null
            elseif height < 0 or height > 1500 or not withinBound then
                call .destroy()
            endif
            
        //! endtextmacro
        
        private static method pickAll takes nothing returns nothing
            local thistype this = thistype(0).next
            //! runtextmacro AERIAL_AID_BULLET_LOCALS()
            loop
                exitwhen this == 0
                //Use textmacro to save a function call per bullet instance
                //! runtextmacro AERIAL_AID_BULLET_UPDATE()
                set this = .next
            endloop
        endmethod
        
        static method create takes real x1, real y1, real z1, real x2, real y2, real z2, unit source, player owner, real damage returns thistype
            local thistype this = .allocate()
            local real dx = x2 - x1
            local real dy = y2 - y1
            local real dz = z2 - z1
            local real facing = Atan2(dy, dx)
            local real pitch = Atan(dz/SquareRoot(dx*dx + dy*dy))
            
            static if BULLET_SPEED_3D then
                set .dxy = BULLET_SPEED*BULLET_TIMEOUT*Cos(pitch)
            else
                set .dxy = BULLET_SPEED*BULLET_TIMEOUT
            endif
            
            //Initialize positions and speeds
            set .x = x1
            set .y = y1
            set .z = z1
            set .dx = dxy*Cos(facing)
            set .dy = dxy*Sin(facing)
            static if BULLET_SPEED_3D then
                set .dz = BULLET_SPEED*BULLET_TIMEOUT*Sin(pitch)
                set .dxyz = BULLET_SPEED*BULLET_TIMEOUT
            else
                set .dz = BULLET_SPEED*BULLET_TIMEOUT*Tan(pitch)
                if pitch == 0 then
                    set .dxyz = .dxy
                else
                    set .dxyz = .dz/Sin(pitch)
                endif
            endif
            set .lineCollision = dxy > BULLET_COLLISION
            //Initialize bullet interact properties
            set .source = source
            set .owner = owner
            set .damage = damage
            
            //Create Bullet and set appropriate angle
            //Safety precaution, make sure bullet is not outside bounds
            static if LIBRARY_WorldBounds then
                if x1 > WorldBounds.maxX then
                    set x1 = WorldBounds.maxX
                elseif x1 < WorldBounds.minX then
                    set x1 = WorldBounds.minX
                endif
                if y1 > WorldBounds.maxY then
                    set y1 = WorldBounds.maxY
                elseif y1 < WorldBounds.minY then
                    set y1 = WorldBounds.minY
                endif
            else
                if x1 > WorldBounds2.maxX then
                    set x1 = WorldBounds2.maxX
                elseif x1 < WorldBounds2.minX then
                    set x1 = WorldBounds2.minX
                endif
                if y1 > WorldBounds2.maxY then
                    set y1 = WorldBounds2.maxY
                elseif y1 < WorldBounds2.minY then
                    set y1 = WorldBounds2.minY
                endif
            endif
            call MoveLocation(l, x1, y1)
            static if LIBRARY_DummyRecycler then
                set .u = GetRecycledDummy(x1, y1, z1 - GetLocationZ(l), facing*bj_RADTODEG)
            elseif LIBRARY_MissileRecycler then
                set .u = GetRecycledMissile(x1, y1, z1 - GetLocationZ(l), facing*bj_RADTODEG)
            else
                set .u = CreateUnit(DUMMY_OWNER, DUMMY_ID, x1, y1, facing*bj_RADTODEG)
                call SetUnitFlyHeight(.u, z1 - GetLocationZ(l), 0)
            endif
            set .bulletModel = AddSpecialEffectTarget(BULLET_MODEL, .u, "origin")
            call SetUnitAnimationByIndex(.u, R2I(pitch*bj_RADTODEG + 90.5))
            
            //Linked-list
            set .next = 0
            set .prev = thistype(0).prev
            set .next.prev = this
            set .prev.next = this
            if .prev == 0 then
                call TimerStart(t, BULLET_TIMEOUT, true, function thistype.pickAll)
            endif
            return this
        endmethod
        
    endstruct
    
    private struct Gun
        
        private effect targetSfx
        
        readonly unit target
        readonly real dx
        readonly real dy
    
        readonly thistype next
        readonly thistype prev
        
        method destroy takes nothing returns nothing
            //Remove from List
            set .prev.next = .next
            set .next.prev = .prev
            if .target != null then
                call DestroyEffect(.targetSfx)
            endif
            set .targetSfx = null
            set .target = null
            call .deallocate()
        endmethod
        
        method update takes unit newTarget returns nothing
            if newTarget != .target then
                if .target != null then
                    call DestroyEffect(.targetSfx)
                endif
                if newTarget != null then
                    set .targetSfx = AddSpecialEffectTarget(TARGET_MODEL, newTarget, TARGET_ATTACHMENT)
                endif
            endif
            set .target = newTarget
        endmethod
        
        static method create takes thistype head, real dx, real dy returns thistype
            local thistype this = .allocate()

            set .dx = dx
            set .dy = dy
            set .target = null
            
            set .next = head.next
            set .prev = head
            set .next.prev = this
            set .prev.next = this
            return this
        endmethod
        
        static method head takes nothing returns thistype
            local thistype this = .allocate()
            set .next = 0
            set .prev = 0
            return this
        endmethod
        
    endstruct
    
    
    //The self-sorting list, using an Insertion Sort algorithm
    private struct List
    
        private real value
        readonly unit unit
        readonly thistype next
        readonly thistype prev
        
        method destroy takes nothing returns nothing
            //Remove List
            set .prev.next = .next
            set .next.prev = .prev
            set .value = 0
            set .next = 0
            set .unit = null
            call .deallocate()
        endmethod
        
        static method empty takes nothing returns nothing
            local thistype this = thistype(0).next
            loop
                exitwhen this == 0
                call .destroy()
                set this = thistype(0).next
            endloop
        endmethod
        
        static method add takes unit u, real hp, integer count returns nothing
            local thistype node = thistype(0).next  //head node is thistype(0)
            local boolean insert = true
            local thistype this
            static if PRIORITIZE_HERO then
                local boolean isHero = IsUnitType(u, UNIT_TYPE_HERO)
            endif
            //Insert in the current list
            loop
                exitwhen node == 0 
                static if PRIORITIZE_HERO then
                    if isHero then
                        exitwhen hp < node.value or not IsUnitType(node.unit, UNIT_TYPE_HERO)
                    else
                        exitwhen hp < node.value and not IsUnitType(node.unit, UNIT_TYPE_HERO)
                    endif
                else
                     exitwhen hp < node.value
                endif
                set count = count - 1
                //If it will not get included in the count anyway, end the insertion and do not insert it in the list
                if count == 0 then
                    set insert = false
                    exitwhen true
                endif
                set node = node.next
            endloop
            //Insert 'this' before 'node'
            if insert then
                set this = .allocate()
                set .unit = u
                set .value = hp
                set .next = node
                set .prev = node.prev
                set .next.prev = this
                set .prev.next = this
            endif
        endmethod
    endstruct
    
    private struct Effect
    
        private lightning laser
        private real x1
        private real y1
        private real x2
        private real y2
        
        private thistype next
        private thistype prev
        
        private method destroy takes nothing returns nothing
            //Remove from List
            set .prev.next = .next
            set .next.prev = .prev
            //Clean ups
            call DestroyLightning(.laser)
            set .laser = null
            call .deallocate()
        endmethod
        
        method destroyAll takes nothing returns nothing
            local thistype node = .next
            loop
                exitwhen node == 0
                call node.destroy()
                set node = node.next
            endloop
            call .destroy()
        endmethod
        
        //Used on head instances
        method updateHead takes real dx, real dy returns nothing
            local thistype node = .next
            loop
                exitwhen node == 0
                set node.x1 = node.x1 + dx
                set node.y1 = node.y1 + dy
                set node.x2 = node.x2 + dx
                set node.y2 = node.y2 + dy
                call MoveLightningEx(node.laser, false, node.x1, node.y1, 0, node.x2, node.y2, 0)
                set node = node.next
            endloop
        endmethod
        
        static method create takes thistype head, real x1, real y1, real x2, real y2, player p returns thistype
            local thistype this = .allocate()
            set .laser = AddLightning(LASER_CODE, false, x1, y1, x2, y2)
            static if not VISIBLE_LASER then
                if IsPlayerEnemy(GetLocalPlayer(), p) then
                    call SetLightningColor(.laser, 0, 0, 0, 0)
                endif
            endif
            set .x1 = x1
            set .y1 = y1
            set .x2 = x2
            set .y2 = y2
            set .next = head.next
            set .prev = head
            set .next.prev = this
            set .prev.next = this
            return this
        endmethod
        
        private static constant real PLANE_SIGHT_HALF_ANGLE_RAD = 0.5*PLANE_SIGHT_ANGLE*bj_DEGTORAD
        
        static method head takes real x, real y, real angle, real radius, player owner returns thistype
            local thistype this = .allocate()
            local real dx = Cos(angle + PLANE_SIGHT_HALF_ANGLE_RAD)
            local real dy = Sin(angle + PLANE_SIGHT_HALF_ANGLE_RAD)
            local real limit = angle + PLANE_SIGHT_HALF_ANGLE_RAD
            local real tempAngle
            local real tempX
            local real tempY
            
            set .next = 0
            set .prev = 0
            //Create AREA_SFX radius
            call Effect.create(this, x + MIN_HIT_DISTANCE*dx, y + MIN_HIT_DISTANCE*dy, x + radius*dx, y + radius*dy, owner)
            set dx = Cos(angle - PLANE_SIGHT_HALF_ANGLE_RAD)
            set dy = Sin(angle - PLANE_SIGHT_HALF_ANGLE_RAD)
            call Effect.create(this, x + MIN_HIT_DISTANCE*dx, y + MIN_HIT_DISTANCE*dy, x + radius*dx, y + radius*dy, owner)

            //Create AREA_SFX curve
            //! textmacro AERIAL_AID_AREA_SFX_CURVE takes RADIUS
                set tempAngle = angle - PLANE_SIGHT_HALF_ANGLE_RAD
                set tempX = x + $RADIUS$*Cos(tempAngle)
                set tempY = y + $RADIUS$*Sin(tempAngle)
                loop
                    set tempAngle = tempAngle + LASER_DISTANCE/$RADIUS$
                    exitwhen tempAngle > limit
                    set dx = x + $RADIUS$*Cos(tempAngle)
                    set dy = y + $RADIUS$*Sin(tempAngle)
                    call Effect.create(this, tempX, tempY, dx, dy, owner)
                    set tempX = dx
                    set tempY = dy
                endloop
                call Effect.create(this, tempX, tempY, x + $RADIUS$*Cos(limit), y + $RADIUS$*Sin(limit), owner)
            //! endtextmacro
                        
            //! runtextmacro AERIAL_AID_AREA_SFX_CURVE("MIN_HIT_DISTANCE")
            //! runtextmacro AERIAL_AID_AREA_SFX_CURVE("radius")
            return this
        endmethod
        
        
    endstruct
    
    private struct Plane
        
        //Spell Mechanics
        private unit caster
        private unit plane
        private player owner
        private integer lvl
        private boolean toggled
        private boolean outside
        private real duration
        
        
        //Gun-related
        private Gun gunHead
        private real radius
        private integer gunCount
        private real gunDamage
        private real gunFireTime
        private real gunCtr     //counter for gun firing rate
        
        //Paratrooper-related
        private real soldierSpawnRate
        private real soldierCtr   //counter for paratrooper deployment
        private boolean deploy
        private integer spawnCtr    //number of paratrooper deployed
        
        //Visual Effect related
        private Effect sfxHead
        
        //Movement
        private real x      //Contains the location of the Plane, the Plane is not meant
        private real y      //to be moved by Moving effects such as Swap, Hook, Knockback, etc.
        private real z
        
        private real angle
        private real dx
        private real dy
        private real dz
        
        private thistype next
        private thistype prev
        
        private static timer t = CreateTimer()
        private static group g = CreateGroup()
        
        static if LIBRARY_Table then
            private static Table tb
            private static Table tbCount
        else
            private static hashtable hash = InitHashtable()
        endif
        
        static if not LIBRARY_BonusMod then
            private static constant integer BONUS_ARMOR = 0
        endif
        
        private method destroy takes nothing returns nothing
            local integer id = GetHandleId(.caster)
            //Remove from List
            set .prev.next = .next
            set .next.prev = .prev
            if thistype(0).next == 0 then
                call PauseTimer(t)
            endif

            //Table Clean-up
            static if LIBRARY_Table then
                set tbCount[id] = tbCount[id] - 1
                if tbCount[id] == 0 then
                    call tb.remove(id)
                    call tbCount.remove(id)
                    call UnitRemoveAbility(.caster, TOGGLE_ID)
                    call UnitRemoveAbility(.caster, SPELL_ID_DEPLOY)
                endif
            else
                call SaveInteger(hash, id, 1, LoadInteger(hash, id, 1) - 1)
                if LoadInteger(hash, id, 1) == 0 then
                    call FlushChildHashtable(hash, id)
                    call UnitRemoveAbility(.caster, TOGGLE_ID)
                    call UnitRemoveAbility(.caster, SPELL_ID_DEPLOY)
                endif
            endif
            //Destroy Handles
            if UnitAlive(.plane) then
                call RemoveUnit(.plane)
            endif
            //For perfect clean-up
            set .caster = null
            set .plane = null
            //Recycle Index
            call .deallocate()
        endmethod

        //Avoid recalculating them everytime
        private static constant real PLANE_SIGHT_HALF_ANGLE_RAD = 0.5*PLANE_SIGHT_ANGLE*bj_DEGTORAD
        private static constant real SLOPE_CHECK = MIN_HIT_DISTANCE/PLANE_HEIGHT
        
        private method update takes nothing returns nothing
            local Gun gun = .gunHead.next
            local boolean withinPlay    //within Playable Area
            local List list
            local unit u 
            local real x
            local real y
            local real z
            local real dx
            local real dy
            local real angle
            local real diff
            local real height
            
            //Movement
            set .x = .x + .dx
            set .y = .y + .dy
            
            //Safety check
            set withinPlay = .x < playMaxX and .x > playMinX and .y < playMaxY and .y > playMinY
            if withinPlay then
                call SetUnitX(.plane, .x)
                call SetUnitY(.plane, .y)
            endif
            
            //Hide/Unhide the Plane when leaving/entering playable map area
            if .outside then
                if withinPlay then
                    set .outside = false
                    call ShowUnit(.plane, true)
                endif
            else
                if not withinPlay then
                    set .outside = true
                    call ShowUnit(.plane, false)
                endif
            endif
            
            if .duration > 0 and UnitAlive(.plane) then
                //Change Plane Height
                if .z > PLANE_HEIGHT then
                    set .z = .z + .dz
                    if .z < PLANE_HEIGHT then
                        set .z = PLANE_HEIGHT
                    endif
                    call SetUnitFlyHeight(.plane, .z, 0)
                endif
                
                //Will only do some action if it has stable height
                if .z == PLANE_HEIGHT then
                    //Create SFX Laser Border when the Plane is active, it will only happen once
                    if .sfxHead == 0 then
                        set .sfxHead = Effect.head(.x, .y, .angle, .radius, .owner)
                    else
                        //Update SFX
                        call .sfxHead.updateHead(.dx, .dy)
                    endif
            
                    set .duration = .duration - TIMEOUT
                    //Targeting
                    call GroupEnumUnitsInRange(g, .x, .y, .radius, null)
                    call MoveLocation(l, .x, .y)
                    set z = GetLocationZ(l) + PLANE_HEIGHT
                    loop
                        set u = FirstOfGroup(g)
                        exitwhen u == null
                        call GroupRemoveUnit(g, u)

                        if TargetFilter(u, .owner) then
                            set x = GetUnitX(u)
                            set y = GetUnitY(u)
                            set dx = x - .x
                            set dy = y - .y
                            set angle = Atan2(dy, dx)
                            set diff = RAbsBJ(angle - .angle)
                            //Check if it is within range of gun angle
                            if RMinBJ(diff, 2*bj_PI - diff) <= PLANE_SIGHT_HALF_ANGLE_RAD then
                                //Then check if it is within range of gun pitch
                                call MoveLocation(l, x, y)
                                //GetUnitFlyHeight(u) + GetLocationZ(l) = absolute z of the target
                                //recycle variable 'real angle' as the check distance
                                set angle = SLOPE_CHECK*(z - GetUnitFlyHeight(u) - GetLocationZ(l)) //recycled real-type variable
                                if dx*dx + dy*dy >= angle*angle then   
                                    call List.add(u, GetWidgetLife(u), .gunCount)
                                endif
                            endif
                        endif
                    endloop
                    //Update Gun Targets
                    set list = List(0).next
                    loop
                        exitwhen gun == 0
                        call gun.update(list.unit)
                        set list = list.next
                        //If there are more guns than targets, go back to the first target so that all guns are active
                        if list == 0 then
                            set list = List(0).next
                        endif
                        set gun = gun.next
                    endloop
                    //Empty the list
                    call List.empty()
                    //Are the guns ready to fire?
                    set .gunCtr = .gunCtr + TIMEOUT
                    if .gunCtr >= .gunFireTime then
                        set .gunCtr = .gunCtr - .gunFireTime
                        set gun = .gunHead.next
                        loop
                            exitwhen gun == 0 or gun.target == null
                            set x = GetUnitX(gun.target)
                            set y = GetUnitY(gun.target)
                            call MoveLocation(l, x, y)
                            call Bullet.create(.x + gun.dx, .y + gun.dy, z, x, y, GetUnitFlyHeight(gun.target) + GetLocationZ(l), .plane, .owner, .gunDamage)
                            set gun = gun.next
                        endloop
                    endif
                    //Are paratroopers commanded to deploy?
                    if .deploy and .spawnCtr < MaxSpawnCount(.lvl) then
                        set .soldierCtr = .soldierCtr + TIMEOUT
                        if .soldierCtr >= .soldierSpawnRate then
                            set .soldierCtr = .soldierCtr - .soldierSpawnRate
                            if withinPlay then
                                call Paratrooper.create(.owner, .lvl, .x, .y, .z)
                                set .spawnCtr = .spawnCtr + 1
                            endif
                        endif
                    endif
                endif
            else
                //Destroy Guns
                if .gunHead != 0 then
                    loop
                        exitwhen gun == 0
                        call gun.destroy()
                        set gun = gun.next
                    endloop
                    call .gunHead.destroy()
                    set .gunHead = 0
                endif
                //Destroy Effects
                if .sfxHead != 0 then
                    call .sfxHead.destroyAll()
                    set .sfxHead = 0
                endif
                //Make the plane rise again until it is no longer seen in the screen
                set .z = .z - .dz
                if .z > PLANE_HEIGHT_INITIAL or not UnitAlive(.plane) then
                    call .destroy()
                else
                    call SetUnitFlyHeight(.plane, .z, 0)
                endif
            endif
        endmethod

        
        private static method pickAll takes nothing returns nothing
            local thistype this = thistype(0).next
            loop
                exitwhen this == 0
                call .update()
                set this = .next
            endloop
        endmethod
        
        //Delayed toggle
        private static method toggle takes nothing returns nothing
            local timer delay = GetExpiredTimer()
            static if LIBRARY_Table then
                local thistype this = tb[GetHandleId(delay)]
            else
                local thistype this = LoadInteger(hash, GetHandleId(delay), 0)
            endif
            
            set .toggled = true
            call UnitAddAbility(.caster, TOGGLE_ID)
            call UnitAddAbility(.caster, SPELL_ID_DEPLOY)
            call DestroyTimer(delay)
            set delay = null
        endmethod
        
        private static method onCast takes nothing returns nothing
            local thistype this = .allocate()
            local timer delay = CreateTimer()
            local integer i = 1
            local integer id
            local real x
            local real y
            local real cos
            local real sin
            local real spd
            local real gunX
            local real gunY
        
            //Spell Data and Initializations
            set .caster = GetTriggerUnit()
            set .owner = GetTriggerPlayer()
            set .deploy = false
            set .sfxHead = 0
            set .lvl = GetUnitAbilityLevel(.caster, SPELL_ID)
            set .spawnCtr = 0
            set .gunHead = Gun.head()
            set .gunCtr = 0
            set .gunFireTime = GunFiringRate(.lvl)
            set .gunDamage = GunDamage(.lvl)
            set .soldierCtr = 0
            set .soldierSpawnRate = SpawnRate(.lvl)
            set .duration = Duration(.lvl)
            set .radius = GunRadius(.lvl)
            set x = GetSpellTargetX()
            set y = GetSpellTargetY()
            set .angle = Atan2(y - GetUnitY(.caster), x - GetUnitX(.caster))
            set cos = Cos(.angle)
            set sin = Sin(.angle)
            set .gunCount = GunCount(.lvl)
            loop
                exitwhen i > .gunCount
                set gunX = GunOffsetX(i, .gunCount)
                set gunY = GunOffsetY(i, .gunCount)
                call Gun.create(.gunHead, gunX*cos - gunY*sin, gunY*cos + gunX*sin)
                set i = i + 1
            endloop
            
            //Movement Data
            set spd = PlaneSpeed(.lvl)*TIMEOUT
            set .dx = spd*cos
            set .dy = spd*sin
            set .dz = -PLANE_FALL_SPEED*TIMEOUT
            //Calculate the spawn loc based on duration and target location with an offset for the rise/fall of the plane
            set .x = x - (0.5*.duration + (PLANE_HEIGHT_INITIAL - PLANE_HEIGHT)/PLANE_FALL_SPEED)*PlaneSpeed(.lvl)*cos
            set .y = y - (0.5*.duration + (PLANE_HEIGHT_INITIAL - PLANE_HEIGHT)/PLANE_FALL_SPEED)*PlaneSpeed(.lvl)*sin
            set .z = PLANE_HEIGHT_INITIAL
            if .x > playMaxX or .x < playMinX or .y > playMaxY or .y < playMinY then
                //Safety precaution, make sure plane is not outside bounds to prevent fatal error
                //recycle 'x' and 'y' as the spawn loc, because .x and .y must not be overwritten
                set x = .x
                set y = .y
                static if LIBRARY_WorldBounds then
                    if x > WorldBounds.maxX then
                        set x = WorldBounds.maxX
                    elseif x < WorldBounds.minX then
                        set x = WorldBounds.minX
                    endif
                    if y > WorldBounds.maxY then
                        set y = WorldBounds.maxY
                    elseif y < WorldBounds.minY then
                        set y = WorldBounds.minY
                    endif
                else
                    if x > WorldBounds2.maxX then
                        set x = WorldBounds2.maxX
                    elseif x < WorldBounds2.minX then
                        set x = WorldBounds2.minX
                    endif
                    if y > WorldBounds2.maxY then
                        set y = WorldBounds2.maxY
                    elseif y < WorldBounds2.minY then
                        set y = WorldBounds2.minY
                    endif
                endif
                set .outside = true
                set .plane = CreateUnit(.owner, PLANE_ID, x, y, .angle*bj_RADTODEG)
                call ShowUnit(.plane, false)
            else
                set .outside = false
                set .plane = CreateUnit(.owner, PLANE_ID, .x, .y, .angle*bj_RADTODEG)
            endif
            call SetUnitFlyHeight(.plane, .z, 0)
            static if not CONTROLLABLE then
                call SetUnitTurnSpeed(.plane, 0.0)
            endif
            
            //Stats
            static if LIBRARY_BonusMod then
                call UnitSetBonus(.plane, BONUS_ARMOR, PlaneArmor(lvl))
            else
                call UnitSetBonus2(.plane, BONUS_ARMOR, PlaneArmor(lvl))
            endif
            static if LIBRARY_SetUnitMaxState then
                call SetUnitMaxState(.plane, UNIT_STATE_MAX_LIFE, PlaneLife(lvl))
            else
                call SetUnitMaxState2(.plane, UNIT_STATE_MAX_LIFE, PlaneLife(lvl))
            endif
            
            //Store caster handle id for onDeploy data retrieval
            set id = GetHandleId(.caster)
            static if LIBRARY_Table then
                set tb[id] = this
                set tbCount[id] = tbCount[id] + 1
                set tb[GetHandleId(delay)] = this
            else
                call SaveInteger(hash, id, 0, this)
                call SaveInteger(hash, id, 1, LoadInteger(hash, id, 1) + 1)
                call SaveInteger(hash, GetHandleId(delay), 0, this)
            endif
            
            //Toggle Ability
            call TimerStart(delay, 0., false, function thistype.toggle)
            
            //Linked-list
            set .next = 0
            set .prev = thistype(0).prev
            set .next.prev = this
            set .prev.next = this
            if .prev == 0 then
                call TimerStart(t, TIMEOUT, true, function thistype.pickAll)
            endif
        endmethod
        
        private static method onDeploy takes nothing returns nothing
            static if LIBRARY_Table then
                local thistype this = tb[GetHandleId(GetTriggerUnit())]
            else
                local thistype this = LoadInteger(hash, GetHandleId(GetTriggerUnit()), 0)
            endif

            set .deploy = true
            
            //Toggle Ability
            set .toggled = false
            call UnitRemoveAbility(.caster, TOGGLE_ID)
            call UnitRemoveAbility(.caster, SPELL_ID_DEPLOY)
        endmethod
        
        static if not LIBRARY_SpellEffectEvent then
            private static method castCondition takes nothing returns boolean
                local integer spell = GetSpellAbilityId()
                if spell == SPELL_ID then
                    call thistype.onCast()
                elseif spell == SPELL_ID_DEPLOY then
                    call thistype.onDeploy()
                endif
                return false
            endmethod
        endif

        private static method onInit takes nothing returns nothing
            local integer i = 0
            static if PRELOAD then
                local unit u1 = CreateUnit(DUMMY_OWNER, PARATROOPER_AIR_ID, 0, 0, 0)
                local unit u2 = CreateUnit(DUMMY_OWNER, PLANE_ID, 0, 0, 0)
            endif
            static if LIBRARY_SpellEffectEvent then
                call RegisterSpellEffectEvent(SPELL_ID, function thistype.onCast)
                call RegisterSpellEffectEvent(SPELL_ID_DEPLOY, function thistype.onDeploy)
            else
                local trigger t = CreateTrigger()
                call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
                call TriggerAddCondition(t, Condition(function thistype.castCondition))
            endif
            static if LIBRARY_Table then
                set tb = Table.create()
                set tbCount = Table.create()
            endif
            static if not LIBRARY_BonusMod then
                call BonusMod_Init()
            endif
            static if not LIBRARY_SetUnitMaxState then
                call SetUnitMaxState_Init()
            endif
            //For toggling from Aerial Aid -> Deploy Paratroopers and vice versa
            loop
                exitwhen i == bj_MAX_PLAYER_SLOTS
                call SetPlayerAbilityAvailable(Player(i), TOGGLE_ID, false)
                set i = i + 1
            endloop
            //Playable Map bounds for non-locust units
            set playMinX = GetRectMinX(bj_mapInitialPlayableArea)
            set playMaxX = GetRectMaxX(bj_mapInitialPlayableArea)
            set playMinY = GetRectMinY(bj_mapInitialPlayableArea)
            set playMaxY = GetRectMaxY(bj_mapInitialPlayableArea)
            static if PRELOAD then
                call UnitAddAbility(u1, TRANSFORM_ID)
                call UnitAddAbility(u2, SPELL_ID_DEPLOY)
                call UnitAddAbility(u2, SPELL_ID)
                call RemoveUnit(u1)
                call RemoveUnit(u2)
                set u1 = null
                set u2 = null
            endif
        endmethod
    
    endstruct

endscope

Spellset Information:

  • 1600 lines of vJASS code (Comments included).
  • 55 Configurables reaching all aspects of the ability.
  • Attached map comes with a mini-game showing the spell's capability.
  • Comes with sub-skill Deploy Paratroopers.
  • Excellent documentation explaining each configuration and the general work flow.
  • Follows JPAG coding convention.
  • Easy to import, no need to manually copy paste each Object Editor Data (uses lua Object generation).
  • Summoned units stats are controlled through code.
  • No dependencies, but it supports optional dependencies for better performance and execution.
  • Advance 3D missile system.
  • Great focus on safety, preventing crash due to units reaching outside the map bounds.
Spell Mechanics Note (Default Configuration):

  • Heroes have higher target priority than non-Hero units with lower hitpoints. See PRIORITIZE_HERO.
  • Paratroopers are first targeted as Air units, then changes Ground units when close to the ground. See GND_HEIGHT.
  • If Paratroopers somehow hits the ground greater than a threshold speed, it will instantly die. See SPEED_WITH_DAMAGE.
  • The plane will always use all of its gun even though there are less targets. All guns will be active as long as there is/are enemy unit(s) in sight.
  • Cliffs and Hills can block the Bullet from the Plane.
  • The Gun Bullet uses a 3D collision algorithm supporting even very fast missile speed.
  • The Gun Radius is centered on the Plane, not on the gun position. The Gun Position determines the source location of the bullets.
  • The target location will be the midpoint of the line connecting the spawn location and expire location.
  • The plane will be directly above the target point when exactly half of the total duration has elapsed.
  • Plane guns can only hit units within the field of sight of the Plane. The field of sight has a 3D conic shape and cannot hit units directly below it. The field of sight is indicated by the enclosed area of the laser.
  • The falling entrance and rising exit of the Plane is not part of the spell duration, and the plane is not active during that time and the duration timer is paused at that time.
  • Generates 3 object editor unit data (Plane, Paratrooper Flying, Paratrooper Ground).
  • Generates 4 object editor ability data (Aerial Aid, Deploy Paratroopers, Aerial Aid Toggle, Paratrooper Fly -> Ground).
  • If BonusMod is not used, it will generate additional 16 object editor ability data for the dynamically configurable attack damage and armor. In that case, Paratrooper Bonus Damage and Bonus Armor is capped at 255.
  • If SetUnitMaxState is not used, it will generate additional 1 object editor ability data for the dynamically configurable hitpoint.
  • The area enclosed by the laser shows the field of sight of the plane at absolute z difference of PLANE_HEIGHT.
WIP Links

- WIP#1
Images
Ignore the food used, I used it as a timer which updates every second.

Tooltip

Images

GIFs


tooltip.jpg

Plane Firing 1

Plane Firing 2

Deploying Paratroopers 1

Deploying Paratroopers 2

Plane_Firing1.jpg
Plane_Firing2.jpg
Deploying1.jpg
Deploying2.jpg

Spell Demo 1

Spell Demo 2

Enemy's Perspective

Using Cliffs as shield

AerialAid1.jpg
Coming soon when my internet miraculously got fast again.
EnemyPerspective1.jpg
CliffShield.jpg

Credits

Credits list is in the code.
[tr]
 

Attachments

  • Flux - Aerial Aid.w3x
    340.4 KB · Views: 52
  • Flux - Aerial Aid v1.01.w3x
    341.5 KB · Views: 57
Last edited:
Level 9
Joined
Oct 14, 2013
Messages
238
What's with the number of code-line competition?
Is that a thing here? I don't get it, tbh.
----
If there any files are incomplete or incorrect, please tell me because i'm new here > <
You need to reconfigure the names of your variables; look at the other entries to find out.

And by the way I don't think there is a need for Aghanim mode in this contest. Aghanim is only for DotA, and if it changes your spell's nature I think it is counted as 2 versions of your spell, which I think, completely from a personal viewpoint, will have negative score for you.
----
@Flux
Your entry is very similar to Jimmy Raynor's Ulti in HotS. Except for the parachute part. I know the mechanisms are different for guns, targeting and things, but the whole concept lacks originality, I guess. (Just my own opinion).
----
And, I need to provide some step by step documentation for my spell, I guess? So I'll be better get to it, sooner rather than later.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
What's with the number of code-line competition?
Is that a thing here? I don't get it, tbh.
----
Your entry is very similar to Jimmy Raynor's Ulti in HotS. Except for the parachute part. I know the mechanisms are different for guns, targeting and things, but the whole concept lacks originality, I guess. (Just my own opinion).
----
And, I need to provide some step by step documentation for my spell, I guess? So I'll be better get to it, sooner rather than later.
No of lines of code doesn't mean anything, I just like putting it there.

And I have no idea who Jimmy Raynor is, I don't play HotS. I can assure you, the concept of my entry is originally mine, no references. And why tell this now? You couldn't tell me this earlier?
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
Your entry is very similar to Jimmy Raynor's Ulti in HotS. Except for the parachute part. I know the mechanisms are different for guns, targeting and things, but the whole concept lacks originality, I guess. (Just my own opinion).
The only similarities between Flux's entry and Raynor's ulti from HotS is that a "plane" is called. Other than that, his spell is pretty original, especially for the Hive.
 
Status
Not open for further replies.
Top