• 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] Saving locations in hashtables!

Status
Not open for further replies.
Level 7
Joined
Jul 9, 2012
Messages
159
Hello again!
I have just started working with hashtables and everything works fine except one thing.
I'm trying to make a trigger where a unit will spawn every 30 seconds. Its spawning location will then be saved in a hashtable. Later on, if the unit casts a chain lightning ability at a target, it will be teleported to its initial spawning point and will then start dragging the targeted unit towards it.

Everything works fine in my trigger except the location where it spawned isn't stored into the hashtable, and it then moves to the center of the map instead.

Here are the triggers:
  • Initial Variables
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Anubarak = Lord of Azjol-Nerub 0001 <gen>
      • Set PoisonCloudRegion[1] = Poison Cloud 1 <gen>
      • Set PoisonCloudRegion[2] = Poison Cloud 2 <gen>
      • Hashtable - Create a hashtable
      • Set DiseaseBringerHash = (Last created hashtable)
  • Disease Bringer Spawn
    • Events
      • Time - Every 30.00 seconds of game time
    • Conditions
    • Actions
      • Set DiseaseBringerPoint = (Center of PoisonCloudRegion[(Random integer number between 1 and 2)])
      • Set CallOfThePlagueCasterPoint = DiseaseBringerPoint
      • Unit - Create 1 Disease Bringer for Player 12 (Brown) at DiseaseBringerPoint facing Default building facing degrees
      • Hashtable - Save Handle OfCallOfThePlagueCasterPoint as (Key (Last created unit)) of 1 in DiseaseBringerHash
      • Custom script: call RemoveLocation(udg_DiseaseBringerPoint)
      • Custom script: call RemoveLocation(udg_CallOfThePlagueCasterPoint)
  • Call of the Plague
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Call of the Plague
    • Actions
      • Set CallOfThePlagueCaster = (Triggering unit)
      • Set CallOfThePlagueTarget = (Target unit of ability being cast)
      • Hashtable - Save Handle OfCallOfThePlagueTarget as (Key (Triggering unit)) of 2 in DiseaseBringerHash
      • Set CallOfThePlagueTargetPoint = (Position of CallOfThePlagueTarget)
      • Set CallOfThePlagueCasterPoint = (Load (Key (Triggering unit)) of 1 in DiseaseBringerHash)
      • Custom script: call SetUnitX(udg_CallOfThePlagueCaster,GetLocationX(udg_CallOfThePlagueCasterPoint))
      • Custom script: call SetUnitY(udg_CallOfThePlagueCaster,GetLocationY(udg_CallOfThePlagueCasterPoint))
      • Lightning - Create a Drain Life lightning effect from source CallOfThePlagueCasterPoint to target CallOfThePlagueTargetPoint
      • Set CallOfThePlagueLightning = (Last created lightning effect)
      • Hashtable - Save Handle OfCallOfThePlagueLightning as (Key (Triggering unit)) of 3 in DiseaseBringerHash
      • Unit - Make CallOfThePlagueCaster face CallOfThePlagueTarget over 0.00 seconds
      • Unit - Pause CallOfThePlagueCaster
      • Special Effect - Create a special effect attached to the head of CallOfThePlagueTarget using Abilities\Spells\Undead\AntiMagicShell\AntiMagicShell.mdl
      • Set CallOfThePlagueEffect = (Last created special effect)
      • Hashtable - Save Handle OfCallOfThePlagueEffect as (Key (Triggering unit)) of 4 in DiseaseBringerHash
      • Custom script: call RemoveLocation(udg_CallOfThePlagueCasterPoint)
      • Custom script: call RemoveLocation(udg_CallOfThePlagueTargetPoint)
      • Unit Group - Add CallOfThePlagueCaster to CallOfThePlagueUG
      • Trigger - Turn on Call of the Plague Loop <gen>
  • Call of the Plague Loop
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in CallOfThePlagueUG) Greater than 0
        • Then - Actions
          • Unit Group - Pick every unit in CallOfThePlagueUG and do (Actions)
            • Loop - Actions
              • Set CallOfThePlagueCaster = (Picked unit)
              • Set CallOfThePlagueLightning = (Load (Key (Picked unit)) of 3 in DiseaseBringerHash)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (CallOfThePlagueCaster is alive) Equal to True
                • Then - Actions
                  • Set CallOfThePlagueTarget = (Load (Key (Picked unit)) of 2 in DiseaseBringerHash)
                  • Set CallOfThePlagueCasterPoint = (Load (Key (Triggering unit)) of 1 in DiseaseBringerHash)
                  • Set CallOfThePlagueTargetPoint = (Position of CallOfThePlagueTarget)
                  • Set CallOfThePlagueTargetMovePoint = (CallOfThePlagueTargetPoint offset by 8.00 towards (Angle from CallOfThePlagueTargetPoint to CallOfThePlagueCasterPoint) degrees)
                  • Lightning - Move CallOfThePlagueLightning to source CallOfThePlagueTargetMovePoint and target CallOfThePlagueCasterPoint
                  • Custom script: call SetUnitX(udg_CallOfThePlagueTarget,GetLocationX(udg_CallOfThePlagueTargetMovePoint))
                  • Custom script: call SetUnitY(udg_CallOfThePlagueTarget,GetLocationY(udg_CallOfThePlagueTargetMovePoint))
                  • Custom script: call RemoveLocation(udg_CallOfThePlagueCasterPoint)
                  • Custom script: call RemoveLocation(udg_CallOfThePlagueTargetPoint)
                  • Custom script: call RemoveLocation(udg_CallOfThePlagueTargetMovePoint)
                • Else - Actions
                  • Unit Group - Remove CallOfThePlagueCaster from CallOfThePlagueUG
                  • Lightning - Destroy CallOfThePlagueLightning
                  • Set CallOfThePlagueEffect = (Load (Key (Picked unit)) of 4 in DiseaseBringerHash)
                  • Special Effect - Destroy CallOfThePlagueEffect
        • Else - Actions
          • Trigger - Turn off (This trigger)
Thank you!
 
Last edited:
Level 5
Joined
May 6, 2013
Messages
125
  • Disease Bringer Spawn
    • Events
      • Time - Every 30.00 seconds of game time
    • Conditions
    • Actions
      • Set DiseaseBringerPoint = (Center of PoisonCloudRegion[(Random integer number between 1 and 2)])
      • Set CallOfThePlagueCasterPoint = DiseaseBringerPoint
      • Unit - Create 1 Disease Bringer for Player 12 (Brown) at DiseaseBringerPoint facing Default building facing degrees
      • Hashtable - Save Handle OfCallOfThePlagueCasterPoint as (Key (Last created unit)) of 1 in DiseaseBringerHash
      • Custom script: call RemoveLocation(udg_DiseaseBringerPoint)
      • Custom script: call RemoveLocation(udg_CallOfThePlagueCasterPoint)
I'm surprised that this trigger didn't crash the game (certainly would have been a better outcome, bugfindwise). DiseaseBringerPoint and CallOfThePlagueCasterPoint contain a handle to the exact same location and are therefor removed twice, which is a bug in itself. Your problem, however, is, that the hashtable contains a handle to that removed point, so when you load it up and use it, warcraft sees that it has allready been destroyed, and uses the default location (0,0) instead.

Also, on a more general note, remember to flush your hashtables to prevent leak and, more importantly, degeneration of your hashtable. Or, in your case, you cant just flush the entire table, so you should use the RemoveSavedHandle function.
 
Level 7
Joined
Jul 9, 2012
Messages
159
Thank you for the reply!
Sorry for the late response; was very busy + it took me a while to fully understand your reply - as I said, just started working with it and I find it damn confusing.. :p + rep!

Can't find the RemoveSavedHandle anywhere within the trigger menues. Is it a custom script, and how do I use it then? :)
 
Level 7
Joined
Jul 9, 2012
Messages
159
Thank you very much for the tip - I love the help from the society of Hive! :)

I'm getting closer, but it still doesn't work well, and I can't find my mistakes.
The casting unit is moved to the stored location in "Call of the Plague Cast", which is nice. But the targeted unit and the lightning in "Call of the Plague Loop" is still dragged towards (0,0).

So here come all the triggers again (sorry for that):
  • Disease Bringer Spawn
    • Events
      • Time - Every 30.00 seconds of game time
    • Conditions
    • Actions
      • Set DiseaseBringerPoint = (Center of PoisonCloudRegion[(Random integer number between 1 and 2)])
      • Unit - Create 1 Disease Bringer for Player 12 (Brown) at DiseaseBringerPoint facing Default building facing degrees
      • Hashtable - Save Handle OfDiseaseBringerPoint as (Key (Last created unit)) of 1 in DiseaseBringerHash
  • Call of the Plague Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Call of the Plague
    • Actions
      • Set CallOfThePlagueCaster = (Triggering unit)
      • Set CallOfThePlagueTarget = (Target unit of ability being cast)
      • Hashtable - Save Handle OfCallOfThePlagueTarget as (Key (Triggering unit)) of 2 in DiseaseBringerHash
      • Set CallOfThePlagueTargetPoint = (Position of CallOfThePlagueTarget)
      • Set CallOfThePlaguePoint = (Load (Key (Triggering unit)) of 1 in DiseaseBringerHash)
      • Custom script: call SetUnitX(udg_CallOfThePlagueCaster,GetLocationX(udg_CallOfThePlaguePoint))
      • Custom script: call SetUnitY(udg_CallOfThePlagueCaster,GetLocationY(udg_CallOfThePlaguePoint))
      • Lightning - Create a Drain Life lightning effect from source CallOfThePlaguePoint to target CallOfThePlagueTargetPoint
      • Set CallOfThePlagueLightning = (Last created lightning effect)
      • Hashtable - Save Handle OfCallOfThePlagueLightning as (Key (Triggering unit)) of 3 in DiseaseBringerHash
      • Unit - Make CallOfThePlagueCaster face CallOfThePlagueTarget over 0.00 seconds
      • Unit - Pause CallOfThePlagueCaster
      • Special Effect - Create a special effect attached to the head of CallOfThePlagueTarget using Abilities\Spells\Undead\AntiMagicShell\AntiMagicShell.mdl
      • Set CallOfThePlagueEffect = (Last created special effect)
      • Hashtable - Save Handle OfCallOfThePlagueEffect as (Key (Triggering unit)) of 4 in DiseaseBringerHash
      • Custom script: call RemoveLocation(udg_CallOfThePlagueTargetPoint)
      • Custom script: call RemoveLocation(udg_CallOfThePlaguePoint)
      • Unit Group - Add CallOfThePlagueCaster to CallOfThePlagueUG
      • Trigger - Turn on Call of the Plague Loop <gen>
The problem occurs in this trigger... I think?
  • Call of the Plague Loop
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in CallOfThePlagueUG) Greater than 0
        • Then - Actions
          • Unit Group - Pick every unit in CallOfThePlagueUG and do (Actions)
            • Loop - Actions
              • Set CallOfThePlagueCaster = (Picked unit)
              • Set CallOfThePlagueLightning = (Load (Key (Picked unit)) of 3 in DiseaseBringerHash)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (CallOfThePlagueCaster is alive) Equal to True
                • Then - Actions
                  • Set CallOfThePlaguePoint = (Load (Key (Picked unit)) of 1 in DiseaseBringerHash)
                  • Set CallOfThePlagueTarget = (Load (Key (Picked unit)) of 2 in DiseaseBringerHash)
                  • Set CallOfThePlagueTargetPoint = (Position of CallOfThePlagueTarget)
                  • Set CallOfThePlagueTargetMovePoint = (CallOfThePlagueTargetPoint offset by 8.00 towards (Angle from CallOfThePlagueTargetPoint to CallOfThePlaguePoint) degrees)
                  • Lightning - Move CallOfThePlagueLightning to source CallOfThePlagueTargetMovePoint and target CallOfThePlaguePoint
                  • Custom script: call SetUnitX(udg_CallOfThePlagueTarget,GetLocationX(udg_CallOfThePlagueTargetMovePoint))
                  • Custom script: call SetUnitY(udg_CallOfThePlagueTarget,GetLocationY(udg_CallOfThePlagueTargetMovePoint))
                  • Custom script: call RemoveLocation(udg_CallOfThePlaguePoint)
                  • Custom script: call RemoveLocation(udg_CallOfThePlagueTargetPoint)
                  • Custom script: call RemoveLocation(udg_CallOfThePlagueTargetMovePoint)
                • Else - Actions
                  • Unit Group - Remove CallOfThePlagueCaster from CallOfThePlagueUG
                  • Lightning - Destroy CallOfThePlagueLightning
                  • Set CallOfThePlagueEffect = (Load (Key (Picked unit)) of 4 in DiseaseBringerHash)
                  • Special Effect - Destroy CallOfThePlagueEffect
                  • For each (Integer CallOfThePlagueIndex) from 1 to 4, do (Actions)
                    • Loop - Actions
                      • Custom script: call RemoveSavedHandle(udg_DiseaseBringerHash, GetHandleId(udg_CallOfThePlagueCaster), udg_CallOfThePlagueIndex)
        • Else - Actions
          • Trigger - Turn off (This trigger)
Thank you!
 
Last edited:
Level 5
Joined
May 6, 2013
Messages
125
  • Call of the Plague Loop
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • [...]
        • Set CallOfThePlaguePoint = (Load (Key (Picked unit)) of 1 in DiseaseBringerHash) //<--- load the point handle from the table
        • Set CallOfThePlagueTarget = (Load (Key (Picked unit)) of 2 in DiseaseBringerHash)
        • Set CallOfThePlagueTargetPoint = (Position of CallOfThePlagueTarget)
        • Set CallOfThePlagueTargetMovePoint = (CallOfThePlagueTargetPoint offset by 8.00 towards (Angle from CallOfThePlagueTargetPoint to CallOfThePlaguePoint) degrees)
        • Lightning - Move CallOfThePlagueLightning to source CallOfThePlagueTargetMovePoint and target CallOfThePlaguePoint
        • Custom script: call SetUnitX(udg_CallOfThePlagueTarget,GetLocationX(udg_CallOfThePlagueTargetMovePoint))
        • Custom script: call SetUnitY(udg_CallOfThePlagueTarget,GetLocationY(udg_CallOfThePlagueTargetMovePoint))
        • Custom script: call RemoveLocation(udg_CallOfThePlaguePoint) //<-- destroy this point
        • Custom script: call RemoveLocation(udg_CallOfThePlagueTargetPoint)
        • Custom script: call RemoveLocation(udg_CallOfThePlagueTargetMovePoint)
You destroy the location after you first used it, thus every subsequent execution will use a destroyed location (and default to 0,0). You need to destroy it only after you dont have to use it anymore (which would be where you put the unit out of the group and do the other cleanup).

Also, i think the parameters from the RemoveSavedHandle custom script are inverted compared to the GUI insert actions, like this
  • Hashtable - Save Handle Of DiseaseBringerPoint as (Key (Last created unit)) of 1 in DiseaseBringerHash
  • Custom script: call RemoveSavedHandle(udg_DiseaseBringerHash, 1, GetHandleId(GetLastCreatedUnitBJ())
 
Status
Not open for further replies.
Top