• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Solved] Something isn't quite right here

Status
Not open for further replies.
Level 13
Joined
Jan 2, 2016
Messages
973
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
973
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