• 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.

Hashtables Help

Level 6
Joined
Feb 22, 2025
Messages
82
Long time no see, um trying to create a damage event that happens 1 sec after you call down the infernal ability, tried storing the caster and target point of ability being cast into hashtable but can't achieve the goal, I just started to understand hashtables, might need some guide, ty!
--------------------------------------------------------------------------------
  • Inferno Hash
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set Inferno_Hash = (Last created hashtable)
  • CastInferno
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Inferno (Item)
    • Actions
      • Set Inferno_Caster = (Triggering unit)
      • Set Inferno_AOE = 300.00
      • Set Inferno_DMG = 400.00
      • Set Inferno_Target = (Target point of ability being cast)
      • Set Inferno_Caster = Inferno_TempCaster
      • Hashtable - Save Handle OfInferno_Caster as 1 of (Key Inferno_TempCaster.) in Inferno_Hash.
      • Hashtable - Save Handle OfInferno_Target as 2 of (Key Inferno_TempCaster.) in Inferno_Hash.
      • Custom script: call RemoveLocation( udg_Inferno_Target)
      • Wait 1.00 game-time seconds
      • Trigger - Run InfernoDmg <gen> (ignoring conditions)
  • InfernoDmg
    • Events
    • Conditions
    • Actions
      • Set Inferno_Caster = (Load 1 of (Key Inferno_TempCaster.) in HashTable.)
      • Set Inferno_Target = (Load 2 of (Key Inferno_TempCaster.) in HashTable.)
      • Set Inferno_Group = (Units within Inferno_AOE of Inferno_Target matching (((((Matching unit) is alive) Equal to True) and (((Matching unit) is hidden) Equal to False)) and (((Matching unit) belongs to an enemy of (Owner of Inferno_Caster).) Equal to True)).)
      • Unit Group - Pick every unit in Inferno_Group and do (Actions)
        • Loop - Actions
          • Unit - Cause Inferno_Caster to damage (Picked unit), dealing Inferno_DMG damage of attack type Spells and damage type Normal
      • Custom script: call RemoveLocation( udg_Inferno_Target)
      • Custom script: call DestroyGroup( udg_Inferno_Group)
      • Hashtable - Clear all child hashtables of child (Key (Triggering unit).) in Inferno_Hash.
  • InfernoItem Cast
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Entering unit)) Equal to InfernoRemove
    • Actions
      • Unit - Remove (Entering unit) from the game
 

Chaosy

Tutorial Reviewer
Level 41
Joined
Jun 9, 2011
Messages
13,242
I mean you can start by saying what doesn't work, not that it doesn't work.

Using waits somewhat infamously fucks things up so start by removing that and see what happens in comparison.

InfernoRemove is not referenced anywhere so that seems like an odd trigger to include.

As I finished typing this post I noticed that you're using two different hashtables.
In infernodmg you use HashTable. instead of Inferno_Hash but it kinda looks like a typo
 
Level 7
Joined
Jun 30, 2017
Messages
52
Hi, the reason why this particular case doesn't work is likely because of the following action inside CastInferno trigger:
  • Set Inferno_Caster = Inferno_TempCaster
it should be
  • Set Inferno_TempCaster = Inferno_Caster
Additionally, calling the following RemoveLocation will make that target point no longer available for the next trigger.
 
Level 6
Joined
Feb 22, 2025
Messages
82
Hi, the reason why this particular case doesn't work is likely because of the following action inside CastInferno trigger:
  • Set Inferno_Caster = Inferno_TempCaster
it should be
  • Set Inferno_TempCaster = Inferno_Caster
Additionally, calling the following RemoveLocation will make that target point no longer available for the next trigger.
I see, so removing the location will delete it, I thought that storing it into a hashtable would save it in the hash so i could do the cleanup right on the spot, ty, I'll try with the changes made
 
Level 7
Joined
Jun 30, 2017
Messages
52
Fixing those issues shouldn't be the end-goal tho, as you should strive to replace that wait action, with a periodic timed event on the second trigger.
Second trigger, with that timer event should also loop through a group of active caster units (you can fill in that group with your first trigger), and then do the actions after their delay is finished.

Here's a tutorial on something similar (it doesn't use hashtables, but relies on unit indexing instead) Visualize: Dynamic Indexing

Edit: If it's an ability that multiple units can cast at the same time, that is. Otherwise this spell would suffer similar issues that Dynamic Indexing fixes.
 
Level 6
Joined
Feb 22, 2025
Messages
82
I mean you can start by saying what doesn't work, not that it doesn't work.

Using waits somewhat infamously fucks things up so start by removing that and see what happens in comparison.

InfernoRemove is not referenced anywhere so that seems like an odd trigger to include.

As I finished typing this post I noticed that you're using two different hashtables.
In infernodmg you use HashTable. instead of Inferno_Hash but it kinda looks like a typo
It wasn't a typo I was referencing a wrong hashtable and didn't notice it :goblin_boom: It's working now, anyways yeah i hate dem waits butI need that1 sec until meteor lands to apply damage, the remove trigger is cuz I'm using infernal item ability and cannot set the summoned unit to none, I just wanted the effect without making a new ability
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,916
That trigger is still going to have problems. Try to ditch Waits entirely for custom spells, there's just too many issues involved.

Instead, rely on what Insanity said about using Dynamic Indexing, especially for a spell like this.

No Hashtables needed, and you're actually almost there already. You just need to turn all of your current Variables into Arrays (minus Inferno_Group) and follow the instructions in that link. You'll need to create some new Variables as well, like a Loop and Index integer as well a Real array to track how much time has elapsed (see Inferno_Duration in my example below).

Here's a portion of what your Loop trigger could look like:
  • Events
    • Time - Every 0.02 seconds of game time
  • Conditions
  • Actions
    • For each Integer (Inferno_Loop) from 1 to Inferno_Index do (Actions)
      • Loop - Actions
        • Set Inferno_Duration[Inferno_Loop] = (Inferno_Duration[Inferno_Loop] - 0.02)
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • Inferno_Duration[Inferno_Loop] Less than or equal to 0.01
          • Then - Actions
            • Set Inferno_Group = (Units within Inferno_AOE[Inferno_Loop] of Inferno_Target[Inferno_Loop] matching (((((Matching unit) is alive) Equal to True) and (((Matching unit) is hidden) Equal to False)) and (((Matching unit) belongs to an enemy of (Owner of Inferno_Caster[Inferno_Loop]).) Equal to True)).)
            • Unit Group - Pick every unit in Inferno_Group and do (Actions)
              • Loop - Actions
                • Unit - Cause Inferno_Caster[Inferno_Loop] to damage (Picked unit), dealing Inferno_DMG[Inferno_Loop] damage of attack type Spells and damage type Normal
            • -------- Proceed to clean up and removing this instance from the loop --------
This loops over every active instance of the spell, with different [indexes] representing different instances. Inferno_Duration[] would be Set to 1.00 second in your Cast trigger, this variable replaces your "Wait 1.00 second". We're subtracting 0.02 from it every 0.02 seconds, then checking to see if it's finally reached 0.00. We know that reaching 0.00 means 1.00 second of time has passed and we can now deal damage and end the instance.

With this design you could constantly spam the spell on 100's of different units and everything will continue to work as intended.
 
Last edited:
Top