• 🏆 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!

Save/Load System that saves abilities

Status
Not open for further replies.
Level 1
Joined
Jun 21, 2009
Messages
282
Hey guys, I need a save/load system that saves your hero's level, stats, abilities(so when you -load, you won't have to learn your abilities again through the red cross), Gold, Lumber, Level of the abilities, so if i had a Level 5 storm bolt, and when i load, it'll make it so i'll already learned the level 5 storm bolt for me, and i won't have to learn it through the red cross.
 
Level 16
Joined
May 1, 2008
Messages
1,605
Level 1
Joined
Jun 21, 2009
Messages
282
Do you get to keep abilities you've learned from a vendor (hero ability) and you keep leveling that hero ability by keep buying that same item?
 
Level 1
Joined
Jun 21, 2009
Messages
282
My hero is able to buy a item, that will triggerly learn him an ability, and when you buy more of that item it'll level that ability up, when i -save, will it load that abilites and other abilities that hero has learned through vendors?
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Don't use any of those. Either use http://www.hiveworkshop.com/forums/spells-569/encoder-1-0-0-0-a-189883/?prev=d=list&r=20&u=nestharus or http://www.wc3c.net/showthread.php?t=87360. Don't use any other save/load system unless you want codes that are 2x longer than they need to be. Those are the only 2 save/load systems that are any good.

I suggest http://www.hiveworkshop.com/forums/spells-569/encoder-1-0-0-0-a-189883/?prev=d=list&r=20&u=nestharus though as that will output smaller codes w/ security.

edit
Comparisons
JASS:
//iGen does it in 17 w/ security (prob 15-16 w/o)
//CodeGen does it in 16 w/o security
//Acehart's does it in 16
//PipeDream's Optimal Save System does it in 7 chars w/ 0 security
//Encoder does it in 7 chars w/ 0 security

You can see the results for yourself.

My hero is able to buy a item, that will triggerly learn him an ability, and when you buy more of that item it'll level that ability up, when i -save, will it load that abilites and other abilities that hero has learned through vendors?

If you save them into the code, yes.


Also, Encoder 2.0.0.0 will be able to save things like item charges =), but it's taking me a very long time to code it o-o.

So the only save/load system I really recommend you use is Encoder as that's more customizable than PipeDream's, supports multiple save/load code versions, and has a chance to output smaller codes w/ security as well as uses ranges rather than maxes and can encode negative values.

It is probably the best save/load system to date, and 2.0.0.0 will be superior to every other save/load system ever created for wc3, the others won't even be able to come close to it.
 
Last edited:
Level 1
Joined
Jun 21, 2009
Messages
282
Don't use any of those. Either use http://www.hiveworkshop.com/forums/spells-569/encoder-1-0-0-0-a-189883/?prev=d=list&r=20&u=nestharus or http://www.wc3c.net/showthread.php?t=87360. Don't use any other save/load system unless you want codes that are 2x longer than they need to be. Those are the only 2 save/load systems that are any good.

I suggest http://www.hiveworkshop.com/forums/spells-569/encoder-1-0-0-0-a-189883/?prev=d=list&r=20&u=nestharus though as that will output smaller codes w/ security.

edit
Comparisons
JASS:
//iGen does it in 17 w/ security (prob 15-16 w/o)
//CodeGen does it in 16 w/o security
//Acehart's does it in 16
//PipeDream's Optimal Save System does it in 7 chars w/ 0 security
//Encoder does it in 7 chars w/ 0 security

You can see the results for yourself.



If you save them into the code, yes.


Also, Encoder 2.0.0.0 will be able to save things like item charges =), but it's taking me a very long time to code it o-o.

So the only save/load system I really recommend you use is Encoder as that's more customizable than PipeDream's, supports multiple save/load code versions, and has a chance to output smaller codes w/ security as well as uses ranges rather than maxes and can encode negative values.

It is probably the best save/load system to date, and 2.0.0.0 will be superior to every other save/load system ever created for wc3, the others won't even be able to come close to it.

The only thing is, is that I don't know how to use Jass, if Jass knowledge is required for this saving/loading system.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Minimal vjass knowledge is required. It's pretty easy.

For custom script, make a global called encoder and then do like
set encoder = Encoder.create("[0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"]) or w/e.

Then do like Encoder(encoder).add(lowBound, highBound), but this would probably be best done in plain text.

Just check out the demo map and use that as a template, most of it is variable sets and I'm sure you can read that ; P. For the actual saving portion, you can just do GUI and keep in mind DataBuffer.write() and DataBuffer.read() = ).

But really, is it not worth it for a code of half the size? : |
 
Level 1
Joined
Jun 21, 2009
Messages
282
Yeah, the code is super long, if i could minimize the code somehow, and yeah i've looked at the demo map, looks really complex for a -save and -load system since it saves the percentage of the exp bar and the start location of where you saved your character onto that map, i'd really love to use this system but the only problem is that i don't know where to start since its in jass and i don't know a thing about jass.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I could walk you through it if you like.

Ok, the triggers you'll need to look at are in the demo folder.

The first one is the Catalog.

From line 17 on-
struct Catalog extends array

private static constant integer CUR_VERSION = 0
That refers to your current version. Just change this to values between 0 and 9.

Notice I do
set encoders[0] = encoder
A bit lower.

You are provided with a pretty useful thing called a textmacro.

JASS:
        //! runtextmacro CREATE_CATALOG("Hero")
        //! runtextmacro CREATE_CATALOG("Item")
        //! runtextmacro CREATE_CATALOG("Pet")

Remember that in save/load codes, you have to create a catalog of most everything you want to save. A catalog would be the arrays you store all your heroes in, items in, and etc. This macro creates catalogs for you. It looks easy to create a new catalog no? It is.

This line creates a catalog called Hero, which is used to store the hero unit type ids in the map
//! runtextmacro CREATE_CATALOG("Hero")

It can be named whatever you want, I just named it Hero because that made sense ;P.

A unit id is the Unit Type Id. If you go into the object editor and hit CTRL+D, you will see the raw code unit ids of units.

The catalog macro is run within the Catalog struct (right where I have the 3 macros at).

JASS:
    struct Catalog extends array
        private static hashtable table = InitHashtable()
        private static constant integer CUR_VERSION = 0
        readonly static Encoder array encoders
        
        static method operator encoder takes nothing returns Encoder
            return encoders[CUR_VERSION]
        endmethod

        //put them here
        //! runtextmacro CREATE_CATALOG("Hero")
        //! runtextmacro CREATE_CATALOG("Item")
        //! runtextmacro CREATE_CATALOG("Pet")

The next portion is the init version 0 area
private static method initv0 takes nothing returns boolean

There are 10 initialization areas in the demo, meaning you can have up to 10 active encoders. If you add new features to your map, like a new hero, and you want backwards compatibility, that is where the 10 initialization areas come in handy.

The Encoder object is what actually stores the values you can put into your save/load code. Think of it as having slots that you can plug into.

local Encoder encoder = Encoder.create(Base["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*():<>?+-"], 148194, 2562)

The long string would be the key I'm using (the characters used for the save/load code). Normally, you scramble this up and people don't normally use special characters.

Example-
5cD234EFGHXYUVQRST789irstuvwxyz6NO01PnWZabIJKLMjklopmqdABCefgh

Encoder.create(Base["5cD234EFGHXYUVQRST789irstuvwxyz6NO01PnWZabIJKLMjklopmqdABCefgh"], 148194, 2562)

The next value is used to make it so codes can't be easily modified. The larger the value, the less likely a code can be modified. Large values will increase the size of the code. I normally use a 6 digit number like what I used here: 148194.

The next value controls how likely one player can load up the code of another player. It's already unlikely, even if this value was 0 or 1 because the code scrambling is unique to every player. However, there is still a very tiny chance that 2 players could load up the same code (though the code would give different data for both of them). This value makes that chance very small. I always make it 2 digits less than the modification protection value so that it doesn't increase the size of the code at all: 2562

The next portion is where things are added to the catalog. The things created are based on what you named the catalog. For example

call addHero('Hpal')

That is only addHero because I named the catalog Hero. If I had named it Pooky, it would have been addPooky. You can pass in any integer value. I'm passing in unit type ids (remember Object Editor, units have ids). Hpal refers to the Paladin. Look it up in Object Editor =P.

I add in tons of heroes...

Next, I move on to the Pet catalog, which takes more units. I'm just adding creeps here actually (neutral hostile i think?).

After that is the Item catalog, where I am going through many of the items in the game and adding them (I went through a lot o-o).

Finally, when you are finished building your catalog, you need to build your encoder. Remember that an encoder has slots that you can plug values into?

Each slot in the Encoder can store a specific range of values, and you can tell it precisely what range you want.

call encoder.add(0,1000000) //gold

That's the very first range I added to the encoder, which means that the first slot in the Encoder can take a value anywhere from 0 to 1000000. Remember a player could have anywhere from 0 to 1000000 gold.

Always add your biggest value first*** to make your code smaller.

Next, I add in the lumber
call encoder.add(0,1000000) //lumber

A player can have between 0 and 1000000 lumber right? Right.

After that, I add in the hero
call encoder.add(1,HeroCount) //hero

Notice I used a variable called HeroCount. Remember the Hero catalog? HeroCount was generated by it. If I had named the catalog Pooky, it would have been PookyCount. It refers to the maximum possible hero you can have. So if you had 10 heroes in your map, it would be 10 and the range would be 1-10. I make the minimum 1 here because a player will always have a hero. 0 would mean that the player might not have a hero, which doesn't make sense.

Next I added in the x
call encoder.add(0,100) //hero x

Remember, I did freaky stuff to make the coordinates a percent. 0 to 100 refers to 0% to 100%. 0 would be at the very bottom of the map and 100 would be at the very top.

Next, the level
call encoder.add(1,10) //hero level

In this map, the minimum level a hero can have is 1 and the max is 10. Can change it, but I don't recommend changing the min unless your heroes can be level 0, or the very first level in the map is something like level 23.

Next, I add the % xp
call encoder.add(0,99) //hero % xp

Notice that this is not 0-100. The reason is because at 100%, the hero has leveled. At max level, the xp would actually be 0%.

Then I have stats
JASS:
                call encoder.add(1,256)         //str
                call encoder.add(1,256)         //agi
                call encoder.add(1,256)         //int

This means that the max stat my heroes can have are 256, but you can change it to whatever. It changes from map to map.

Next, hero life and mana
JASS:
                call encoder.add(0,100)         //hero life
                call encoder.add(0,100)         //hero mana

Again, percents.

Next, the hero inventory, which has 6 items in it
call encoder.add(1,ItemCount) //item 1

So this would be able to handle any item. However, this should have been 0 to ItemCount because the hero may not have an item. This means that every single slot has to have an item :| (my mistake)

Next, the item charge
call encoder.add(0,25) //item 1 charge

Notice that this'll make it so that you always have to save an item's charge and you can only save a max charge of 25. Most items in a map actually have a charge of 0. There is a reason charged items typically aren't saved in ORPGs.

On another note, Encoder 2.0.0.0 will be able to handle charged items brilliantly. If you save an item and it has a max charge of 100, it'll make a slot to store that charge =P. If it has a max charge of 0, it won't make a slot. Nice eh? : )

And yea, doing the other 5 items in the inventory
JASS:
                call encoder.add(1,ItemCount)   //item 2
                call encoder.add(0,25)          //item 2 charge
                call encoder.add(1,ItemCount)   //item 3
                call encoder.add(0,25)          //item 3 charge
                call encoder.add(1,ItemCount)   //item 4
                call encoder.add(0,25)          //item 4 charge
                call encoder.add(1,ItemCount)   //item 5
                call encoder.add(0,25)          //item 5 charge
                call encoder.add(1,ItemCount)   //item 6
                call encoder.add(0,25)          //item 6 charge

Then I made it so that a hero could have 4 pets in this map, so I store them all.

call encoder.add(1,PetCount) //pet1

Notice my mistake. The minimum is 1, meaning the hero always has to have a pet :\. It should have been 0 to PetCount.

And store all of the pet's stats
JASS:
                call encoder.add(0,100)         //pet1 x
                call encoder.add(0,100)         //pet1 y
                call encoder.add(0,100)         //pet1 facing
                call encoder.add(0,100)         //pet1 life
                call encoder.add(0,100)         //pet1 mana

Yawn, you should be getting it at this point

And the rest of the pets
JASS:
                call encoder.add(1,PetCount)    //pet2
                call encoder.add(0,100)         //pet2 x
                call encoder.add(0,100)         //pet2 y
                call encoder.add(0,100)         //pet2 facing
                call encoder.add(0,100)         //pet2 life
                call encoder.add(0,100)         //pet2 mana
                
                
                call encoder.add(1,PetCount)    //pet3
                call encoder.add(0,100)         //pet3 x
                call encoder.add(0,100)         //pet3 y
                call encoder.add(0,100)         //pet3 facing
                call encoder.add(0,100)         //pet3 life
                call encoder.add(0,100)         //pet3 mana
                
                call encoder.add(1,PetCount)    //pet4
                call encoder.add(0,100)         //pet4 x
                call encoder.add(0,100)         //pet4 y
                call encoder.add(0,100)         //pet4 facing
                call encoder.add(0,100)         //pet4 life
                call encoder.add(0,100)         //pet4 mana

And that's that. You can also store abilities, but that requires you make an ability catalog or a special ability catalog unique to each hero. You'd do it just the same way, add each ability to the catalog, then add slots to the encoder to store the ability and its level.

Ex
JASS:
call encoder.add(0,AbilityCount)
call encoder.add(0,3)           //ability level

If the ability was level 0, then they may have it, but it's not been learned yet ;P. However, if when they first get the ability it's at level 1, then you could make it 1,3.

JASS:
call encoder.add(0,AbilityCount)
call encoder.add(1,3)           //ability level

And if they could have like 12 abilities, you'd have to add it 12 times.

So now the encoder is built as well as the catalogs.

The next trigger to look at is Saving

Scroll down to this area
JASS:
            set encoder = Catalog.encoder
            
            //first open the encoder for the triggering player
            //because this is saving, don't pass it a code
            call encoder.open(null, pid)

First, I read the latest encoder from Catalog.encoder, just so I know what to use for my encoder. Next, I open the encoder. pid refers to the player's id (I make a little variable at the top of the function) and null refers to the code. If the code is null, it'll open up for writing. If the code is not null, it'll open for reading.

And here are my locals just so that it is clear where these variables are coming from
JASS:
        local player p = GetTriggerPlayer()
        local integer pid = GetPlayerId(p)
        local Encoder encoder
        local integer i
        local integer i2
        local unit u
        local item it

Just scroll down to call DataBuffer.write(GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD))

Remember that the first slot added to the encoder was the gold? Just read the player's gold and write it to the buffer. You can easily do this in GUI as well

  • Actions
    • Set number = ((Triggering player) Current gold)
    • Custom script: call DataBuffer.write(udg_number)
GetPlayerState would be the JASS native that retrieves a player's properties, like gold.

So I am just writing data into the buffer in the order that I added to the encoder.

The order was
JASS:
            /*
                gold, lumber

                hero
                    %x, %y, %facing, level, %xp
                    
                hero str, agi, int
                    
                hero %life, hero %mana

                item1, charge
                item2, charge
                item3, charge
                item4, charge
                item5, charge
                item6, charge

                pet1
                    x%, y%, facing%, life%, mana%
                pet2
                    x%, y%, facing%, life%, mana%
                pet3
                    x%, y%, facing%, life%, mana%
                pet4
                    x%, y%, facing%, life%, mana%
            */

Sure enough, next is lumber
call DataBuffer.write(GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER))

Just read the lumber and wrote it into buffer. Again, can easily be done in GUI.

Next the hero
call DataBuffer.write(Catalog.getHeroId(GetUnitTypeId(u)))

Notice I used Catalog.getHeroId. When creating a catalog, it also creates a getId type thingie so that you can convert a unit id into a catalog id, thus making the number way smaller. The thing takes the unit id.

GetUnitTypeId(u) would return like Hpal for a Paladin.

So together, Catalog.getHeroId(GetUnitTypeId(u))

Where I am passing the unit type id of the unit into the catalog so that I can convert it into a hero catalog id. I then pass that hero catalog id into the DataBuffer.

If I had named the catalog Pooky, it would be Catalog.getPookyId and I would pass in a well... a pooky I guess, lol... for pets, remember that they are units, so I still pass in GetUnitTypeId.

Next are the coords
JASS:
            call DataBuffer.write(GetPercentUnitX(u))
            call DataBuffer.write(GetPercentUnitY(u))

GetPercentUnitX will retrieve a unit's percent position on the map given the unit. It is part of the UnitStatePercent library.

Then facing, level, and xp. Notice that the facing and xp are again retrieved as percents. The hero level is not.
JASS:
            call DataBuffer.write(GetPercentUnitFacing(u))
            call DataBuffer.write(GetHeroLevel(u))
            call DataBuffer.write(GetPercentHeroXP(u))

And all of the stats. The false means to not include bonuses in with the stats (bonuses from things like armor).
JASS:
            call DataBuffer.write(GetHeroStr(u, false))
            call DataBuffer.write(GetHeroAgi(u, false))
            call DataBuffer.write(GetHeroInt(u, false))

And percent life and mana
JASS:
            call DataBuffer.write(GetPercentUnitLife(u))
            call DataBuffer.write(GetPercentUnitMana(u))

The inventory is a little trickier as you need to loop over the items in a unit's inventory.

JASS:
            set i = UnitInventorySize(u)
            set i2 = 6-i
            loop
                set i = i - 1
                set it = UnitItemInSlot(u, i)
                call DataBuffer.write(Catalog.getItemId(GetItemTypeId(it)))
                call DataBuffer.write(GetItemCharges(it))
                exitwhen i == 0
            endloop
            loop
                exitwhen i2 == 0
                call DataBuffer.write(0)
                call DataBuffer.write(0)
                set i2 = i2 - 1
            endloop

This essentially loops through each item in the unit's inventory and writes it in. However, what if the unit only had an inventory size of 4? Remember there are 6 spaces for items in the code, so 6 items have to be written, even if the rest are 0s. The second loop writes in 0s. If the unit had an inventory size of 4, it'd write in 2 0s at the end. Notice that I first write the item, then I write its charges. Remember that when I built the encoder, I first added a slot for the item, then the charge.

Next, I read each pet
JASS:
            call DataBuffer.write(Catalog.getPetId(GetUnitTypeId(u)))
            call DataBuffer.write(GetPercentUnitX(u))
            call DataBuffer.write(GetPercentUnitY(u))
            call DataBuffer.write(GetPercentUnitFacing(u))
            call DataBuffer.write(GetPercentUnitLife(u))
            call DataBuffer.write(GetPercentUnitMana(u))

And yea, it gets boring. Essentially, all you need to know is to write data to the encoder, you use DataBuffer.write =P, and you have to write in the exact same order that you built the encoder in.

Finally, I display the encoder id and the code
JASS:
            call DisplayTimedTextToPlayer(p, 0, 0, 60, "Encoder Version: " + encoder.toString())
            call DisplayTimedTextToPlayer(p, 0, 0, 60, DataBuffer.code)

DataBuffer.code returns the code, colorized and ready to go. That's all that needs to be done. encoder.toString() (where encoder is your Encoder object) returns the encoder as a little mini code. This allows a player to do something like -load encoder code for older codes.

Loading is done the exact same way except that you use Read first...

All of this garbage is for loading older codes
JASS:
set s = SubString(s, 6, StringLength(s))
        loop
            set char = SubString(s, i, i+1)
            exitwhen char == DELIMITER or i == k
            set i = i + 1
        endloop
        if (char == DELIMITER) then
            set s3 = SubString(s, 0, i)
            set s2 = ""
            set k = StringLength(s3)
            loop
                set k = k - 1
                set char = SubString(s3, k, k+1)
                if (char != " ") then
                    set s2 = char + s2
                endif
                exitwhen k == 0
            endloop
            set encoder = Encoder.convertString(s2)
            debug if (encoder > 0) then
                set s = SubString(s, i+1, k)
            debug else
                return false
            debug endif
        else
            set encoder = Catalog.encoder
        endif

Don't worry yourself over it ;P.

The portion you want to look at is
if (encoder.open(s, pid)) then

That will attempt to open the code with the encoder. If it returns true, the load was successful. It if returns false, the load wasn't successful. Again, pid refers to the player id of the player. s refers to the code.

You have to rip the little -load portion out of the s, which is a portion of what my jumbled mess of code above does.

So, just read...
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, DataBuffer.read())

Sets the player's gold to what's read.

call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, DataBuffer.read())

Sets the player's lumber

CreateUnit(p, Catalog.Hero[DataBuffer.read()], PercentToX(DataBuffer.read()), PercentToY(DataBuffer.read()), PercentToFacing(DataBuffer.read()))

That does a whole bunch of reading. First, it reads the hero. Catalog.Hero will convert a hero id into a unit type id.

Catalog.Hero[DataBuffer.read()]

Then it reads the percent x. PercentToX will convert the percent x into a valid x coordinate.

PercentToX(DataBuffer.read())

Then the percent y and percent facing. It uses all of this to create a unit.

Next, it reads the level
set lvl = DataBuffer.read()

I stored it into a variable because if you try to set the level of a level 1 unit to 1, it'll set it to 2... it's a funky bug.

JASS:
            if (lvl > 1) then
                call SetHeroLevel(u, lvl, false)
            endif

That essentially says to only set the hero level if the level is bigger than 1 ;P. Bug avoided ;D.

Then I add the percent hero xp with the special function
call AddPercentHeroXP(u, DataBuffer.read())

Notice I'm just reading everything in the same order that I wrote.

And here comes the stats
JASS:
            call SetHeroStr(u, DataBuffer.read(), true)
            call SetHeroAgi(u, DataBuffer.read(), true)
            call SetHeroInt(u, DataBuffer.read(), true)

The true makes them permanent.

And then I read life and mana
JASS:
            set lp = DataBuffer.read()
            set mp = DataBuffer.read()

Remember, I read life and mana while the hero gear was on, so first I need to add the gear to the hero and then set the life and mana. That's why I just didn't set it out right.

Add all the gear
JASS:
            set i = UnitInventorySize(u)
            set i2 = 6-i
            loop
                set i = i - 1
                call UnitAddItemToSlotById(u, Catalog.Item[DataBuffer.read()], i)
                call SetItemCharges(UnitItemInSlot(u, i), DataBuffer.read())
                exitwhen i == 0
            endloop
            loop
                exitwhen i2 == 0
                call DataBuffer.read()
                call DataBuffer.read()
                set i2 = i2 - 1
            endloop

Same deal with the 0s. If the hero had an inventory of 4, then I just read out a few 0s.

Now I set life and mana with my awesome percent functions
JASS:
            call SetPercentUnitLife(u, lp)
            call SetPercentUnitMana(u, mp)

Then the first pet
JASS:
            set u = CreateUnit(p, Catalog.Pet[DataBuffer.read()], PercentToX(DataBuffer.read()), PercentToY(DataBuffer.read()), PercentToFacing(DataBuffer.read()))
            set pet1[pid] = u
            call SetPercentUnitLife(u, DataBuffer.read())
            call SetPercentUnitMana(u, DataBuffer.read())

And the other 3 pets ;|

JASS:
            set u = CreateUnit(p, Catalog.Pet[DataBuffer.read()], PercentToX(DataBuffer.read()), PercentToY(DataBuffer.read()), PercentToFacing(DataBuffer.read()))
            set pet2[pid] = u
            call SetPercentUnitLife(u, DataBuffer.read())
            call SetPercentUnitMana(u, DataBuffer.read())
            
            set u = CreateUnit(p, Catalog.Pet[DataBuffer.read()], PercentToX(DataBuffer.read()), PercentToY(DataBuffer.read()), PercentToFacing(DataBuffer.read()))
            set pet3[pid] = u
            call SetPercentUnitLife(u, DataBuffer.read())
            call SetPercentUnitMana(u, DataBuffer.read())
            
            set u = CreateUnit(p, Catalog.Pet[DataBuffer.read()], PercentToX(DataBuffer.read()), PercentToY(DataBuffer.read()), PercentToFacing(DataBuffer.read()))
            set pet4[pid] = u
            call SetPercentUnitLife(u, DataBuffer.read())
            call SetPercentUnitMana(u, DataBuffer.read())


Hopefully you now know how to use Encoder =P. This was just how I decided to do it in the demo map, but you can do w/e you like for catalogs and you don't necessarily have to load up all of this data. You can build whatever encoder you like ^)^.

As I said, the code is actually pretty simple and you could probably handle it without any problems, it was just my implementation that turned kind of complicated =P.

And again, the save/load code in the map packs all of this
JASS:
/*
    Gold:   688620
    Lumber: 888649

    Bronze Drake 
        upper right
        facing out

    Black Drake
        upper left
        facing in

    Gnoll
        Bottom left (close)
        facing out

    Furbolg Elder Shaman
        Right
        facing out

    Far Seer
        Center
        Facing up

    Level:  7
    xp:     2742

    Strength:       27
    Agility:        24
    Intelligence: 37

    Scepter of Mastery
                        3/3

    Celestial Orb of Souls
                        0/0

    Orb of Venom
                        0/0

    Greater Scroll of Replenishment
                        1/1

    Serathil
                        0/0

    Shimmerglaze Roast
                        5/6

    Mana:   365
    Hp:     665

    Name saving code: 
        WorldEdit

    Code:
        10%O (ijD k@Oa ?@<f Oe4a &sha J%AP wQlV 0pHZ tbF1 (vE0 n&ZQ Rk3^ tA4$ eD
*/

Notice how small the code is for that insane amount of data. In pretty much any other save/load code, you are probably looking at 110+ characters. That code I have there is 58 characters long. That is a LOT shorter than 110 no? : P
 
Status
Not open for further replies.
Top