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

Nether Barrage v0.02

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
  • Like
Reactions: ultmatmaster
Nether Barrage spell.
I got the Idea of this spell while I was playing WoW as an Arcane mage.

There are actually two spells - one creates bolts, another shoots'em.
Learning creation spell also adds the Shooting spell.
Created bolts float around the Caster until shot, so spamming this spell for many times can cause an immense lagg.

Give me credits if you use it.

  • Nether Barrage Learn
    • Events
      • Unit - A unit Learns a skill
    • Conditions
      • (Learned Hero Skill) Equal to Conjure Nether Bolt
      • (Level of Nether Barrage for (Triggering unit)) Equal to 0
    • Actions
      • -------- This trigger has only one action, because all it needs to do is to add the Barrage ability if it is the very first level of spell learned by Caster --------
      • Unit - Add Nether Barrage to (Triggering unit)
  • Conjure Nether Bolt
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Conjure Nether Bolt
    • Actions
      • -------- Stores Caster into a Variable --------
      • Set Caster = (Triggering unit)
      • -------- Finds location of Caster --------
      • Set Points[1] = (Position of Caster)
      • -------- Loads number of currently floating bolts --------
      • Set Integer[1] = (Load 0 of (Key (Triggering unit)) from Hashtable)
      • -------- Counts damage of Bolts --------
      • -------- NOTE 1: Change your damage here --------
      • Set Real[1] = (50.00 + (50.00 x (Real((Level of Conjure Nether Bolt for Caster)))))
      • -------- Sets the number of Bolts created now --------
      • -------- NOTE 2: Change your created bolts here, the second number defines how many bolts will be created --------
      • Set Integer[2] = 2
      • -------- Does the creation --------
      • For each (Integer A) from 1 to Integer[2], do (Actions)
        • Loop - Actions
          • -------- Increases the Number of Floating bolts by 1 for each bolt --------
          • Set Integer[1] = (Integer[1] + 1)
          • -------- Randomises orbiting speed --------
          • -------- NOTE 2: Change your min/max orbiting speed here --------
          • Set Real[2] = (Random real number between -18.00 and 18.00)
          • -------- Randomises distance from Caster --------
          • Set Real[3] = (Random real number between 30.00 and 200.00)
          • -------- Randomises starting angle --------
          • Set Real[4] = (Random angle)
          • -------- Randomises Floating Height --------
          • Set Real[5] = (Random real number between 10.00 and 350.00)
          • -------- Counts a location for randomized reals --------
          • Set Points[2] = (Points[1] offset by Real[3] towards Real[4] degrees)
          • -------- Creates a Bolt --------
          • -------- NOTE 4: Change your bolt's model in Object Editor, unit Nether Bolt --------
          • Unit - Create 1 Nether Bolt for (Owner of Caster) at Points[2] facing Real[4] degrees
          • -------- Enables the Edition of Bolt's flying height --------
          • Unit - Add Storm Crow Form to (Last created unit)
          • Unit - Remove Storm Crow Form from (Last created unit)
          • -------- Turns Collision of the Bolt off --------
          • Unit - Turn collision for (Last created unit) Off
          • -------- Changes Bolt's flying height to one randomized --------
          • Animation - Change (Last created unit) flying height to Real[5] at 75.00
          • -------- Stores all information needed to hashtable --------
          • -------- NOTE 5: All information is attached to Bolt --------
          • Hashtable - Save Handle OfCaster as 0 of (Key (Last created unit)) in Hashtable
          • Hashtable - Save Real[1] as 1 of (Key (Last created unit)) in Hashtable
          • Hashtable - Save Real[2] as 2 of (Key (Last created unit)) in Hashtable
          • Hashtable - Save Real[3] as 3 of (Key (Last created unit)) in Hashtable
          • -------- Marks the created bolt as available for use --------
          • -------- NOTE 6: This one is attached to Caster, be careful with your code --------
          • Hashtable - Save Handle Of(Last created unit) as Integer[1] of (Key (Triggering unit)) in Hashtable
          • -------- Checks if there are any floating bolts in game --------
          • -------- If not, turns on the Floating Trigger --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (FloatingBolts is empty) Equal to True
            • Then - Actions
              • Trigger - Turn on Nether Bolt Float <gen>
            • Else - Actions
          • -------- Adds created bolt to the Floating Bolts' group --------
          • Unit Group - Add (Last created unit) to FloatingBolts
          • -------- Clears the leak created here --------
          • Custom script: call RemoveLocation(udg_Points[2])
      • -------- Updates number of Floating Bolts --------
      • -------- NOTE 7: This one is attached to Caster, be careful with your code --------
      • Hashtable - Save Integer[1] as 0 of (Key (Triggering unit)) in Hashtable
      • -------- Checks if Caster is in Conjurers' group --------
      • -------- If not, adds Caster to it --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Caster is in Conjurers) Not equal to True
        • Then - Actions
          • Unit Group - Add Caster to Conjurers
        • Else - Actions
      • -------- Fixes the Leak --------
      • Custom script: call RemoveLocation(udg_Points[1])
  • Nether Bolt Shoot
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Nether Barrage
      • ((Triggering unit) is in Conjurers) Equal to True
    • Actions
      • -------- Stores Target into a variable --------
      • Set Target = (Target unit of ability being cast)
      • -------- Loads the Number of Available bolts --------
      • Set Integer[1] = (Load 0 of (Key (Triggering unit)) from Hashtable)
      • -------- Finds the Second number used in the Saves/loads, refering to the Last created bolt --------
      • Set Integer[2] = (Key (Load Integer[1] of (Key (Triggering unit)) in Hashtable))
      • -------- Changes Flying height of the Bolt to the one of Target's + 55 to make it hit the Chest of Target --------
      • Animation - Change (Load Integer[1] of (Key (Triggering unit)) in Hashtable) flying height to (55.00 + (Current flying height of Target)) at 400.00
      • -------- Stores Target into a Variable --------
      • -------- NOTE 1: This is attached to the Bolt --------
      • Hashtable - Save Handle OfTarget as 2 of Integer[2] in Hashtable
      • -------- Removes Bolt from Floating Bolts' group --------
      • Unit Group - Remove (Load Integer[1] of (Key (Triggering unit)) in Hashtable) from FloatingBolts
      • -------- Checks if there is any bolt flying at its target at the moment. If not, turns the Sliding trigger on --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (ExpandedBolts is empty) Equal to True
        • Then - Actions
          • Trigger - Turn on Nether Bolt Slide <gen>
        • Else - Actions
      • -------- Adds the Bolt into Expanded Bolts' group --------
      • Unit Group - Add (Load Integer[1] of (Key (Triggering unit)) in Hashtable) to ExpandedBolts
      • -------- Reduces available bolts' number by one --------
      • Set Integer[1] = (Integer[1] - 1)
      • -------- Checks if there is any bolt left --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Integer[1] Equal to 0
        • Then - Actions
          • -------- If not, clears the Hashtable for Caster's account and removes it from conjurers' group --------
          • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in Hashtable
          • Unit Group - Remove (Triggering unit) from Conjurers
        • Else - Actions
          • -------- If there is, updates the number of bolts left --------
          • Hashtable - Save Integer[1] as 0 of (Key (Triggering unit)) in Hashtable
      • -------- Checks if there is any Floating Bolt left in the game. If not, turns off the Floating Bolts' trigger --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (FloatingBolts is empty) Equal to True
        • Then - Actions
          • Trigger - Turn on Nether Bolt Float <gen>
        • Else - Actions
  • Nether Bolt Float
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in FloatingBolts and do (Actions)
        • Loop - Actions
          • -------- Loads the Caster --------
          • Set Caster = (Load 0 of (Key (Picked unit)) in Hashtable)
          • -------- Finds location of Caster - Our Center of all bolts' orbit --------
          • Set Points[1] = (Position of Caster)
          • -------- Checks if Caster is dead --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Caster is alive) Equal to True
            • Then - Actions
              • -------- If it isn't... --------
              • -------- Loads angle from Caster to the Bolt and increases it by Randomised angle --------
              • Set Real[1] = (Load 2 of (Key (Picked unit)) from Hashtable)
              • Set Real[1] = (Real[1] + (Facing of (Picked unit)))
              • -------- Loads Distance from Caster to the Bolt --------
              • Set Real[2] = (Load 3 of (Key (Picked unit)) from Hashtable)
              • -------- Counts the Point to which the Bolt would be moved --------
              • Set Points[2] = (Points[1] offset by Real[2] towards Real[1] degrees)
              • -------- Moves Bolt to the Counted Point --------
              • Unit - Move (Picked unit) instantly to Points[2], facing Real[1] degrees
              • -------- Fixes the leak --------
              • Custom script: call RemoveLocation(udg_Points[2])
            • Else - Actions
              • -------- If it is, then --------
              • -------- Finds the Hashtable Key of Caster --------
              • Custom script: set udg_Integer[1] = GetHandleIdBJ(udg_Caster)
              • -------- Clears Caster's hashtable account --------
              • Hashtable - Clear all child hashtables of child Integer[1] in Hashtable
              • -------- Removes Caster from Conjurers --------
              • Unit Group - Remove Caster from Conjurers
              • -------- Finds all posible targets --------
              • -------- NOTE 2: Enumerates all orgnic, non-magic immune visible units that don't have the Stray Bolt buff, which would only be gained this way. Does not enumerate Dummy Targets --------
              • -------- If you want to make it possible, but very imba IMO, to hit same target with several bolts after death, remove the checking if target has Stray Bolt Buff --------
              • Set PosTargets = (Units within 700.00 of Points[1] matching ((((((Matching unit) is A structure) Not equal to True) and ((Unit-type of (Matching unit)) Not equal to Dummy Caster)) and ((((Matching unit) has buff Stray Bolt ) Not equal to True) and (((Matching unit) is dead) N
              • -------- Checks if there is any target to hit --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (PosTargets is empty) Equal to True
                • Then - Actions
                  • -------- If not, then... --------
                  • -------- Randomises a point --------
                  • Set Points[2] = (Points[1] offset by (Random real number between 200.00 and 700.00) towards (Random angle) degrees)
                  • -------- Creates a dummy unit at the randomised point --------
                  • Unit - Create 1 Dummy Caster for (Owner of Caster) at Points[3] facing Default building facing degrees
                  • -------- Sets the Created dummy unit as the Target of the Stray bolt --------
                  • Set Target = (Last created unit)
                  • -------- Changes the Flying heigh of the Bolt to 0 --------
                  • Animation - Change (Picked unit) flying height to 0.00 at 400.00
                  • -------- Stores Caster into the Hashtable --------
                  • -------- NOTE 3: Attached to the Bolt --------
                  • Hashtable - Save Handle OfTarget as 2 of (Key (Picked unit)) in Hashtable
                  • -------- Checks if there is any Bolt already sliding. If not, turns the Sliding trigger on --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (ExpandedBolts is empty) Equal to True
                    • Then - Actions
                      • Trigger - Turn on Nether Bolt Slide <gen>
                    • Else - Actions
                  • -------- Changes group of the Bolt --------
                  • Unit Group - Remove (Picked unit) from FloatingBolts
                  • Unit Group - Add (Picked unit) to ExpandedBolts
                  • -------- Clears the leak made here --------
                  • Custom script: call RemoveLocation(udg_Points[2])
                • Else - Actions
                  • -------- Selects a random unit from Group and marks it as target --------
                  • Custom script: set bj_wantDestroyGroup = true
                  • Unit Group - Pick every unit in (Random 1 units from PosTargets) and do (Set Target = (Picked unit))
                  • -------- Gives it a Stray Bolt Buff, saving it from other bolts --------
                  • Unit - Create 1 Dummy Caster for (Owner of Caster) at Points[1] facing Default building facing degrees
                  • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
                  • Unit - Add Stray Bolt to (Last created unit)
                  • Unit - Order (Last created unit) to Undead Banshee - Curse Target
                  • -------- Changes the Flying Height of Bolt to one of Target's + 55, making it be at about chest of the Target --------
                  • Animation - Change (Picked unit) flying height to ((Current flying height of Target) + 55.00) at 400.00
                  • -------- Stores Target into Variable --------
                  • -------- NOTE 4: This one is attached to Bolt --------
                  • Hashtable - Save Handle OfTarget as 2 of (Key (Picked unit)) in Hashtable
                  • -------- Checks if there is any bolt sliding at its target already. If not, turns Sliding Trigger on --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (ExpandedBolts is empty) Equal to True
                    • Then - Actions
                      • Trigger - Turn on Nether Bolt Slide <gen>
                    • Else - Actions
                  • -------- Changes group of the Bolt --------
                  • Unit Group - Remove (Picked unit) from FloatingBolts
                  • Unit Group - Add (Picked unit) to ExpandedBolts
              • -------- Fixes the Group Leak --------
              • Custom script: call DestroyGroup(udg_PosTargets)
          • -------- Fixes the Location Leaks --------
          • Custom script: call RemoveLocation(udg_Points[1])
      • -------- Checks if there is any Floating Bolt left after loop. If no, turns this trigger off --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (FloatingBolts is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
  • Nether Bolt Slide
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in ExpandedBolts and do (Actions)
        • Loop - Actions
          • -------- Loads our Duo --------
          • Set Caster = (Load 0 of (Key (Picked unit)) in Hashtable)
          • Set Target = (Load 2 of (Key (Picked unit)) in Hashtable)
          • -------- Loads damage-to-deal --------
          • Set Real[1] = (Load 1 of (Key (Picked unit)) from Hashtable)
          • -------- Finds locations of the Duo, and counts a point at which the Bolt would be moved --------
          • Set Points[1] = (Position of (Picked unit))
          • Set Points[2] = (Position of Target)
          • Set Points[3] = (Points[1] offset by 25.00 towards (Angle from Points[1] to Points[2]) degrees)
          • -------- Checks if it is Time for bolt to hit the Target --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between Points[1] and Points[2]) Greater than or equal to 100.00
            • Then - Actions
              • -------- If not, moves Bolt to Counted Point --------
              • Unit - Move (Picked unit) instantly to Points[3]
            • Else - Actions
              • -------- If it is... --------
              • -------- Removes a Stray Bolt buff, in case it wasn't target of a normal Nether Barrage target --------
              • Unit - Remove Stray Bolt buff from Target
              • -------- Causes the Damage --------
              • Unit - Cause Caster to damage Target, dealing Real[1] damage of attack type Spells and damage type Normal
              • -------- Plays the impact SFX. on Ground if target is a Dummy Unit --------
              • -------- NOTE 1: Change your Impact SFX here --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of Target) Not equal to Dummy Caster
                • Then - Actions
                  • Special Effect - Create a special effect attached to the chest,mount of Target using Abilities\Spells\NightElf\SpiritOfVengeance\SpiritOfVengeanceBirthMissile.mdl
                • Else - Actions
                  • Special Effect - Create a special effect at Points[1] using Abilities\Spells\NightElf\SpiritOfVengeance\SpiritOfVengeanceBirthMissile.mdl
              • -------- FIxes SFX leak --------
              • Special Effect - Destroy (Last created special effect)
              • -------- Clears the Bolt's hashtable account --------
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in Hashtable
              • -------- Removes Bolt from Sliding Bolts' group and then from game --------
              • Unit Group - Remove (Picked unit) from ExpandedBolts
              • Unit - Remove (Picked unit) from the game
          • -------- Fixes the Leaks --------
          • Custom script: call RemoveLocation(udg_Points[1])
          • Custom script: call RemoveLocation(udg_Points[2])
          • Custom script: call RemoveLocation(udg_Points[3])
      • -------- Checks if there is any Sliding Bolt left after loop. If no, turns this trigger off --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (ExpandedBolts is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
v0.01 - First Release
v0.02 - Fixed Group Leak


Keywords:
nether, barrage, wow, mage, arcane
Contents

Nether Barrage v0.02 (Map)

Reviews
12.12 IcemanBo: For long time as NeedsFix. Rejected. 03:44, 12th Dec 2015 IcemanBo:
Note: just took a quick look at the code, might test this later...

instead of using the integer array (Integer[]), just use two integer variables since you only use two members of the array (Integer[1] and Integer[2])...

also with the other arrays like Real[], use different variables with more fitting name rather than creating an array with less than 10 members...
ex. change Real[1] to BoltDamage, Real[2] to OrbitSpeed, etc...

its always better to have the variables names to be self-explanatory...
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
First of all, I have to say I like the spell.

I'm against adding abilities like that. The command card slots are limited enough, many custom maps use five hero abilities plus maybe backpack icon etc. and the extra icon won't fit there. Maybe you could replace the summon ability with the shoot ability, and when the orbs are used, give the summon ability back.

This is unnecessary since the unit has locust. You can set collision size to 0 in object editor.
  • Unit - Turn collision for (Last created unit) Off
In Nether Bolt Load, you are loading stuff and then you do <Is caster alive> check. But you don't need all the stuff if the caster is dead.

Unit group leak:
  • Unit Group - Pick every unit in (Random 1 units from PosTargets) and do (Set Target = (Picked unit))
add
  • Cusom script: set bj_wantDestroyGroup = true
before that line.

These checks should be right after "remove unit from group" action:
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (FloatingBolts is empty) Equal to True
    • Then - Actions
      • Trigger - Turn off (This trigger)
    • Else - Actions
In Nether Bolt Slide, you calculate Point[3], but you don't necessarily need it.

I'd modify the tooltip a bit. Using "you" in a tooltip isn't a good idea.

I'm puzzled as to why you'd name the ability v0.01, since clearly this isn't v0.01. The rules state that only "finished" spells should be uploaded (meaning v1.00).

The effects are nice and the coding is good in general.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Bribe

With arrays, if you find yourself using "[1], [2], [3]" for things, those should be converted to regular variables because arrays are slower and consume more memory than regular variables.

(Key (Picked unit)) should be stored into a variable as it involves three function calls.

Nether bolt float
- PosTargets does not need to be set to a variable. You can use "set bj_wantDestroyGroup = true" and the "Unit group is empty" check will destroy the group internally.

Special effects would be nicer if their string-art could be configured during initialization.
 
Top