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

[Solved] Something isn't quite right here

Status
Not open for further replies.
Level 13
Joined
Jan 2, 2016
Messages
978
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:
Level 13
Joined
Jan 2, 2016
Messages
978
Okay, after many, and weird tests, I found out what was wrong....
"FlushParentHashtable" acts like "DestroyHashtable".
I thought it's supposed to clear ALL of the hashtable's fields, but instead it was just clearing the hashtable itself xP

After I stopped flushing the parent hashtable - it all started working properly :)

JASS:
library TableRecycler

    globals
        private hashtable array Tables
        private integer count = 0
    endglobals
    
    function RecTable takes hashtable h returns nothing
        if count < 8192 then
            set Tables[count] = h
            set count = count + 1
        else
            call FlushParentHashtable(h)
        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
 
Status
Not open for further replies.
Top