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

[vJASS] Encoder freeze issue

Status
Not open for further replies.
Level 3
Joined
Mar 14, 2011
Messages
32
hello
i've been using Nestharus's awesome Encoder
but this save function keep freezes the game... would appreciate some help

a question : can i put conditions within the function?

JASS:
    private function Save takes nothing returns boolean
        local player p = GetTriggerPlayer()
        local integer pid = GetPlayerId(p)
        local DataBuffer buffer
        local unit u = hero[pid]
        local integer i
        local integer array items
        local item array it
        local integer ic = 5
        local integer t
        local ItemCatalog1 cat
        local integer uid
        local timer ti
        local MBData mb
        
        if pdata[pid] then
        
            set buffer = GetCurrentEncoder().write(pid)
            set u = hero[pid]
            set uid = GetUnitTypeId(u)

            if uid == 'H00P' or uid == 'H00Q' then
                set cat = ItemCatalog1[0]
            elseif uid == 'H025' then
                set cat = ItemCatalog1[1]
            elseif uid == 'H00C' or uid == 'H00E' or uid == 'H00H' then
                set cat = ItemCatalog1[2]
            elseif uid == 'H00D' or uid == 'H01I' then
                set cat = ItemCatalog1[3]
            elseif uid == 'H00B' or uid == 'H01E' then
                set cat = ItemCatalog1[4]
            elseif uid == 'H024' then
                set cat = ItemCatalog1[5]
            endif
                
            call buffer.write(HeroCatalog1[uid].id)
            call buffer.write(GetHeroLevel(u))
            if GetHeroLevel(u) < 126 then
                call buffer.write(GetPercentHeroXP(u))
            endif
            call buffer.write(GetHeroStr(u,false))
            call buffer.write(GetHeroAgi(u,false))
            call buffer.write(GetHeroInt(u,false))
            call buffer.write(Stat[u].token1)
            call buffer.write(Stat[u].token2)
                
            set i = 5
            loop
                set t = cat.id(GetItemTypeId(UnitItemInSlot(u,i)))
                if (t != 0) then
                    set items[ic] = t
                    set it[ic] = UnitItemInSlot(u, i)
                    set ic = ic - 1
                endif
                exitwhen i == 0
                set i = i - 1
            endloop
            set ic = 5
            loop
                call buffer.write(items[ic])
                set it[ic] = null
                exitwhen ic == 0 or items[ic] == 0
                set ic = ic - 1
            endloop
                
            set i = GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)/100
            if i > 1000 then
                set i = 1000
            endif
            call buffer.write(i)
                
            call DisplayTimedTextToPlayer(p, 0, 0, 60, buffer.code)
            
            set i = UnitInventorySize(u)
            loop
                exitwhen i == 0
                set i = i - 1
                call RI(UnitItemInSlot(u,i))
            endloop
            
            set ti = Stat[u].t
            set mb = GetTimerData(ti)
            call ReleaseTimer(ti)
            call mb.destroy()
            
            call Stat[u].mb.clear()
            call Stat[u].mb.destroy()
            
            call RemoveUnit(u)
            call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,0)
            set u = null
            set pdata[pid] = false
            
        endif
        return false
    endfunction
 
First off... why don't you just use a table for all of this???
JASS:
        if uid == 'H00P' or uid == 'H00Q' then
            set cat = ItemCatalog1[0]
        elseif uid == 'H025' then
            set cat = ItemCatalog1[1]
        elseif uid == 'H00C' or uid == 'H00E' or uid == 'H00H' then
            set cat = ItemCatalog1[2]
        elseif uid == 'H00D' or uid == 'H01I' then
            set cat = ItemCatalog1[3]
        elseif uid == 'H00B' or uid == 'H01E' then
            set cat = ItemCatalog1[4]
        elseif uid == 'H024' then
            set cat = ItemCatalog1[5]
        endif

It'd be faster and less code : P



Also... if you have a large number of shuffles and a large number of bases in the scrambling algorithm, this could cause the save command to freeze for a bit.


For each base in the shuffling algorithm, the number has to be converted from one base to another base. This involves many trigger evaluations and a lot of operations. Base conversion is a very heavy thing, especially for large numbers.

The next thing that is done is the scrambling, which includes 1 more trigger evaluation and a another mass of operations.

So if you have 7 bases, this is done 7 times. If you have 3 shuffles, then it's done 21 times.

This is the reason why for larger codes, save commands now freeze.

If you want to get rid of the freeze, lower the amount of bases and the amount of shuffles. You can get away with 1 shuffle if you have around 7 bases. If 7 bases freezes, try lowering it until it doesn't freeze anymore.

You really need 2-3 bases bare minimum to get a decent shuffle going. 3 will be pretty eh, 2 mediocre (weak in some cases).


Why are there masses of trigger evaluations? Because it would otherwise hit the op limit : P.


edit
cool, answered within 10 minutes of post, lol
 
Level 3
Joined
Mar 14, 2011
Messages
32
Does reaching op limit cause permanent freeze?

The function froze game permanently.. Not just for a few seconds :(
 
Status
Not open for further replies.
Top