HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Help with save/load code

01-29-2006, 07:32 PM#1
RaptorTeak
Hi there :).

I decided to continue my post there, like explained on the help in the trigger :).

I want to get this save/load system working on my map, so I copied all, added items/heroes in pools, etc etc.... But when I type -save, it always return me "(null)"...

I really don't know what to do now, I tried lots of things but no one worked...
I please you to have a look at it and to say what you think..

Thanks in advance.

ps : Pool class trigger is desactived because I copied it in the script part, like it says to do.

ps2 : test it with a mage for now....

RaptorTeak.
Attached Files
File type: w3xMolten Core 0.01a-engversion.w3x (228.3 KB)
01-30-2006, 12:37 AM#2
Vexorian
Are you initializing the codemaker engine?
01-30-2006, 07:22 AM#3
RaptorTeak
Well. Now I added the call in my initialisation trigger. There is some progress, now it does not longer say "(null)", it says " Loaded SUccefully" (note the space before Loaded, where normally a hero name has to be there).

I changed the tmp_point to a constant point (center of a region), and removed the "set udg_tmp_point = PositionOf(Triggering Unit)"

So -save is now working well, I got my code, but -load doesn't work (it does what I said a little upper).

...
01-30-2006, 02:24 PM#4
Vexorian
Ok, checking the map now.

You have a serious issue and it is that you have to use 4 letter codes (check the item pool setting) you are using I00D:shas , but you should only consider the first stuff (I00D)

I will try to see what the heck is happening, seems the hero id isn't working right
01-30-2006, 03:19 PM#5
Vexorian
I found the problem.

You were already initializing the codemaker because you even copied the Init Code Maker trigger.

So that was not the problem

The reason it worked after you added it to map initialization and the cause of all the problems was this:

Trigger:
Initialize Environment
Events
Conditions
Collapse Actions
Game - Set the time of day to 23.59
Game - Turn the day/night cycle Off
Game - Set game speed to Fastest
Game - Lock the game speed
-------- ----------------------- Quest Log ----------------------- --------
Quest - Create a Required quest titled Jeu with the description Comment jouer, using icon path ReplaceableTextures\CommandButtons\BTNAvatar.blp
Quest - Change the description of (Last created quest) to - POUSSEZ les monst...
Quest - Create a Required quest titled Affaiblir l'adversa... with the description Renverser la partie, using icon path ReplaceableTextures\CommandButtons\BTNHex.blp
Quest - Change the description of (Last created quest) to - AMELIORER vos uni...
Game Cache - Reload all game cache data from disk
Game Cache - Create a game cache from MC.w3v
Set Cache = (Last created game cache)

Remove the Game Cache - Reload all game cache data from disk line. first of all gamecache saving doesn't work in multiplayer, second in single player just creating the game cache is enough to make it load.

Reload all game cache data from disk , makes the game forget all the changes made to game caches and reload everything, so there was no reason to have it there anyways.

And because the codemaker (and almost every single thing I made) is gamecache based, that line cleans all the data used by the codemaker / hero-save code so it was as if you weren't initializing anything.

But yeah, once you fix the problems with the items and remove this line it should work correctly
01-30-2006, 03:38 PM#6
RaptorTeak
Thank you very much !!!!

It's now working very well :). I am glad this community, and you exist :).
Thanks again :).
01-30-2006, 03:44 PM#7
RaptorTeak
Oh, well, hero is loading, but.... Still a prob :

I changed all items ID, like you said (removed shas, etc... just kept the I008 etc...), I did the same for spells.

I tested with a mage, which is actually the only which has everything in the pool (skills, etc...). I put it level 10, took all spells, and took 2-3 items from arcanist set (mage's set in WoW). Then saved/reloaded, and, Oo, items and skills weren't there.... :(.

Only the unit level 10 was loaded....
01-30-2006, 03:47 PM#8
Vexorian
can you attach the new map?
01-30-2006, 03:50 PM#9
RaptorTeak
There it is...
Attached Files
File type: w3xMolten Core 0.01a-engversion.w3x (228.1 KB)
01-30-2006, 11:54 PM#10
Vexorian
Thanks, this reminded me a serious bug the editor has with the custom script section.

When you type % in the custom script section the % is not saved.

You have to type %% in order to let it be considered % . The lame thing is that that doesn't happen when the % is in a trigger's text.

to fix the problem you need to replace

local string cm=".................................!.#$%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................... .............................................................."

with:

local string cm=".................................!.#$%%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................... .............................................................."

in the custom script section.

Easy fix is to replace your custom script section with this:

Collapse JASS:
//##START##
//********************************************************************************************
//*
//*  Pool Class Functions
//*  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*   To implement them, first make sure that you have a gamecache variable udg_poolclass , to
//*  Copy it either use next trigger called "Variable Copyness" or just go the trigger editor,
//*  press ctrol + b and create a gamecache variable called poolclass, the udg_ is added
//*  automatically.
//*
//*   After that, copy the contents of this trigger begining with the //##Start## and
//* ending with the //##End## TO YOUR MAP'S CUSTOM SCRIPT SECTION , DON'T JUST Copy the trigger
//* ( The custom script section is at the top of the trigger list with the map's name.
//*
//*   In theory, you may just copy the trigger, making sure it is above any other trigger, then
//* Instantly save, this is easier, but may not work well.
//*
//********************************************************************************************

//===================================================================================
function PoolClass takes nothing returns gamecache
    if udg_poolclass==null then
        call FlushGameCache(InitGameCache("pool.vx"))
        set udg_poolclass=InitGameCache("pool.vx")
        call ExecuteFunc("Pool_SetupCharMap")
    endif
 return udg_poolclass
endfunction

//===================================================================================
function PoolGetItem takes integer poolid, integer itemn returns integer
    return GetStoredInteger( PoolClass(), I2S(poolid), I2S(itemn))
endfunction

//===================================================================================
function CountItemsInPool takes integer poolid returns integer
    return GetStoredInteger( PoolClass(), I2S(poolid), "n")
endfunction

//===================================================================================
function GetEnumPoolItem takes nothing returns integer
    return GetStoredInteger( PoolClass(), "Class", "Enum")    
endfunction

//===================================================================================
function ForPool takes integer poolid, code callback returns nothing
 local trigger t=CreateTrigger()
 local integer a=1
 local integer n=CountItemsInPool( poolid)
 local gamecache pc=PoolClass()
    call TriggerAddAction( t, callback)
    call TriggerWaitOnSleeps( t, true)
    loop
        exitwhen a>n
        call StoreInteger( pc, "Class", "Enum", PoolGetItem( poolid, a))
        call TriggerExecute(t)
        set a=a+1
    endloop
    call FlushStoredInteger( pc, "Class", "Enum")
 call DestroyTrigger( t)
 set t=null
 set pc=null
endfunction

//===================================================================================
// Uses a the function's name instead of a code argumment, it is better than ForPool
// because ForPool Creates Triggers to run the callback
//
function ForPool2 takes integer poolid, string callbackfuncname returns nothing
 local integer a=1
 local integer n=CountItemsInPool( poolid)
 local gamecache pc=PoolClass()
    loop
        exitwhen a>n
        call StoreInteger( pc, "Class", "Enum", PoolGetItem( poolid, a))
        call ExecuteFunc(callbackfuncname)
        set a=a+1
    endloop
 set pc=null
endfunction


//===================================================================================
function GetFirstOfPool takes integer poolid returns integer
    return GetStoredInteger( PoolClass(), I2S(poolid), "1")
endfunction

//===================================================================================
function PoolPickRandomItem takes integer poolid returns integer
    return GetStoredInteger( PoolClass(), I2S(poolid), I2S( GetRandomInt(  1, GetStoredInteger( PoolClass(), I2S(poolid), "n" ) ) ))
endfunction

//===================================================================================
function GetItemPositionInPool takes integer poolid, integer it returns integer
    return GetStoredInteger( PoolClass(), I2S(poolid), "i"+I2S(it))
endfunction

//===================================================================================
function IsItemInPool takes integer poolid, integer it returns boolean
    return GetItemPositionInPool( poolid, it) != 0
endfunction

//===================================================================================
function PoolAddItem takes integer poolid, integer value returns nothing
 local integer n
 local gamecache pc=PoolClass()
    if not IsItemInPool( poolid, value) then
        set n=GetStoredInteger( pc, I2S(poolid), "n") + 1
        call StoreInteger( pc, I2S(poolid), "n", n)
        call StoreInteger( pc, I2S(poolid), I2S(n), value)
        call StoreInteger( pc, I2S(poolid) , "i"+I2S(value), n )
    endif
 set pc=null
endfunction

//===================================================================================
function PoolRemoveItem takes integer poolid, integer value returns nothing
 local integer p=GetItemPositionInPool( poolid, value)
 local integer n=GetStoredInteger( PoolClass(), I2S(poolid), "n")
 local gamecache pc=PoolClass()
    if p!=0 then
        call FlushStoredInteger( pc, I2S(poolid), I2S(p))
        call FlushStoredInteger( pc, I2S(poolid), "i"+I2S(value))
        if n > p then
            call StoreInteger( pc, I2S(poolid), I2S(p), GetStoredInteger( pc, I2S(poolid), I2S(n)))
            call StoreInteger( pc, I2S(poolid), "i"+I2S( GetStoredInteger( pc, I2S(poolid), I2S(n))), p)
            call FlushStoredInteger( pc, I2S(poolid), I2S(n))
        endif
        call StoreInteger( pc, I2S(poolid), "n", n - 1)
    endif
 set pc=null
endfunction

//===================================================================================
function PoolAddPool takes integer sourcepoolid, integer destpoolid returns nothing
 local integer a=1
 local integer n=CountItemsInPool( sourcepoolid)
    loop
        exitwhen a>n
        call PoolAddItem( destpoolid, PoolGetItem( sourcepoolid, a))
        set a=a+1
    endloop
endfunction

//===================================================================================
function PoolRemovePool takes integer sourcepoolid, integer destpoolid returns nothing
 local integer a=1
 local integer n=CountItemsInPool( sourcepoolid)
    loop
        exitwhen a>n
        call PoolRemoveItem( destpoolid, PoolGetItem( sourcepoolid, a))
        set a=a+1
    endloop
endfunction

//===================================================================================
function DestroyPool takes integer poolid returns nothing
    call FlushStoredMission( PoolClass(), I2S(poolid))
endfunction

//===================================================================================
function CreatePool takes nothing returns integer
 local integer N=GetStoredInteger( PoolClass(), "Class", "N") + 1
    call StoreInteger( PoolClass(), "Class", "N", N)
 return N
endfunction

//===================================================================================
// Adds a tokenized string to a pool,
//  Example: PoolAddS(udg_p, "1;2;3;4") will add to the udg_p pool : 1,2,3 and 4
//
function PoolAddS takes integer poolid, string s returns nothing
 local string current=""
 local integer i=0
    set s=s+";"
    loop
        exitwhen SubString(s, i, i+1) == "" or SubString(s, i, i+1) == null
        if SubString(s, i, i+1) == ";" then
            call PoolAddItem( poolid, S2I(current))
            set current=""
        else
            set current=current+SubString(s, i, i+1)
        endif
        set i=i+1
    endloop
endfunction

//===================================================================================
// Converts a tokenized string into a pool,
//  Example: S2Pool( "1;2;3;4") will return a pool that has 1,2,3 and 4 inside
//
function S2Pool takes string s returns integer
 local integer spool= CreatePool()
    call PoolAddS(spool,s)
 return spool
endfunction

//=============================================================================================================
function Pool_SetupCharMap takes nothing returns nothing
 local gamecache g=udg_poolclass
 local string cm=".................................!.#$%%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."
 local integer i=0
 local string c
    if HaveStoredInteger(g,"charmap","A2") then
        return
    endif
    loop
        set c=SubString(cm,i,i+1)
        exitwhen (c==null) or (c=="")
        if (c!=".") then
            if c==StringCase(c,true) then
                set c=c+"2"
            else
                set c=c+"1"
            endif
            call StoreInteger(g,"charmap",c,i)
        endif
        set i=i+1
    endloop
 set g=null
endfunction
function Pool_Rawcode2Int takes gamecache g, string s returns integer
 local string c
 local integer i=0
 local integer r=0
    loop
        exitwhen i>3
        set c=SubString(s,i,i+1)
        set r=r*256
        if c==StringCase(c,true) then
            set c=c+"2"
        else
            set c=c+"1"
        endif
        set r=r+GetStoredInteger(g,"charmap",c)
        set i=i+1
    endloop
 return r
endfunction

function PoolAddRawcodes_thread takes nothing returns nothing
//Threaded because I don't want it to halt execution for no reason
//
 local gamecache g=PoolClass()
 local string s=bj_lastPlayedMusic
 local integer poolid=bj_groupEnumTypeId
 local string current=""
 local integer i=0
    set s=s+";"

    loop
        exitwhen SubString(s, i, i+1) == "" or SubString(s, i, i+1) == null
        if SubString(s, i, i+1) == ";" then
            call PoolAddItem(poolid, Pool_Rawcode2Int(g,current))
            set current=""
        else
            set current=current+SubString(s, i, i+1)
        endif
        set i=i+1
    endloop

 set g=null
endfunction

//=====================================================================================================================
// Adds a string of tokenized rawcodes to a pool
//  Example: PoolAddRawcodes(udg_p,"A000;A001")  will add 'A000' and 'A001' to the pool
//
// (Saves some lines, but is not as good efficiency wise)
//
function PoolAddRawcodes takes integer poolid, string s returns nothing
 local string b=bj_lastPlayedMusic
    set bj_groupEnumTypeId=poolid
    set bj_lastPlayedMusic=s
    call ExecuteFunc("PoolAddRawcodes_thread")
    set bj_lastPlayedMusic=b
endfunction

//===================================================================================================================
// Converts a tokenized string of rawcodes into a pool,
//  Example: Rawcodes2Pool( "A000;A001;AHbz;S000") will return a pool that has 'A000,'A001','AHbx' and 'S000' inside
//
// (Saves some lines, but is not as good efficiency wise)
//
function Rawcodes2Pool takes string s returns integer
 local integer spool= CreatePool()
    call PoolAddRawcodes(spool,s)
 return spool
endfunction
//##END##

01-31-2006, 03:45 PM#11
RaptorTeak
Ok, thank you very much, it's now fully working :).
02-02-2006, 08:05 PM#12
RaptorTeak
Back with new problems !

Unfortunaly.... :(.

So... I tested it in solo, made a char, typped -save, relaunched the game, type -load, my code, etc... Worked succefully.

Then, after lots of games on internet, I tried the save/load functions.
But oooh, I was anyway asking for three codes to be sure, all returned the "error 3" when tried to load....

It seems to work on solo, but not on battle.net :(.
I'm sure to have been typping the right code on the -load, but anyway I always got the ugly "Loading error 3"....

I attached the map, hope you can have a look at it :(.

I've already tried to reduce the FCS size, with no success.

Thanks in advance !
Attached Files
File type: w3xMolten Core 0.91.w3x (231.2 KB)
02-03-2006, 01:33 AM#13
Vexorian
RaptorTeak, the codes you get when your name is Vx won't work when your name is Vexorian244. It depends on the battle net account. Reducing FCS would only make the whole codes different and stop working, besides of reducing safety.

Make sure the player name you use to save the code in single player is not different from the bnet game you use in multiplayer
02-03-2006, 05:36 AM#14
RaptorTeak
I know that, and yes I used of nickname "RaptorTeak" on solo and battle.net.

Anyay, the first time I tried it, when I saved I was on battle.net, and when I loaded, 2 minutes later, I was also on battle.net, with same nickname.

Try it by yourself, modify a bit the map (add item "SUpprématie" on the start or something, to be really strong), then launch it, take any class, loot some items related to your class, remove "Supprématies" from you (we never know).

then reload the map and try the code you got >.<....

Normally you should get an error 3.
02-03-2006, 11:58 AM#15
Vexorian
I can't try it in battle net. But make sure it is a battle net problem, try saving the exact same hero and load it later in single player

Edit: also make sure you are copying all the characters correctly. Sometimes there are confusions with some of them. Try to use a safer charmap like ABCDEFHKLMNPQRSTUVWXYZ2345789$@& it is the bigger charmap with the least number of character confusions, although it is no longer a 64 characters charmap and will make the code a little bigger.