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

Hashtables?

Status
Not open for further replies.
Level 4
Joined
Jan 28, 2013
Messages
94
I'm just starting with Hastables but I feel like I could use some help. As it is I can't make heads nor tail over it. I have read tutorials on here so I'm getting some grasp over it. However the tutorials are based around spells and uses real variables. I wonder if Hastables can store unit information? I found the Unit handle but I'm not sure what that does... The tutorials on here seem to mostly use real variables and global variables like Picked Unit...

Also, can you use Hastables for other things than spells?

How does these Handles and Key Handles work? I saw Handles like Questitem and Multiboard but I'm not sure how to use Hastable in conjugation with those actions.

There doesn't seem to be a Load function like the Game Cache Restore function... How do I load something like property or units from Hastables?
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
Instead of ANOTHER tutorial I would give you, I would give you the information directly and try to keep it short and simple.

Hashtable uses 2D array which consists of childKey and parentKey.
Something[parentKey][childKey] = "Bla Bla"

This is an example to store String variable to a unit casting a spell;
  • Hashtable Setup
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set Hashtable = (Last created hashtable)
  • Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
    • Actions
      • Set Caster = (Triggering unit)
      • Set String = (Name of (Ability being cast))
      • Custom script: set udg_parentKey = GetHandleId(udg_Caster)
      • Hashtable - Save String as 0 of parentKey in Hashtable
      • Set String = (Load 0 of parentKey from Hashtable)
      • Game - Display to (All players) the text: String
This trigger will save String variable (Ability Name) to a (Triggering unit) and will be loaded and shown as Game Message.

As you can see;
  • Custom script: set udg_parentKey = GetHandleId(udg_Caster)
The parentKey is set to GetHandleId(udg_Caster), this means that parentKey is set to the Caster, meaning that any data shall be saved to the Caster (Triggering unit).

As you notice this line;
  • Hashtable - Save String as 0 of parentKey in Hashtable
Save Something as childKey of parentKey in Hashtable

For childKey, you can put any integer you want (recommended to start at 0 and increment by 1 per each data saved to a handle).

For instance, if you want to save 3 data to a single handle, you would do this
  • Hashtable - Save String as 0 of parentKey in Hashtable
  • Hashtable - Save Integer as 1 of parentKey in Hashtable
  • Hashtable - Save Real as 2 of parentKey in Hashtable
This is what it looks like;
Data[0][0] = String
Data[0][1] = Integer
Data[0][2] = Real

What if you save all 3 data to the same childKey ?
It will overwrite the previous saved data, meaning that it will only save Real because Integer overwrites String, and Real overwrites Integer for the last saved.

Above is to save data to an exist handle in the map, but what if you want to save data to a non-exist handle in the map yet ?
What if you want to save an Integer with value '100' to a Unit-type Paladin ?
You can't refer it to (Triggering unit) any longer because this requires an exist handle in the map first, right ?

So here's what you would do;
  • Hashtable Setup
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set Hashtable = (Last created hashtable)
      • -------- ////////// --------
      • -------- Save Integer value of 100 to Paladin --------
      • -------- ////////// --------
      • -------- Set values --------
      • Set UnitType = Paladin
      • Custom script: set udg_parentKey = udg_UnitType
      • Set Integer = 100
      • Hashtable - Save Integer as 0 of parentKey in Hashtable
  • Enter Map
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Paladin
    • Actions
      • Set Unit = (Triggering unit)
      • Custom script: set udg_parentKey = GetUnitTypeId(udg_Unit)
      • Set String = (String((Load 0 of parentKey from Hashtable)))
      • Game - Display to (All players) the text: String
As you can see;
  • Custom script: set udg_parentKey = udg_UnitType
I no longer use GetHandleId(unit) because that is to reference an existing unit, while this function will refer to the Unit-type itself and as you can see, parentKey is in Integer and it is set to Unit-type, how can it be set to different data type ?

The Unit-type is converted into Integer such as 'h000' and 'hpea' and such.

Then;
  • Custom script: set udg_parentKey = GetUnitTypeId(udg_Unit)
This time, I used GetUnitTypeId(unit) because the saved data is saved to a Unit-type, not the Unit itself, that is why I used that function to refer to the Unit-type of the Unit (Triggering unit)

And as usual, I load the value by using 0 as childKey and wala !
100 is found and can be used (retrieved from the Unit-type of the Unit - saved via Setup trigger in map init).
 
Level 4
Joined
Jan 28, 2013
Messages
94
try this and this, both will help you.

Thanks but I've already read those and it helped me a little to understand it but it did not answer my questions.

@defskull
Thank you for explaining. I'm not sure I understand fully but it helps a bit. I'll have to think it over and maybe test it and perhaps learn something. If I got any more questions I'll get back to you.

So if I want to add a unit to Hastable I have to set it as a variable? Then somehow add it to the Hashtable? I'm not sure I understand that Custom Script... what does ParentKey mean? I have only taken a look so far at the GUI action Set handle of Unit as Value of Value in Hashtable.
So there are no Hashtable function like "Restore Unit from Category in Cache with facing..." ? I'll only be able to load unit and set them as variables?

I'm still not sure about these handles and keyhandles... are those related to parentKey and childKey?
 
Level 9
Joined
Apr 23, 2011
Messages
460
I understood hashtables very easily because of my work with wow lua, specifically the for loop.

The for loop in WoW Lua uses the syntax:
Code:
for k, v in pairs(pairs) do
end

I learned this as such, when dealing with the values, k is the key value, or pointer to the reference v, or value. It's best to play with this yourself and discover other applications towards it. Personally I believe in learning fundamentals and practicing concepts, but to each his own.
 

TKF

TKF

Level 19
Joined
Nov 29, 2006
Messages
1,266
I can show you an example

  • Set MissileUnitType[13] = Devastator Proximity Mine (Space)
  • Set ArmedMissileType[13] = Devastator Proximity Mine (Armed)
  • Set AbilityTypeFire[13] = Release Devastator Proximity Mine
  • Set ItemMissileType[13] = |cff0852A5Devastator Proximity Mine
  • Custom script: set udg_Temp_Integer = 'h02E'
  • Custom script: set udg_Temp_Integer2 = 'A02K'
  • Hashtable - Save 37.00 as 0 of Temp_Integer in HashDamageData
  • Hashtable - Save 5.00 as 1 of Temp_Integer in HashDamageData
  • Hashtable - Save 2400.00 as 7 of Temp_Integer in HashDamageData
  • Hashtable - Save 1800.00 as 8 of Temp_Integer in HashDamageData
  • Hashtable - Save 13 as 0 of Temp_Integer2 in HashDamageData
  • Hashtable - Save 1800.00 as 1 of Temp_Integer2 in HashDamageData
  • Hashtable - Save True as 2 of Temp_Integer2 in HashDamageData
In my map I store things like hull and shield damage, real damage and duration of weapon.

I use first value to store the value, and 2nd as 0, 1, 2, 3 etc. This allows you to store multiple values on an integer/unit handle.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
What if you save all 3 data to the same childKey ?
It will overwrite the previous saved data, meaning that it will only save Real because Integer overwrites String, and Real overwrites Integer for the last saved.

No, only data of the same type will overwrite. Integers won't overwrite reals, reals won't overwrite strings and so on. Unit will overwrite special effect for example, since they are both handle types.
 
Level 4
Joined
Jan 28, 2013
Messages
94
Tell me, what are you trying to achieve ?
Or do you want to start with a simple thing first ?
Always apply/practice what you have learnt, it helps, a lot.
I don't know what I want to archive... I just want to learn how this Hastable function works. All the variables, handles, saving/loading confuses me.

I thought that maybe I could use Hastable to store a unit temporary, like Game Cache. I got a mount spell where I want to save the mounting unit, replace it with a mounted unit and then restore the original unit, keeping abilities, spells, experience, stats etc. It didn't work properly with only Game Cache so i thought that maybe Hastable is better.

I also thought that maybe I could use Hastables to store unit for a transformation spell. The unit transforms itself to a bear, like a druid, and can then transform back. But it has to work as a Hero ability so the standard Druid of the Claw spell won't work. I'm helping a friend with making a map and he needs that spell but I don't know how to trigger it properly.

I could use some help with understanding the handle functions in the Hastable and the Save VAR as VALUE of VALUE in HASHTABLE. And the Store handle of UNIT as VALUE of VALUE in HASTABLE.
I also don't understand these parentKey/childKey functions someone mentioned.
Or what happens when I store VAR as 1 of (Picked Unit) in HASTABLE. Where does Picked Unit come from? How is that acess when I stored it under something else before?
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
I just want to learn how this Hastable function works. All the variables, handles, saving/loading confuses me.
Defskull's post does exactly this I believe?
Yeah, it may be long and terrifying, but what else do you want?
The best way to learn stuff is to experiment. Go ahead and open the editor, try messing with the hashtables, see what it does.

Most of the time, you can just look at them as variables with a 2D (2-dimensional) array.
If you understand how variables with an array work, then you'll surely understand hashtables too.
After all, Var[0] and Var[0][0] do look alike :D (

I thought that maybe I could use Hastable to store a unit temporary, like [...]
No.
Well, yes. You can. But it's not good.
Hashtables are slow. Don't use hashtables for something you can use a regular variable for.
Besides, I always have "Temp"-variables in my map: no need to create new variables for those things you've mentioned.

Hashtables shine when their large 2D-arrays are put to the test (the array index can go up to 231-1 I believe, in comparison to the lousy 213-1 for regular arrays).
This is extremely useful for Raw/Handle Id's: those values are usually a lot higher than the 8191-limit for regular arrays.
So with these hashtables, you can store any value directly for a unit (that is: the value is directly linked with the ID of the unit). That's an O(1) lookup complexity.

Making them save some value that doesn't even really need those arrays is a waste of time.
I also don't understand these parentKey/childKey functions someone mentioned.
It's a bit like Folders on your PC: the folders are the parents, whereas the files are the children. If you delete the folder, then all files inside it will be gone.
Same rules apply here: something you want to save is always saved inside a file (child), this file is always saved inside a folder (parent).
The parent contains all the children, so if the parent is removed, all children inside it will be removed as well.

In GUI, the child comes first and then the parent.

Here's an example:
  • Hashtable - Save Handle of MyUnit as 0 of 1 in Hashtable
  • Hashtable - Save True as 1 of 1 in Hashtable
  • Hashtable - Save 16 as 2 of 1 in Hashtable
  • Hashtable - Save 3.14 as 1 of 0 in Hashtable
You store "MyUnit", "True" and "16" in Parent 1, but they're all saved in different children.
"3.14" is saved in a different Parent (0).

Now if you use "Clear Child Hashtable" and clear all children of the parent 1, then "MyUnit", "True" and "16" will all be removed from the hashtable.
"3.14" will still exist, because it has a different parent (0).

I really can't explain it any more basic than that :(.
 
Level 4
Joined
Jan 28, 2013
Messages
94
Defskull does explain variables (string & integer) and saving/loading Hastable and I appreciate that. But the thing is the handles aren't explained like Questitem handle, Unit handle, Multiboard handle, key Handle function. But I guess I'll have to learn them myself...
I have never used arrays... only Set Variable = Something

Oh OK thanks. So for my spell... I need another trigger function?

Thanks for explaining parentKey/childKey! I didn't understand it at first but now I do.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
I have never used arrays... only Set Variable = Something
Oh, in that case: learn about arrays first.
They're really useful, and you'll notice that you use them for all kinds of stuff once you get the hang of it (do note that it's better to create regular variables if no array is needed).

Create some kind of simple list first, something like this:
  • Set UnitType[1] = Footman
  • Set String[1] = "footman"
  • Set UnitType[2] = Peasant
  • Set String[2] = "peasant"
  • (and so on, until you're satisfied)
Then create a trigger that creates a unit of type "UnitType" whenever one of those strings is typed by a player.
It's a redundant system, but it seems like a nice thing to create :p.

Or if you can think of anything else where you have to link 2 or more values, then you can try that.
One example would be a TD: you can link the unit-type that gets spawned with the wave by simply using an array (e.g.: UnitType[4] would be the unit-type that gets spawned at Wave 4 of the TD)

Hashtables are one step above arrays in my book.
 
Status
Not open for further replies.
Top