JASS:
private function GetActualEndSpeed takes real init, real modif returns real
local real result = init * modif
if result < MinMoveSpeed then
return MinMoveSpeed
endif
return result
endfunction
private function EndSpeedModifying takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = LoadUnitHandle(Table, GetHandleId(t), 'unit')
local hashtable h = LoadHashtableHandle(Table, GetHandleId(u), 0)
local real current_speed = LoadReal(h, 1, 0)
local integer temp_int = LoadInteger(h, 0, 0)
local real speed_change = LoadReal(h, 0, temp_int)
call SetUnitMoveSpeed( u , current_speed + speed_change )
if temp_int == 1 then
call FlushChildHashtable(h, 0)
else
call RemoveSavedReal(h, 0, temp_int)
call SaveInteger(h, 0, 0, temp_int-1)
endif
set temp_int = LoadInteger(h, 1, 1)
if temp_int == 1 then
call RemoveSavedHandle(Table, GetHandleId(u), 0)
call RecTable(h)
else
call SaveInteger(h, 1, 1, temp_int-1)
call SaveReal(h, 1, 0, current_speed + speed_change )
endif
set h = null
call FlushChildHashtable(Table, GetHandleId(t) )
call DestroyTimer(t)
set t = null
set u = null
endfunction
function ChangeUnitSpeed takes unit u, real speed_modifier, real duration, integer buff_ability, integer buff_icon returns nothing
local timer t = CreateTimer()
local integer id = GetHandleId(t)
local hashtable h = LoadHashtableHandle(Table, GetHandleId(u), 0)
local real init_speed
local real end_speed
local integer temp_int
if h == null then
set h = GetFreeTable()
set init_speed = GetUnitDefaultMoveSpeed(u)
call SaveHashtableHandle(Table, GetHandleId(u), 0, h)
else
set init_speed = LoadReal(h, 1, 0)
endif
set temp_int = LoadInteger(h, 1, 1) + 1
set end_speed = GetActualEndSpeed( init_speed, speed_modifier )
call SetUnitMoveSpeed( u , end_speed )
call SaveInteger(h, 1, 1, temp_int)
call SaveReal(h, 1, 0, end_speed)
set temp_int = LoadInteger(h, buff_ability, 0) + 1
call SaveReal(h, buff_ability, temp_int, init_speed - end_speed)
call SaveInteger(h, buff_ability, 0, temp_int)
set h = null
call SaveUnitHandle(Table, id, 'unit', u )
/* if buff_ability != 0 then
call UnitAddAbility( u , buff_ability )
call SaveInteger(Table, id, 'babi', buff_ability)
call SaveInteger(Table, id, 'buff', buff_icon)
call SaveReal(Table, id, 'rtim', duration )
call TimerStart( t, SpeedRefreshRate, true, function PeriodicCheck )
else */
call TimerStart( t, duration, false, function EndSpeedModifying )
// endif
set t = null
set u = null
endfunction
And the hashtable library:
JASS:
library TableRecycler
globals
private hashtable array Tables
private integer count = 0
endglobals
function RecTable takes hashtable h returns nothing
call FlushParentHashtable(h)
if count < 8192 then
set Tables[count] = h
set count = count + 1
endif
endfunction
function GetFreeTable takes nothing returns hashtable
local hashtable h
if count > 0 then
set count = count - 1
set h = Tables[count]
set Tables[count] = null
return h
else
return InitHashtable()
endif
endfunction
endlibrary
So... the problem is that sometimes when I use the ChangeUnitSpeed function (with 0 as buff_ability) - I get temp_int = 1 (both of them are always the same during the tests)
But sometimes, if I use it again - It's still 1, while it should be 2.
And I end up with the minimum movespeed, instead of the default move speed once the effect is over.
The idea is to be changing the unit's move speed without caring about outside factors (items / abilities).
So in the unit's hashtable, in (1, 1) I'm saving how many times has the unit's speed been changed trough this system.
In (1, 0) I'm saving what's the unit's current speed WITHOUT items / abilities.
In (buff_ability, 0) I'm saving how many times has a unit been slowed by a certain "buff".
In (buff_ability, ~The value from the 0~) I'm saving the movespeed difference in a sequence like "50, 40, 30, etc", so I can return the unit's speed in reverse order (30, 40, 50; instead of 50, 40, 30).
EDIT: Little update - the problem seems to start happening once the unit's speed has been returned to normal.
When I use the function for 1-st time - a new hashtable is created.
When I use it few more times before the effect from the 1-st use has worn off - the old table is used (everything works normally)
Then if I wait for all of the stacks to wear off, when I use it - new hashtable is assigned (as it should happen), but then when I used it before the effect from the initial use has worn off - it keeps using new hashtables, instead of the one already made...
Last edited by a moderator: