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

[Trigger] Problem With My Spell

Status
Not open for further replies.
Level 4
Joined
Jun 16, 2010
Messages
48
I Will Glad If Some One Can Help Me Im New With Hashtables And Im Making A Spell With Them ,I created a spell That slam the ground push all the units back and when they reach to the end a dps start for 4 second .main problem is when i cast my spell for the first time it have a bug & when i slam the ground and there is no unit near me to push back , next time i use my spell no one get dps. ( but if i slam the ground with unit for first time its work fine ) can any one help me?!
Please Test The Spell If U See Any Other Bug Pls Help Me To Fix It.
Fist Part :
  • Actions
    • -------- Setting VB --------
    • Set HS_DDps = 40.00
    • Set HS_TDps = 4.00
    • Set HS_C = (Triggering unit)
    • Set HS_P = (Position of HS_C)
    • Set HS_Loop = (HS_Loop + 1)
    • Set HS_T = 0.90
    • Set HS_D = 50.00
    • Set HS_UG = (Units within 300.00 of HS_P matching ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of HS_C)) Equal to True) and ((((Matching unit) is A structure) Equal to False) and (((Playable map area) contains (Matching
    • Trigger - Turn on HS I Loop <gen>
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every unit in HS_UG and do (Actions)
      • Loop - Actions
        • Set HS_Target = (Picked unit)
        • Custom script: set udg_HS_Handle = GetHandleId(udg_HS_Target)
        • Set HS_P2 = (Position of HS_Target)
        • Set HS_A = (Angle from HS_P2 to HS_P)
        • Set HS_Dis = (300.00 - (Distance between HS_P2 and HS_P))
        • Unit Group - Add HS_Target to HS_Group
        • Unit - Turn collision for HS_Target Off
        • Hashtable - Save HS_T as 1 of HS_Handle in HS_H
        • Hashtable - Save HS_A as 2 of HS_Handle in HS_H
        • Hashtable - Save HS_D as 3 of HS_Handle in HS_H
        • Hashtable - Save (HS_Dis / 6.00) as 4 of HS_Handle in HS_H
        • Hashtable - Save HS_TDps as 5 of HS_Handle in HS_H
        • Hashtable - Save HS_DDps as 6 of HS_Handle in HS_H
        • Custom script: call RemoveLocation(udg_HS_P2)
    • Custom script: call RemoveLocation(udg_HS_P)

  • HS I Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in HS_Group and do (Actions)
        • Loop - Actions
          • Hashtable - Save (HS_T - 0.03) as 1 of HS_Handle in HS_H
          • Set HS_Target = (Picked unit)
          • Custom script: set udg_HS_Handle = GetHandleId(udg_HS_Target)
          • Set HS_T = (Load 1 of HS_Handle from HS_H)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • HS_T Less than or equal to 0.00
            • Then - Actions
              • Trigger - Turn on HS I Dps <gen>
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • HS_T Greater than 0.00
            • Then - Actions
              • Destructible - Pick every destructible within 100.00 of (Position of HS_Target) and do (Actions)
                • Loop - Actions
                  • Destructible - Kill (Picked destructible)
              • Set HS_A = (Load 2 of HS_Handle from HS_H)
              • Set HS_D = (Load 3 of HS_Handle from HS_H)
              • Set HS_Dis = (Load 4 of HS_Handle from HS_H)
              • Set HS_P = (Position of HS_Target)
              • Set HS_P2 = (HS_P offset by HS_D towards (HS_A + 180.00) degrees)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Playable map area) contains HS_P2) Equal to True
                • Then - Actions
                  • Unit - Move HS_Target instantly to HS_P2, facing HS_A degrees
                • Else - Actions
              • Special Effect - Create a special effect attached to the origin of HS_Target using Abilities\Spells\Other\HealingSpray\HealBottleMissile.mdl
              • Special Effect - Destroy (Last created special effect)
              • Hashtable - Save (HS_Dis x (HS_T x HS_T)) as 3 of HS_Handle in HS_H
              • Custom script: call RemoveLocation(udg_HS_P)
              • Custom script: call RemoveLocation(udg_HS_P2)
            • Else - Actions
              • Hashtable - Clear all child hashtables of child HS_Handle in HS_H
              • Unit Group - Remove HS_Target from HS_Group
              • Unit - Turn collision for HS_Target On
              • Set HS_Loop = (HS_Loop - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • HS_Loop Less than or equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions


  • HS I Dps
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in HS_Group and do (Actions)
        • Loop - Actions
          • Set HS_Target = (Picked unit)
          • Custom script: set udg_HS_Handle = GetHandleId(udg_HS_Target)
          • Set HS_DDps = (Load 6 of HS_Handle from HS_H)
          • Set HS_TDps = (Load 5 of HS_Handle from HS_H)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • HS_TDps Greater than 0.00
            • Then - Actions
              • Hashtable - Save (HS_TDps - 1.00) as 5 of HS_Handle in HS_H
              • Unit - Cause HS_C to damage HS_Target, dealing HS_DDps damage of attack type Spells and damage type Normal
              • Special Effect - Create a special effect attached to the overhead of HS_Target using Abilities\Spells\Items\PotionOfOmniscience\CrystalBallCaster.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
              • Hashtable - Clear all child hashtables of child HS_Handle in HS_H
              • Unit Group - Remove HS_Target from HS_Group
 

Attachments

  • HS.w3x
    17.8 KB · Views: 40
Last edited:
Level 5
Joined
Jun 16, 2004
Messages
108
There are some pretty big things wrong with the trigger. For one I am pretty sure it only works by luck and it does not actually execute the way you expected.

Firstly notice that you do this in HS I Loop:
  • Else - Actions
    • Hashtable - Clear all child hashtables of child HS_Handle in HS_H
    • Unit Group - Remove HS_Target from HS_Group
    • Unit - Turn collision for HS_Target On
    • Set HS_Loop = (HS_Loop - 1)
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • HS_Loop Less than or equal to 0
      • Then - Actions
        • Trigger - Turn off (This trigger)
      • Else - Actions
But you also do this in HS I Dps:
  • Else - Actions
    • Hashtable - Clear all child hashtables of child HS_Handle in HS_H
    • Unit Group - Remove HS_Target from HS_Group
Notice that you are removing the unit from HS_Group in both triggers. And both triggers loop through that same group.

So now I will talk about why it only works because of luck. It is because of these four actions:
  • Actions
    • Hashtable - Save (HS_T - 0.03) as 1 of HS_Handle in HS_H
    • Set HS_Target = (Picked unit)
    • Custom script: set udg_HS_Handle = GetHandleId(udg_HS_Target)
    • Set HS_T = (Load 1 of HS_Handle from HS_H)
Notice a few things. First, you are saving the new HS_T value to HS_Handle before you change HS_Handle to the current unit. Next, you are loading HS_T from HS_Handle after changing HS_T.

So it goes something like this on the first loop:
Save .90 - .03 to HS_Handle
Change HS_Handle to current unit handle
Load .90 from new HS_Handle

So it saves .87 to the previous HS_Handle, then it loads .90 from the new HS_Handle. This results in a bug in your trigger, and yet that bug is the only reason your trigger works (mostly).

On the very first unit picked in HS I Loop, what do you think HS_Handle is set to? It is set to the last unit looped on in the HolySlam trigger, the last unit in the unit group. So on the very first iteration of your HS I Loop, you are setting HS_T of the last unit to .87. Remember that HS_T is loaded after HS_Handle is changed.

So consider this situation: you hit three units with your holy slam attack. On the first HS I Loop execution, the HS_T values for each unit will be loaded as follows:
Unit 1: .90
Unit 2: .90
Unit 3: .87

Remember that the last unit has its HS_T changed because HS_Handle is set to the last unit in the group in HolySlam, and you save HS_T to HS_Handle first before changing HS_Handle.

This is a bug and yet kind of lucky because on the last iteration, the numbers look like this:
Unit 1: .03
Unit 2: .03
Unit 3: .00

Which means because of unit 3, these actions run:
  • Else - Actions
    • Hashtable - Clear all child hashtables of child HS_Handle in HS_H
    • Unit Group - Remove HS_Target from HS_Group
    • Unit - Turn collision for HS_Target On
    • Set HS_Loop = (HS_Loop - 1)
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • HS_Loop Less than or equal to 0
      • Then - Actions
        • Trigger - Turn off (This trigger)
      • Else - Actions
HS_Loop becomes 0, turning your trigger off before the trigger can loop again.

This is a bug because all of your units in the group except for the last one miss one iteration of their knockback, which is not a big deal really, except collision will remain turned off for the rest of the units. Also, that one removed unit will not be affected by HS I Dps.

This is also lucky because it means only one of the units gets removed from HS_Group, allowing your HS I Dps trigger to run for the rest of the units.

So what happens when you cast HolySlam with no units nearby? The variable HS_Loop becomes 1 and the trigger HS I Loop turns on, that is about it. Because there are no units in HS_Group, HS I Loop does not actually do anything, but remains turned on.

Then when you cast on actual units, this is what happens: the last unit gets to .00 just like I said before, only this time, when this runs:
  • Set HS_Loop = (HS_Loop - 1)
HS_Loop does not become 0, because you had a cast before this that did not do anything, but left HS_Loop at 1. So HS_Loop was 2, but becomes 1. Keep in mind that your HS_T values look something like this at this point:
Unit 1: .03
Unit 2: .03
Unit 3: .03
...
Unit N: .00

So your HS I Loop runs again, this time giving values like this:
Unit 1: .00
Unit 2: .00
Unit 3: .00
...
Unit N: -.03

What happens when a unit's HS_T is <= .00 ?
This happens:
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • HS_T Less than or equal to 0.00
    • Then - Actions
      • Trigger - Turn on HS I Dps <gen>
    • Else - Actions
And this happens:
  • Else - Actions
    • Hashtable - Clear all child hashtables of child HS_Handle in HS_H
    • Unit Group - Remove HS_Target from HS_Group
    • Unit - Turn collision for HS_Target On
    • Set HS_Loop = (HS_Loop - 1)
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • HS_Loop Less than or equal to 0
      • Then - Actions
        • Trigger - Turn off (This trigger)
      • Else - Actions
Which means every unit is removed from HS_Group, leaving no units for HS I Dps to operate on. Also, it decrements HS_Loop N-1 times, which means HS_Loop will probably become negative.

I am not sure what your intentions for HS_Loop are, but if it is supposed to be equal to the size of the group, you should set it to the size of the group instead of to 1 in HolySlam. Next, you should remove these:
  • Hashtable - Clear all child hashtables of child HS_Handle in HS_H
    • Unit Group - Remove HS_Target from HS_Group
From your HS I Loop trigger and let HS I Dps remove them from the group instead. That might fix most of the problems, including most units missing one knockback iteration, DPS not executing when you cast HolySlam on nothing, and so on.

Your spell will not be MUI or MPI, but it already is not so.
 
Level 4
Joined
Jun 16, 2010
Messages
48
Oh , Dear Tnx A Lot ! I Never Think That One Day Some One Explain Me Like This ! Tnx A Lot . So 4 Fixing it I Should Just Remove That 2 Triggers?!
And I Think If I Change It Like This it Should be fix ( as u said i moved the time - position )
And Should I Add A Condition For my Loop To Check if There is more than one unit in the Group?!
HS I Loop

  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • ((Playable map area) contains HS_P2) Equal to True
    • Then - Actions
      • Unit - Move HS_Target instantly to HS_P2, facing HS_A degrees
    • Else - Actions
    • Special Effect - Create a special effect attached to the origin of HS_Target using Abilities\Spells\Human\SpellSteal\SpellStealMissile.mdl
    • Special Effect - Destroy (Last created special effect)
    • Hashtable - Save (HS_T - 0.03) as 1 of HS_Handle in HS_H
    • Hashtable - Save (HS_Dis x (HS_T x HS_T)) as 3 of HS_Handle in HS_H
    • Custom script: call RemoveLocation(udg_HS_P)
    • Custom script: call RemoveLocation(udg_HS_P2)
i dident get all the parts :D
I Should Add ( Can you help me make it Mui?!)
 
Last edited:
Level 5
Joined
Jun 16, 2004
Messages
108
I made some simple edits to your posted map here.

In particular, I added an array HS_Groups, changed HS_Loop to be an array which holds the current number of units in each group, and made the triggers loop through each of the HS_Groups. I also added two variables HS_Size and HS_DoneSize, which hold the current number of HS_Groups there are and the number that are finished looping. When HS_Size == HS_DoneSize they are both set to 0 and it cleans up the HS_Groups.

This sort of solution is sort of multi-unit instanceable, except due to the way you use the hashtables you cannot stack the effects of more than one HolySlam on one target (one target cannot have two active knockbacks / two active dots, for example).

If you want to be able to stack knockbacks / dots, you would need to change how you use hashtables. Instead of storing multiple values to one unit like you have been doing, you would instead need to store only one value to the unit, which would be an index into a bunch of arrays that store the values you want. Each index would have to be unique to the unit, though, so you would have to keep track of what indices are free somehow. Alternatively, you can have one new hashtable per instance of your spell, but this is not recommended.

It can get sort of messy in GUI.
 

Attachments

  • HS.w3x
    19 KB · Views: 49
Status
Not open for further replies.
Top