• 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 extremely long code issue

Status
Not open for further replies.
Level 3
Joined
Mar 14, 2011
Messages
32
hello

im using nestharus' encoder system and theres a strange bug
when i save the hero with just stats, the code is 8 letter long but when experience is added the code jumps to 21 letter

thank you if you help me !

JASS:
library Encoders uses Catalogs
    globals
        private constant integer CUR_ENC_VER = 2
        private Encoder array encoders
    endglobals
    
    function GetEncoder takes nothing returns Encoder
        return encoders[CUR_ENC_VER]
    endfunction
    
    private struct Encoder1 extends array
        private static constant integer ENC_VER = 2
        private static constant string ENCODER_BASE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
        private static constant integer ENCODER_HASH = 148194
        private static constant integer ENCODER_PLAYER_HASH = 2562
        
        private static method onInit takes nothing returns nothing
            local Encoder encoder = Encoder.create(Base[ENCODER_BASE], ENCODER_HASH, ENCODER_PLAYER_HASH,1)
            
            local CodeRange hero = CodeRange.create(1,HeroCatalog.count)
            local CodeRange lvl = CodeRange.create(1,90)
            local CodeRange xp = CodeRange.create(0,99)
                
            local CodeRange stats = CodeRange.create(0,0)
            local CodeRange stat = CodeRange.create(0,256)
            
            local CodeRange inv = CodeRange.create(0,0)
            local CodeRange it = CodeRange.create(0,ItemCatalog.count)
            
            local CodeRange ab = CodeRange.create(0,8)
            local CodeRange ab2 = CodeRange.create(0,12)
            
            local CodeRange charge = CodeRange.create(1,99)

            local CodeRange abilities = CodeRange.create(0,0)

            local CodeRange resource = CodeRange.create(0,1000000)
                
            call it.link(ItemCatalog.chargeMin,ItemCatalog.chargeMax,charge, 1)
            
            call abilities.linka(ab)
            call abilities.linka(ab)
            call abilities.linka(ab)
            call abilities.linka(ab)
            call abilities.linka(ab2)

            call stats.linka(lvl)
            call stats.linka(xp)
            call stats.linka(stat)
            call stats.linka(stat)
            call stats.linka(stat)
            
            call inv.linka(it)
            call inv.linka(it)
            call inv.linka(it)
            call inv.linka(it)
            call inv.linka(it)
            call inv.linka(it)
        
            call hero.linka(stats)
            call hero.linka(inv)
            
            call hero.link(HeroCatalog.abilMin, HeroCatalog.abilMax, abilities, 0)

            call encoder.add(hero)
            call encoder.add(resource)
            call encoder.add(resource)
            
            set encoders[ENC_VER] = encoder
        endmethod
    endstruct

endlibrary

JASS:
   struct Saver extends array

    private static method saveAbilities takes DataBuffer buffer, unit hero returns nothing
        local AbilityCatalog1 i = AbilityCatalog[GetUnitTypeId(hero)]
        local integer c = i.count
        local integer o = 0
        loop
            exitwhen o == c
            set o = o + 1
            call buffer.write(GetUnitAbilityLevel(hero, i.raw(o)))
        endloop
    endmethod

    private static method saveItem takes DataBuffer buffer, item i returns nothing
        if (i == null) then
            call buffer.write(0)
        else
            call buffer.write(ItemCatalog[GetItemTypeId(i)].id)
            if (buffer.id == 1) then
                call buffer.write(GetItemCharges(i))
            endif
        endif
    endmethod
    
    private static method saveInventory takes DataBuffer buffer, unit u returns nothing
        call saveItem(buffer,UnitItemInSlot(u,0))
        call saveItem(buffer,UnitItemInSlot(u,1))
        call saveItem(buffer,UnitItemInSlot(u,2))
        call saveItem(buffer,UnitItemInSlot(u,3))
        call saveItem(buffer,UnitItemInSlot(u,4))
        call saveItem(buffer,UnitItemInSlot(u,5))
    endmethod
    
    private static method saveStats takes DataBuffer buffer, unit hero returns nothing
        call buffer.write(GetHeroLevel(hero))
        call buffer.write(GetPercentHeroXP(hero))
        call buffer.write(GetHeroStr(hero, false))
        call buffer.write(GetHeroAgi(hero, false))
        call buffer.write(GetHeroInt(hero, false))
    endmethod
    
    private static method saveHero takes DataBuffer buffer, unit hero, integer pid returns nothing
        call buffer.write(HeroCatalog[GetUnitTypeId(hero)].id)
        call saveStats(buffer, hero)
        call saveInventory(buffer, hero)
        call saveAbilities(buffer, hero)
    endmethod
    
    private static method run takes nothing returns boolean
        local player p = GetTriggerPlayer()
        local integer pid = GetPlayerId(p)
        local Encoder encoder
        local DataBuffer buffer
        local integer start = 0
        local integer iid
        
        if (pdata[pid]) then
            set encoder = GetEncoder()
            set buffer = encoder.write(pid)
            call saveHero(buffer, hero[pid], pid)
            call buffer.write(GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER))
            call buffer.write(GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD))
            call DisplayTextToPlayer(p,0,0,"|c0080ffffCode : |r"+buffer.code)
                  
        endif
        
        return false
    endmethod
    
    private static method runs takes nothing returns nothing
        local integer i = 7
        local trigger t = CreateTrigger()
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
        loop
            if (GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER) then
                call TriggerRegisterPlayerChatEvent(t, Player(i), "-save", true)
            endif
            exitwhen i == 0
            set i = i - 1
        endloop
        call TriggerAddCondition(t, function thistype.run)
    endmethod
    
    private static method onInit takes nothing returns nothing
        call TimerStart(CreateTimer(), 0, false, function thistype.runs)
    endmethod
endstruct
 
Last edited:
I told him to put it here so that others could look at it as well.

Help goes into Triggers and Scripts, not on to resource threads =P


I'll take a deeper look at this in a few, but this one thing strikes me as odd
-> local CodeRange stat = CodeRange.create(0,256)

You can have a stat of 0? Like 0 agility? lol

edit
JASS:
    //percent code range
    local CodeRange perc = CodeRange.create(0,100)

And what is that for? I don't see you using it anywhere : P

And just to make sure I have this right-
JASS:
    //ability levels: 3,3,3,1
    call abil4.linka(a8)
    call abil4.linka(a8)
    call abil4.linka(a8)
    call abil4.linka(a8)
    
    //ability levels: 4,4,4,2,4
    call abil5.linka(a12)
    call abil5.linka(a12)
    call abil5.linka(a12)
    call abil5.linka(a12)
    call abil5.linka(a8)

So some of your heroes have 5 abilities of max levels 4,4,4,2 and 4 and others have 4 abilities of max levels 3, 3, 3, and 1?

Just making sure since it appears you cnp'd most of this =)

And you have all of these possible item charges? 2,3,4,5, 6, and 10? In Pearl East Kingdom, I know the guy only had one item charge max of 99 for potions ; )

edit
Also, it's much better to link items to the next items rather than an inventory to 6 items.

item 1 -> item 2 -> item 3 -> item 4 -> item 5 -> item 6

This way you aren't like saving a completely blank inventory ; ).

For xp, it's best to link it to between 1 and 64 since the max level doesn't need xp saved : P


I'll check some out more in a few... make sure to be running this in debug mode so that you can see any error messages that might be popping up. Really, it looks like you cnp'd this out of the encoder demo map and changed a few things around ; )
 
Level 3
Joined
Mar 14, 2011
Messages
32
thank you
i just changed little because it was confusing
and your demo map seemed to have everything i needed
my map doesnt save too much things.. just regular stats and few stuff

ive put 0 in stat because few characters have 0 int

the code still jumps from 8 to 20ish letters.. i really don't know what to do now :(
 
Last edited:
no... think of it like this

You have a level object. Your hero points to the level object.

hero -> level

From there, you can make the level point to xp

level -> xp

You can make level's 1 through 64 point to xp

1 ... 64 -> xp

because level 65 doesn't have xp does it? It's the max lvl, so no need to save xp for that =).

Try looking at the tutorial I wrote for building Encoder objects and catalogs so that you can get a better feel for this =).
 
Level 3
Joined
Mar 14, 2011
Messages
32
ok thank you! ill read the builder tutorial

this big code increase still remains unsolved even though i linked it from 1 to (maxlvl -1)...

i made a hero with lvl 50, 6 items 2 skills but the code is only about 9 letter long
but killing one monster raise code to 23 letters! very frustrating :<

+rep!
 
Last edited:
In a private message, you mentioned that you were getting an buffer not finalized error.

All errors in Encoder are critical errors. If you get even 1, then that means you are doing something that is making your save/load stuff not work.

Think of an error message like a crash.

The data not finalized error means that in the saving process, one of the values you tried to save was out of bounds and didn't fit into the object, or you forgot to save a value =).
 
Level 3
Joined
Mar 14, 2011
Messages
32
no.. the code still jumps from 8 to 21letter due to experience
maybe ill try using getheroexp instead of getpercentheroxp
 
ok... I am honestly at a total loss here, I'd have to see the map to see what's going on...

Here are some suggestions-

In the Save area, add debug messages as you are writing the data to the buffer so that you see that you are writing the right data.

Make sure that the code you are loading is 100% correct.

For xp (in case you don't have the latest UnitStatePercent), see if 50% xp shows a value of 50. For example, at lvl 1, if you need 200 xp to level, set xp to 100 and see if 50 pops up ; ).

If you still see no problems, I'd have to look at it to see what's going on.


I also suggest that you move over to a better framework for backwards compatible codes. The one in the Encoder demo map kinda sucks. The quickstart guide to save/load with Encoder has a better one and shows you how to install.

http://www.hiveworkshop.com/forums/...ickstart-guide-saving-loading-encoder-196496/


The 9 character code size just doesn't sound right to me, unless you only have a few heroes/items in your map ; ).
 
Status
Not open for further replies.
Top