Hashtable Tutorial?

Status
Not open for further replies.
Level 8
Joined
Mar 26, 2009
Messages
301
Is there any good Hashtable tutorial for a total Hashtable noob? I tried this one but it seems a little unclear to me. I don't understand all those fields "Save blah-blah of blah in blah" things. =)
My goal is to create MUI knockback, leap spell and from what I understand; it is possible to make them via hashtables. =) Or if there is other ways to make MUI leap, slide, knockback etc without the aid of hashtables (and Jass - excluding custom scripts) I am open for suggestions =)
 
Level 8
Joined
Mar 26, 2009
Messages
301
I've tried something out. Looks ok for now. But there might be bugs I haven't encounterd yet, or leaks. If someone with experience (and time) can check my triggers and spot the problems, I would be most grateful.
  • Shackles Index
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Shackles_Current_Index = 0
  • Shackles Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Shackle and Drag
    • Actions
      • Set Shackles_Caster[Shackles_Current_Index] = (Triggering unit)
      • Set Shackles_Dragged_Unit[Shackles_Current_Index] = (Target unit of ability being cast)
      • Set LOC_TEMP_Shackles_Caster = (Position of Shackles_Caster[Shackles_Current_Index])
      • Set LOC_TEMP_Shackles_Dragged_Unit = (Position of Shackles_Dragged_Unit[Shackles_Current_Index])
      • Set Shackles_Drag_Angle[Shackles_Current_Index] = (Angle from LOC_TEMP_Shackles_Dragged_Unit to LOC_TEMP_Shackles_Caster)
      • Custom script: call RemoveLocation (udg_LOC_TEMP_Shackles_Caster)
      • Custom script: call RemoveLocation (udg_LOC_TEMP_Shackles_Dragged_Unit)
      • Set Shackles_Current_Index = (Shackles_Current_Index + 1)
      • If (Shackles_Current_Index Equal to 50) then do (Set Shackles_Current_Index = 0) else do (Do nothing)
      • Unit - Turn collision for Shackles_Dragged_Unit[Shackles_Current_Index] Off
      • Sound - Play HeroDreadlordWarcry1 <gen>
  • Shackles Unit Movement
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 0 to 30, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (Shackles_Dragged_Unit[(Integer A)] has buff Shackles ) Not equal to True
            • Then - Actions
              • Set Shackles_Dragged_Unit[(Integer A)] = No unit
              • Set Shackles_Caster[(Integer A)] = No unit
            • Else - Actions
              • Set LOC_TEMP_Shackles_Drag_Process = (Position of Shackles_Dragged_Unit[(Integer A)])
              • Unit - Move Shackles_Dragged_Unit[(Integer A)] instantly to (LOC_TEMP_Shackles_Drag_Process offset by 5.00 towards Shackles_Drag_Angle[(Integer A)] degrees)
              • Cinematic - Ping minimap for (All players) at LOC_TEMP_Shackles_Drag_Process for 1.00 seconds, using a Simple ping of color (62.00%, 12.00%, 94.00%)
              • Custom script: call RemoveLocation (udg_LOC_TEMP_Shackles_Drag_Process)
              • Set LOC_TEMP_Shackles_Caster = (Position of Shackles_Caster[(Integer A)])
              • Set LOC_TEMP_Shackles_Dragged_Unit = (Position of Shackles_Dragged_Unit[(Integer A)])
              • Set REAL_Distance_Shackles_C_D[(Integer A)] = (Distance between LOC_TEMP_Shackles_Caster and LOC_TEMP_Shackles_Dragged_Unit)
              • Custom script: call RemoveLocation (udg_LOC_TEMP_Shackles_Caster)
              • Custom script: call RemoveLocation (udg_LOC_TEMP_Shackles_Dragged_Unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • REAL_Distance_Shackles_C_D[(Integer A)] Less than or equal to 150.00
                • Then - Actions
                  • Unit - Order Shackles_Caster[(Integer A)] to Stop
                  • Set Shackles_Dragged_Unit[(Integer A)] = No unit
                  • Set Shackles_Caster[(Integer A)] = No unit
                • Else - Actions
  • Shackles Cancel
    • Events
      • Unit - A unit Stops casting an ability
    • Conditions
      • (Ability being cast) Equal to Shackle and Drag
    • Actions
      • Unit - Order Shackles_Caster[Shackles_Current_Index] to Stop
      • Unit - Turn collision for Shackles_Dragged_Unit[Shackles_Current_Index] On
      • Set Shackles_Caster[Shackles_Current_Index] = No unit
      • Set Shackles_Dragged_Unit[Shackles_Current_Index] = No unit
  • Shackles Finishes
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Shackle and Drag
    • Actions
      • Unit - Turn collision for Shackles_Dragged_Unit[Shackles_Current_Index] On
      • Set Shackles_Caster[Shackles_Current_Index] = No unit
      • Set Shackles_Dragged_Unit[Shackles_Current_Index] = No unit
 
That would not work.
Try something like this instead...
JASS:
// GLOBALS -or in Gui, Variables.
  integer            oTrigger
  integer            oTrigger_MainIndex
  integer            oTrigger_Index
  
  unit         array oTrigger_Dummy
  
// The Trigger ~ OnCreate
  if ( udg_oTrigger_MainIndex = 0 ) then
    
	call EnableTrigger( gg_trg_The_Trigger_Loop )
	
  endif
  
  set udg_oTrigger_MainIndex               = udg_oTrigger_MainIndex + 1
  set udg_oTrigger_Index                   = udg_oTrigger_Index + 1
  set udg_oTrigger_Dummy[ oTrigger_Index ] = udg_GetTriggerUnit()

// The Trigger ~ Loop [ Initially Disabled ]
  
  loop
    
	set udg_oTrigger = udg_oTrigger + 1
	
  exitwhen ( oTrigger > oTrigger_Index )
    
	if ( udg_oTrigger_Dummy[ udg_oTrigger ] ) then
	  
	  if ( UnitAlive( udg_oTrigger_Dummy[ udg_oTrigger ] ) then
	    
		// Some Actions
		
	  else
	    
		set udg_oTrigger_MainIndex = udg_oTrigger_MainIndex - 1
		if ( udg_oTrigger_MainIndex = 0 ) then
		  
		  set udg_oTrigger_Index = 0
		  set udg_oTrigger_Dummy[ udg_oTrigger ] = null
		  
		endif
		
	  endif
	  
	endif
	
  endloop
 
Level 8
Joined
Mar 26, 2009
Messages
301
No it is fine =) As I said in my first post, my main goal is to learn a method to make MUI spells. If indexing is more efficent, I can go with that =)
Btw; I fixed the bug with my triggers. The part where it resets the index should be set to 30, not 50 =D Other than that, I haven't noticed any major bugs during multiple simultaneous casts.
 
Level 37
Joined
Mar 6, 2006
Messages
9,243
The initialization trigger is not necessary since reals/integers will be 0 at map initialization anyway.

The last two trigger could be removed and replace with a "current order of unit" check in the looping trigger.

Use proper index recycling and not if integer = 50 set integer to 0. Keep track of the number of instances of the spell running. Don't loop from 0 to 30, loop to the number of instances.

Turn off the looping trigger when there are no active instances.
 
Level 8
Joined
Mar 26, 2009
Messages
301
Unless it is going to cause serious problems, I prefer to keep it as it is =) At least for now. Someone else said "use proper indexing etc.." too but I didn't understand a thing from the sample he provided either =) This was my first attempt to make a MUI spell (that includes movement) and many things within WE still confuse me =) For me, change is only necessary when:
- Trigger performs with -visibly- low performance,
- It does not fulfil its job,
- It leaks.
(There is a location leak and a bug with loop trigger here which are now fixed in WE)
So If anyone spots something serious, please warn me =)
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
Hashtables are a structure that maps wide spread data into a small array and handles any collisions that occur (via linking normally).

For you, the user of the structure, they are mearly a 2D array with no capacity limits. Any index, positive, negative or 0 is valid and will refer to a unique slot (like arrays but with 2 indicies).

Unlike arrays, you can leak data into them by keeping stuff in obscure indicies and never removing them. This both wastes memory and degrades the hashtable lookup performance. Thus after you no longer need to store data into a hashtable, you should that location or the parent index to keep them working efficiently.

Good uses of hashtables...
1. Mapping data to object types (as all object types are an integer).
2. Storing index values onto handles (thus from a handle you can get the index to accociated data in arrays).
3. Other uses like breaking down the map into square areas where data has to be stored.
 
Status
Not open for further replies.
Top