HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Advanced Save Codes - Not for the Faint of Heart!

11-26-2004, 07:29 PM#1
Taelrie
Intro
First off this is a tutorial -- not a CnP trigger. This save code is directly from my map, and so chances are it won't be adequate for your map, and im not explaining what everything does for the fun of it. In fact that is why I specifically defined variables as I went along as opposed to putting it all at the front, so it would be harder to copy it without understanding it. It is SO much better to grit it and make a save code for your map, instead of trying to adjust your map to the save code (which is what I tried and failed at in the start), so make an effort and learn the trigger instead of copying it.

Also this is somewhat advanced, if you want a great basic save code trigger tutorial check out JohnFms Save+Load code tutorial , considering I used his trigger as a base for mine, it might be a good idea to check that first.

Btw I have had people ask me about what arrays are all the time, just think of it as a whole bunch of variables with the same name (the array is the number of variables with that name).

Why I hate the Dewey Decimal System
If you want the greatest selection for the save code numbers are bad, very, very, bad (unless working with large numbers at least) Let me explain this to you, so you will understand how the rest of my code works.

The numeric system has only ten combinations (0, 1, 2, etc.) for one digit, and 100 combinations for two digits. However there is 69 feasible enterable keyboard combinations for one digit.

Now to understand the significance of this, let me explain it to you. If you tried to save, say, items, you could only have 10 saveable choices if you wanted to use one digit. if you used the keyboard system, you could have 69. If you had more then 69 items, 2 digits with numerics would give you 100 possible items that you could save. With the keyboard system, you could save up to 4761 items. Which would you rather use? Granted you could stick in a bunch of other digits, but the idea is to keep the code as short as possible (ive tried to shorten this down as much as possible but even so its still nearly 50 characters)

Setting up starting variables
Lots of starting variables for this... Usually however you want to spread out your initilization triggers on a map that would use this save code (if its big enough). A prime example of this is dark lineage, where he sets initilization triggers over 30 seconds to prevent lag. Thus set it up as an inilization trigger, but as a general advice try to set it up before they can load/save but not at initilization. Anyway... the code.

Also Pay attention to the name of the trigger in the code section, if its the same name and doesn't have any event/condition that doesn't mean its a new trigger, but starting from an interruption in the previous trigger (most likely an explanation). Finally if there is no initial value for the triggers, then it wont' be mentioned. Also the variables that are mentioned are for that particular trigger, but might be used later (in which case ill mention in the next trigger, but won't say the details)

Code:
Variables Needed (if not defined earlier):
UnencryptedCode [Type: String] [Initial Value: ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()_=+[{]}*|;:'",<.>/?-  \\Include the hyphon at the end]
SaveCode [Type: String] [Array = 1296]
ItemSets [Type: ItemType] [Array = \\Whatever number of items you want to save]
SpellSets [Type: Ability] [Array = \\Whatever number of spells you want to save]
HeroSets [Type: UnitType] [Array = \\Whatever number of heroes you want to save]
LoopingItems [Type: Integer] \\Note, if you like to use custom text, you can put this as a local variable


Setting Save Code Vars
           Event - Map Initilization
           Conditions -
            Actions -
                   For each (Integer A) from 1 to 36, do (Actions)
                          Loop - Actions
                                  For Each (Integer B) from 1 to 36, do (Actions)
                                         Set SaveCode[LoopingItems] = ((Substring(UnencryptedCode, (Integer A), (Integer A))) + (Substring(CodeSetNormal, (Integer B), (Integer B))))
                                     Set LoopingItems = (LoopingItems + 1)
What this does is basically setting the variable with the letters you will use throughout the code as identification. How this works is it adds the substring from the A loop, so when its starting with the first looping it would add to the variable A, and then it does the same thing with the second loop. In the end it would look like AA, AB, AC, etc. until ZZ, which every letter taking up a seperate array.

Also you might have noticed that I used 1-36, insteald of 1-69. This is because 1-36 on the variable only includes a-z and 1-10. This still has 1296 possible saves (which should be more then enough), and I have noticed that if you set up loops that are too large (somewhere around 3,000) The trigger will actually stop working past that point (you can still restart it but it will only work up the loop then crash again). I have been fiddling around with this, but it has pissed me off to no end so if thats a problem try to isolate it and find ways to lower the amount of the loop. Not only that but symbols can sometimes be hard to decipher from one another and makes it easier for the person to copy down.

Anyway lets continue

Code:
           Actions -
                   \\Don't set ItemSets[1] or SpellSets[1], you will see why
                   Set ItemSets[2] = \\whatever spell you plan to save, one for each array
                   Set SpellSets[2] = \\whatever spell you plan to save (if you plan to use tombs to learn spells at least, otherwise just let them choose from the hero skill menu and get rid of anything that has to do with spells), one for each array
                    Set HeroSets[1] = \\Whatever hero you plan to save, one for each array
This is the grunt work of the whole thing. This is just setting up all the stuff you plan to save

Code:
Variables Needed:
Units[Type: Unit] [Array: 12]

SettingUnits
          Events -
                Unit - A unit enters Rect<Gen>
          Conditions - 
                 ((Triggering Unit) is A Hero) Equal to True
           Actions - 
                  Set Units[(Player number of (Owner of (Triggering Unit))))] = (Triggering Unit)
This just sets the hero to use later on

Save Code
Whew! lets start the actual code! lots of variables here, so make sure not to get confused

Code:
Variables Needed:
UnencryptedCode(Defined Earlier)
Units(Defined Earlier)
EncryptedCode [Type: String] [Initial Value: \\Just take the unencrypted code and scramble it about. This will make sure it is a unique code, you MUST keep the - at the end though]
SaveProof [Type: Boolean] [Array: 12] [Initial Value: True]
PasswordParts [Type: String]

SaveCode
        Event -
Player - Player 1 (Red) types a chat message containing -save as an Exact Match \\Just continue the events from 1-12 for each player
        Conditions -
               SaveProof[(Player number of Triggering Player))] Equal to True
               Units[(Player number of (Triggering Player))] Not Equal to No Unit
        Actions - 
                Set PasswordParts = Empty String
                If ((Hero Level of (Units[Player number of (Triggering Player)]) Greater than 9) then Do (Set PasswordParts = (PasswordParts + (String((Hero Level of (Units[Player number of (Triggering Player)]) else do (Set PasswordParts = (PasswordParts = (0 + (String(Hero Level of Saving_Unit)))))
Wow, thats a long if statement. Basically what this does is checks if the level of the hero is greater then 10, and if it isn't adds a 0 in front of the number so it stays to two digits (length is very important). The conditions just make sure that he hasn't saved already (You will set saveproof to false in the end), and that he has a hero

Anyway Continuing
Code:
Variables Needed:
Gold [Type: Integer]
           Actions -
                  If ((Length of (String((Triggering Player) Current Gold)))) Greater than or equal to 5) Then do (Set PasswordParts = (PasswordParts + (Substring((String(((Triggering Player) Current Gold))), 1, 4))) else do Set PasswordParts = (PasswordParts + (String(((Triggering Player) Current Gold))))
                   Set 
                   If (All Coditions are True) then do (Then Actions) Else do (Else Actions)
                           If - Conditions
                                  ((Triggering Player) Current gold) Greater than or Equal to 100
                            Then - Actions
                                    Set Gold = (Substring((String (((Triggering Player) Current gold))), 1, ((Length of (String(((Triggering Player) Current gold))) - 2)))
                            Else - Actions
                                     Set Gold = (Substring((String(((Triggering Player) Current Gold)), 1, 1))
                  Set PasswordParts = (PasswordParts + (Substring(XXXX, 1, (4 - (Length of Gold)))))
The first part checks if the amount of gold the person has. If it is more then 4 digits long, it sets it to four. This will save up to 999900, as later we will multiply it by 100. The second part pretty much does the same thing but instead sets it to a variable for the next part. Then it pads it for the amount of Xs needed to even the code length.

To continue

Code:
Variables Needed:
Units (Defined Earlier)
HeroSets (Defined Earlier)
PasswordParts (Defined Earlier)

           Actions -
                  For Each (Integer A) from 1 to \\Number of HeroTypes// Do (Actions)
                         If - Conditions
                                    (Unit-Type of Units[Player number of (Triggering Player)] Equal to HeroSets[Integer A])
                         Then - Actions
                                    Set PasswordParts = (PasswordParts + (String((Integer A)]
                                    If (All Conditions are True) Then do (Then Actions) else do (else Actions)
                                            If - Conditions
                                                      (Integer A) Greater then or Equal to 0
                                                      (Integer A) Less then or Equal to 9
                                            Then - Actions
                                                      Set Passwordparts = (PasswordParts + 0)
                                            Else - Actions
                         Else - Actions
This basically finds out what type of hero the particular hero is and saves it to the password accodingly.

Now for the items

Code:
Variables Needed:
Units (Defined Earlier)
ItemSets (Defined Earlier)
PasswordParts (Defined Earlier)
           Actions -
                     For Each (Integer A) from 1 to 6 do (Actions)
                                 If (All Conditions are True) Then do (Then Actions) Else do (Else Actions)
                                            If - Conditions
                                                       (Item Carried by Units[Player Number of (Triggering Player) in Slot (Integer A)) Equal to No Item
                                            Then - Actions
                                                       Set PasswordParts = (PasswordParts + SaveCode[1])
                                            Else - Actions
                                                       For Each (Integer B) from 1 to \\Number of Items// Do (Actions)
                                                                  If (All Conditions are True) Then do (Then Actions) Else do (Else Actions)
                                                                             If - Conditions
                                                                                       Item Carried by Units[Player Number of (Triggering Player) In Slot (Integer A)) Equal to ItemSets[Integer B]
                                                                             Then - Actions
                                                                                        Set PasswordParts = (Password Parts + SaveCode[Integer B])
                                                                             Else - Actions
What this does is it goes through every slot on the person. If he has an item, it checks for the item with the variable and saves accordingly, if not it sets it to AA.

Now Saving Spells is a lot harder, as there is no way to define what slot you are saving the spell from. Thus you have to remove spells as you go, and ultimately that is the only reason you have to remove the character at the end. To get around that you can run the loadcode with the finished savecode, ignoring conditions to get the same hero back, but I don't cover that in this particular tutorial.

Code:
Variables:
SpellSets (defined)
Units (Defined)
PasswordParts (Defined)
           Actions-
                      For Each (Integer A) from 1 to 7, do (Actions)
                                 Loop - Actions
                                            For Each (Integer B) from 1 to \\amount of spells//, do (Actions)
                                                       Loop - Actions
                                                                  If (All Conditions are True) Then do (Then Actions) Else do (Else Actions)
                                                                             If - Conditions
                                                                                        (Level of SpellSets[Integer B] for Units[Player Number of (Triggering Player)] Greater then 0
                                                                             Then - Actions
                                                                                        Set PasswordParts = (PasswordParts + SaveCode[(Integer B)]
                                                                                        Set PasswordParts = (PasswordParts + (String((Level of SpellSets[(Integer B]) for (Units[Player number of (Triggering Player)])
                                                                                        Remove SpellSets[(Integer B)] from Units[Player number of (Triggering Player)]
                                                                             Else - Actions
                                                                                        If ((Integer B) Equal to \\Number of Spells//) then (set PasswordParts = PasswordParts + AA0) Else (Do Nothing)
What this does is it checks each spell against the list you defined earlier, and if it finds one adds it to the code and removes it from the person. If it can't find anything (by going to the amount of spells there is and finding nothing), then it adds AA0 (or the "nothing") to the code.

Now for the Player name

Code:
Variables: 
PasswordParts (Defined Earlier)
PlayerName (String)

           Actions - 
                      Set Player Name = (Name of (Triggering Player))
                      For each (Integer B) from 1 to 15, do ((If Length of Playername) Equal to (Integer B)) then do (Set Playername = Playername + Z)) Else do (Do Nothing)
                      Set Playername = Substring(Playername, 1, 3)
                      Set Playername = (String(Playername) as Upper Case)
                      Set PasswordParts = (PasswordParts + PlayerName)
This first gets the name of the player, and then pads it with Xs until it is 15 characters long (15 is the largest size someone's name cna be). Then it takes the first 3 letters of the person's name and puts it in the code.

Now that we have the information, it is time to encrypt it!
Code:
Variables:
OutPutCode (String, Array = length of string + the multiples of 6, read below)
OutPutCodeNum (Integer, init. Value 1)

           Actions-
                      Set OutPutCode = Empty String
                      Set OutPutCodeNum = 1
                      For Each (Integer A) from 1 to 53\\or whatever the length of your code is + the multiples of 6, do (Actions)
                       If (All Conditions are True) Then do (Then Actions) else do (Else Actions
                                 If - Conditions
                                            (Integer A) not Equal to 6
                                            (Integer A) not Equal to 12
                                            \\Continue in multiples of six until the next multiple takes you past the end of the code including the dashes, in this case the last would be 48
                                 Then - Actions
                                            Set OutPutCode[(Integer A)] = (Substring(PasswordParts, OutPutCodeNum, OutPutCodeNum))
                                            Set OutPutCodeNum = (OutPutCodeNum + 1)
                                 Else - Actions
                                            Set OutPutCode[(Integer A)] = -
Now that probably was very confusing, with the multiples of 6 and all that. Basically what this does is it seperates every 5 digits with a dash. This makes it SOOOOO much easier to copy down, although lengthening the code a bit. The point of OutPutCodeNum is to make sure you are staying on track with the original passwordparts, as there is obviously going to be less in that code then 53

Now to scramble the code
Code:
Variables
OutPutCode2 (String)
           Actions - 
                      Set OutPutCode2 = Empty String
                      For Each (Integer A) from 1 to 53, do (Actions)
                                 Loop - Actions
                                            For Each (Integer B) from 1 to 69, do (Actions)
                                                       Loop - Actions
                                                                  If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                                                             If - Conditions
                                                                                        OutPutCode[(Integer A)] Equal to (SubString(CodeSetNormal, (Integer B), (Integer B))
                                                                             Then - Actions
                                                                                        Set OutPutCode2 = (OutPutCode2 + (Substring(CodeSetEncrypted, (Integer B), (Integer B))))
                                                                             Else - Actions
This is the real encryption. What it does is it takes the letter from each part of the code, and switches it with the letter from the scrambled part of the code. Simple as that.

Now to reverse the code, you might recognize this from the basic save code
Code:
Variables: 
OutPutCode3 (String)
OutPutCode2 (Defined Earlier)
           Actions -
                      For Each (Integer A) from 0 to ((Length of OutPutCode2) - 1), do (Actions
                                 Loop - Actions
                                            Set OutPutCode3 = (OutPutCode3 + (Substring(OutPutCode2, ((Length of OutPutCode2) - (Integer A)), ((Length of OutPutCode2) - (Integer A) + 0))))
That just reverses the code

And now lets color code it!
Code:
Variables:
OutPutCode3 (Defined Earlier)
FinalCode (String)
           Actions-
                      For Each Integer A from 1 to 53, do (Actions)
                                 Loop - Actions
                                            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                            If - Conditions
                                                       or - Any (Conditions) are true
                                                                  Conditions
                                                                             Substring(OutPutCode3, (Integer A), (IntegerA) Equal to -
                                                                             Substring(OutPutCode3, (Integer A), (Integer A) Equal to 0
                                                                             Substring(OutPutCode3, (Integer A), (Integer A) Equal to 1
                                                                             \\Continue this until you get up to 9, I tried used greater/lesser but it didn't work.
                                            Then - Actions
                                                       Set FinalCode = (Final Code + (|1C86EE)+(SubString(OutPutCode3, (Integer A), (Integer A) + |r)
                                            Else - Actions
                                                       \\Do the same as you did for the then actions, but using a different color.
          Set SaveProof[(Player Number of (Triggering Player))] = False
          Set LoadProof[(Player Number of (Triggering Player))] = False
          Unit - Remove Units[(Player Number of (Triggering Player))] From the game.
          Game - Display to (Triggering Player) for 300 Seconds (FinalCode +  is your code, enjoy and play again!

OMG WE ARE DONE WITH THE SAVE CODE!

Load Code
Code:
Variables:
CodeSetNormal (Defined Earlier)
CodeSetEncrypted (Defined Earlier)
LoadString1 (Type: String)
LoadString2 (Type: String)
LoadString4 (Type: String)
LoadCode (Type: Integer)

LoadCode
           Events-
                      Player 1 (red) types a chat message containing -load as a substring
                      \\Just copy that until you get to player 12
           Conditions-
                      (Length of(Entered Chat String)) Equal to 59 \\or whatever your code length is + 6
                      LoadProof is Equal to True
           Actions-
                      Set LoadString1 = (SubString((Entered Chat String), 6, (Length of (Entered chat string)))
                      Set LoadString1 = (String((LoadString1) As Upper Case)
                      Set LoadString2 = Empty String
                      Set LoadString4 = Empty String
                      Set LoadCode = 1
                      For Each (Integer A) from 0 to ((Length of LoadString1) - 1), do (Set LoadString2 = (LoadString2 + (Substring(LoadString1, (Length of LoadString1) - (Integer A)), ((Length of LoadString1) - (Integer A)))))
                      
All this does is it sets everything back to default (in case someone has already saved), saves the code without the -load (the load part takes 6 characters, that is why you only take the code 6 onwards and why the length is whatever the code is + 6) in front of it, and unreverses the code so it can be unencrypted.

Code:
Variables:
LoadString3 (Type: String) (Array: //Whatever length the code is without dashes)
LoadString2 (Defined Earlier)
           Actions-
                      For Each (Integer A) from 1 to (Length of LoadString2), do (Actions)
                                 Loop - Actions
                                            If (All Conditions Are True) then do (Then Actions) else do (Else Actions)
                                                       If - Conditions
                                                                  (SubString(LoadString2, (Integer A), (Integer A))) Not Equal to -
                                                       Then - Actions
                                                                  Set LoadString3[LoadCode] = (SubString(LoadString2, (Integer A), (Integer A))
                                                                  Set LoadCode = (LoadCode + 1)
                                                       Else - Actions
This basically just takes out the dashes. Although a help to copy down they just get in the way when deciphering the code.

Code:
Variables:

           Actions-
                      For Each (Integer A) from 1 to 45, do (Actions)
                                 Loop - Actions
                                            For Each (Integer B) from 1 to 69, do (Actions)
                                                       Loop - Actions
                                                                  If (All Conditions are True) then do (Then Actions) Else do (Else Actions)
                                                                             If - Conditions
                                                                                        LoadString3[(Integer A)] Equal to (Substring(CodeSetEncrypted, (Integer B), (Integer B)))
                                                                             Then - Actions
                                                                                        Set LoadString4 = (LoadString4 + (SubString(CodeSetNormal, (Integer B), (Integer B))
                                                                             Else - Actions
This is basically doing the reverse of what we did for encrypting, by matching the encrypted part and replacing it with the corresponding unencrypted part.

Code:
Variables:
Playername(Defined Earlier)

           Actions-
                      Set Playername = Name of (Triggering Player)
                      (For Each (Integer B) from 1 to 15, do (If (Length of PlayerName) Equal to (Integer B) Then do (Set Playername = PlayerName + Z)) else do (Do Nothing)
                      Set Playername = (Substring(Playername, 1, 3))
                      Set Playername = (String(Playername) As Upper Case)
This just sets up the playername for identification later. Now for this next part I can't help you much, as the information in your code will probably be in different intervals then mine. Thus count up your code for what information goes where, and act accordingly (also remember to count 0, 1, 2, for example 43-45 is 43, 44, and 45 although it looks like 2 numbers). Also note I had an extra number, called Race, which defined what race people were in my RPG. However I didn't include that in the tutorial, so if you are counting one number off (since I didn't adjust the length of the code as well) that is why (didn't feel that extra variables would prove anything in the save code).

Code:
Variables:
LoadString4 (Defined Earlier)
Race (the unmentioned variable)
HeroSets (Defined Earlier)

           Actions-                      
                      If (Substring(LoadString4, 43, 45)) Not Equal to Playername Then do (Skip Remaining Actions) Else do (Do Nothing)
                      Set Race[(Player number of (Triggering Player)] = (Integer(Substring(Loadstring4, 42, 42))))
                      Wait .01 seconds
                      Unit - Create 1 HeroSets[(Integer((Substring(Loadstring4, 7, 8))))] for (Triggering Player) at (Center of StartingCity<gen>) Facing Default Building (270.0) degrees
This basically just checks if the player is the player who owns the save code, and if he is then continues, and creates the hero.

Code:
Variables:
LoadingHero (Type: Unit)
Loadstring4 (Defined Earlier)

           Actions-
                      Set LoadingHero = (Last Created Unit)
                      If (Integer((Substring(LoadString4, 1, 2))) Greater then or Equal to 10) Then do (Hero - Set LoadingHero Hero-Level to (Integer(Substring(Loadstring4, 1, 2))), Hide Level-up Graphics, Else do (Hero - Set LoadingHero Hero-Level to (Integer((Substring(Loadstring4, 2, 2))) Hide level-up Graphics)
Wow that is a long if statement (again). Basically this checks if those two numbers were greater then 10 (we put a 0 in front of the number if they weren't to pad it earlier), and if they weren't we only took the number that mattered. Now I am not sure if they would accept 0X instead of just X for the number, but I didn't bother to test it so if you can you can just void the entire if statement and use the right numbers.

Code:
Variables:
Loadstring4 (Defined Earlier)
Gold2 (type: String)

           Actions-
                      Set Gold2 = Empty String
                      For Each (Integer A) from 1 to 4, do (Actions)
                                 Loop - Actions
                                            If (All Conditions are True) Then do (Then Actions) Else do (Else Actions)
                                                       If - Conditions
                                                                  (Substring((Substring(Loadstring4, 3, 6((Integer A), (Integer A)), Not Equal to X
                                                       Then - Actions
                                                                  Set Gold2 = (Gold2 + (Substring((Substring(Loadstring3, 3, 6)), (Integer A), (Integer A)))
                                                       Else - Actions
                      Player - Set (Triggering player) Current Gold to (Integer(Gold2 X 100))
This basically just sets the gold for the player. if you remember we divided the gold by 100 to fit better in the code, so that is why we multiply it by 100, and the X's were padding for the code so that had to be taken away.

Now for items and spells it is basically the same action over and over
Code:
           Actions-
                      For each(Integer A) from 1 to \\Amount of Saveable Items// do (Actions)
                                 Loop - Actions
                                            If ((Substring(LoadString3, 9, 10)) Equal to Letters[(Integer A)]) then do (Hero - Create Item[(Integer A)] and give it to LoadingHero) else do (Do nothing)
                      For each(Integer A) from 1 to \\Amount of Saveable Items// do (Actions)
                                 Loop - Actions
                                            If ((Substring(LoadString3, 11, 12)) Equal to Letters[(Integer A)]) then do (Hero - Create Item[(Integer A)] and give it to LoadingHero) else do (Do nothing)
                                   \\Keep on doing this until you finish all 6 slots (for me it finishes with 19 and 20)
This basically just creates the items for the person

Code:
Variables:
LoadSpells (Integer)
Loadstring4 (Defined Earlier)

Actions-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    If - Conditions
        (Substring(LoadString3, 21, 22)) Not equal to AA
    Then - Actions
        For each (Integer A) from 1 to 676, do (Actions)
            Loop - Actions
                If ((Substring(LoadString3, 21, 22)) Equal to Letters[(Integer A)]) then do (Unit - Add Spells[(Integer A)] to LoadingHero) else do (Do nothing)
                If ((Substring(LoadString3, 21, 22)) Equal to Letters[(Integer A)]) then do (Set LoadSpells = Spells[(Integer A)]) else do (Do nothing)
    Else - Actions
If ((Substring(LoadString3, 21, 22)) Not equal to AA) then do (Unit - Set Level of LoadSpells for (Triggering unit) to (Integer((Substring(LoadString3, 23, 23))))) else do (Do nothing)
\\Continue this for each spell, for me ending at 41 (3 numbers for each spell)
Set LoadProof[(Player number of (Triggering player))] = False
This sets the spells, and then if the spell exists sets the level for it

And omg we are finally done with the load part too. Congratulate yourself for being able to read all of this stuff without your head exploding!

Any feedback is much appreciated, as shallow as it sounds I do kind of write these to hear how it helps people. Anyway enjoy! Also if you find any mistakes (And I can almost guarantee there will be 2-3) please say so, same with if there is any questions.
12-14-2004, 07:20 PM#2
Mortiegama
OutPutCode (String, Array = length of string + the multiples of 6, read below)

It's a little unclear here as to what I'm supposed to do. There is no selection to enter multiples in the World Editor, unless you're using a modded version.

Also another thing I'd like to mention is that HeroSets and ItemSets should be Unit Type and Item Type, not just Unit or Item, that way you can select from a list as opposed to having to pick something already on the map.
12-16-2004, 08:20 PM#3
Taelrie
Quote:
Originally Posted by Mortiegama
OutPutCode (String, Array = length of string + the multiples of 6, read below)

It's a little unclear here as to what I'm supposed to do. There is no selection to enter multiples in the World Editor, unless you're using a modded version.

Also another thing I'd like to mention is that HeroSets and ItemSets should be Unit Type and Item Type, not just Unit or Item, that way you can select from a list as opposed to having to pick something already on the map.

Well basically you want to make the amount of arrays the length of the code, but you also want to add on extra arrays for the dashes that will be put in the variable with the code itself. We want dashes to separate every 5 digits of the code, so we put it at every 6th multiple. If you want to play it safe set the array to something like 100, it doesn't matter if there is more arrays then what you will use (it raises the size of the file, though by a negligible amount. However do this too often and there will be noticeably longer load times).

And yes they are supposed to be types. And where is all the replys, there is something like 200 views and this is the first. I didn't spend nearly 6 hours writing this for it to be ignored, and yes it is shallow but the important thing is it gets the information across ^_^ .
01-19-2005, 03:45 AM#4
neostorm
http://www.wc3sear.ch/?p=Spells&ID=592
is all i have to say, taelrie i would look at your code more but since i can't find a working verson so i'll pass. I suggest you look at this save system if you are really intrested in save codes. This is a working verson... I really dont code much any more but i suggest you look at it since you think you know enough to instruct others on how to do it.
01-20-2005, 09:07 PM#5
Taelrie
Quote:
Originally Posted by neostorm
http://www.wc3sear.ch/?p=Spells&ID=592
is all i have to say, taelrie i would look at your code more but since i can't find a working verson so i'll pass. I suggest you look at this save system if you are really intrested in save codes. This is a working verson... I really dont code much any more but i suggest you look at it since you think you know enough to instruct others on how to do it.

Im not sure how this got started but the code works. it has always worked, and no maps currently use this code (working or no). I made it in my spare time since the best save code I saw on this website was just a basic tutorial on making them, and nothing advanced and I figured it could help people. Copy this code down and it will work fine, im not sure why you are saying it won't. I have put it in a trigger and tried it out myself, it works fine.

If you are complaining about not finding a map in wc3search that has the trigger, thats because its a tutorial and I prefer people to copy it through so they can understand what they are doing. I mentioned that at the top, you can't read a couple paragraphs then complain that it doesn't work with what you read.

EDIT (realised that this was just a publicity stunt for your map):I don't want to turn this into a flame thread but bottom line this isn't a place to advertise your work. If people want to download it, they will, you don't go to places and slander other people's work and then say yours is much better. This is to learn how to make more advanced save codes, you shouldn't complain, and more specifically lie about anything else that does a similar job. I would like to believe you were just too lazy to read all the code, and decide its too complicated and just say its wrong but if you know how to write a similar save code I doubt that. Thus... if an administrator is reading this can I ask to delete the above post? I don't want to turn this into a flame war or a place to slander other people's work (whether mine or his)

Sorry if that sounds harsh but I dont' take it too well when someone can't even be bothered to read the code before complaining about it and saying its wrong, and then goes and promotes his "better" work over it. I would hardly say that is productive, and considering I am not trying to make an opinion and just giving a tutorial, it is just plain stupid to complain about it without giving any helpful advice; hardly constructive criticism. I appreciate that you are working to forward the knowledge of people but to do it by stepping on other people and lying about their work is just inhumane, we aren't in competition so try working together rather then slandering other work.
01-21-2005, 10:04 AM#6
MeTaCo
Ok ur save code makes a lot of sense taking the time reading it, but I'm stuck.. I read this line over and over again

(Set PasswordParts = (PasswordParts = (0 + (String(Hero Level of Saving_Unit)))))

how can u put 2 equivelant when it's only a 2 Variables only?
did u put it as a typo?
01-21-2005, 11:06 AM#7
MeTaCo
err I found more errors... how can u do substrings when gold is set to as integer... integer u'd have to use integer's and not use substrings unless u convert.... I trust in ur save code.. and reason for not replying earlier was coz I'm undergoing a map, and I was waiting for the right time to build the trigger... could u maybe upload the map to your save file? it would clearify a lot and allow us to help you figure out what is working and not working, thanks. Btw it's a good effort at least u try to put out the advance code
01-21-2005, 12:29 PM#8
Taelrie
Quote:
Originally Posted by MeTaCo
Ok ur save code makes a lot of sense taking the time reading it, but I'm stuck.. I read this line over and over again

(Set PasswordParts = (PasswordParts = (0 + (String(Hero Level of Units[Player Number of (Triggering Player))))))

how can u put 2 equivelant when it's only a 2 Variables only?
did u put it as a typo?

Well the purpose of that is if they are below 10 levels you put a 0 in front of it to keep it at 2 characters long. If you look before that part there is an if statement checking the level of the hero, and just sticking it down if its 10 or above. Later on in the load code I check for the 0 in front of it and remove it if its there.

Quote:
err I found more errors... how can u do substrings when gold is set to as integer... integer u'd have to use integer's and not use substrings unless u convert.... I trust in ur save code.. and reason for not replying earlier was coz I'm undergoing a map, and I was waiting for the right time to build the trigger... could u maybe upload the map to your save file? it would clearify a lot and allow us to help you figure out what is working and not working, thanks. Btw it's a good effort at least u try to put out the advance code

It actually is converted in the code, when you see the part of it that looks like (string((etc.etc.))))) (actually that is shown in your above question too, that is converting it from a string) That means is its converting it from a string. And I suppose ill make a save file =-P. Well a lot of peopel have been asking for a map with the save code so I supose ill convert it when I get home this afternoon.
01-21-2005, 10:25 PM#9
MeTaCo
Quote:
Originally Posted by Taelrie
Well the purpose of that is if they are below 10 levels you put a 0 in front of it to keep it at 2 characters long. If you look before that part there is an if statement checking the level of the hero, and just sticking it down if its 10 or above. Later on in the load code I check for the 0 in front of it and remove it if its there.



It actually is converted in the code, when you see the part of it that looks like (string((etc.etc.))))) (actually that is shown in your above question too, that is converting it from a string) That means is its converting it from a string. And I suppose ill make a save file =-P. Well a lot of peopel have been asking for a map with the save code so I supose ill convert it when I get home this afternoon.

Thx and sorry.. I tried to follow up.. I guess to me it doesn't look right since I just started using var and stuff not long ago, I don't know much about converting but at least I took the time to read ur thread tut and try to follow the best as possible, but like I said before this tut looks good, it is more understandable unlike others that use crc, I don't even know wut crc is... too much variables in other save codes, but this one u make is advance and it's not so confusing like the others, in the other hand Elil's save/load code system has a file, and it would take even longer trying to edit his save/load than to write a fresh one off of yours
01-22-2005, 06:04 AM#10
Taelrie
Quote:
Originally Posted by MeTaCo
Thx and sorry.. I tried to follow up.. I guess to me it doesn't look right since I just started using var and stuff not long ago, I don't know much about converting but at least I took the time to read ur thread tut and try to follow the best as possible, but like I said before this tut looks good, it is more understandable unlike others that use crc, I don't even know wut crc is... too much variables in other save codes, but this one u make is advance and it's not so confusing like the others, in the other hand Elil's save/load code system has a file, and it would take even longer trying to edit his save/load than to write a fresh one off of yours

That was kind of what I was trying to go for. The idea is for it to explain what everything does, and if you write the fresh code you basically either have to understand it or just copy it down word for word, in which case you sort of subconciously understand it. Just think of my tutorial as "taking notes" on how to make a save code. If you go to the trouble to copy it all down into your own code you can't do it wihtout learning something. Just repeat to yourself that it is taking a blank and filling it with information rather then restoring a character, it keeps everything in perspective. Sorry if it makes it harder but I am trying to make a tutorial, not a CnP trigger.

Bottom line is that if you learned something about triggers, whether you got the save code working or not, my work here is done .
01-22-2005, 01:21 PM#11
MeTaCo
ok, sorry but I'm going back to square 1, I know that u try to check the level to see if it is lower than lvl 10, that part I get btw back to this line"(Set PasswordParts = (PasswordParts = (0 + (String(Hero Level of Saving_Unit). My question is, by "hero Level of Saving_Unit," when u say saving_unit, is that a variable? or do you mean triggering unit, or triggering player?

btw are u still going to make a save map, coz I'm stuck badly still, it's fustrating!!

1 more thing, I'm also the only one posting.... :\
01-22-2005, 06:54 PM#12
Taelrie
Quote:
Originally Posted by MeTaCo
ok, sorry but I'm going back to square 1, I know that u try to check the level to see if it is lower than lvl 10, that part I get btw back to this line"(Set PasswordParts = (PasswordParts = (0 + (String(Hero Level of Saving_Unit). My question is, by "hero Level of Saving_Unit," when u say saving_unit, is that a variable? or do you mean triggering unit, or triggering player?

btw are u still going to make a save map, coz I'm stuck badly still, it's fustrating!!

1 more thing, I'm also the only one posting.... :\

Oh that was the variable I used in my map that used this code, I made a separate variable for Units[Player Number of (Triggering Player) because I didn't want to go through the hassle of typing that big thing in every single time. I took that out of this save code because I didn't want to confuse people more then they already are about unneeded variables, but apparantly I missed part of it. And I might still make that save code, but since I lost the original map that had it in a reformat of my computer and the entire reason I made this tutorial is so people could learn it, not just use it, I doubt I will. Sorry but trust me it is a lot easier if you just try to learn it instead of tryin to fit your map to the save code.
01-23-2005, 07:09 PM#13
neostorm
I'm not going to spend my time reconstructing your code in a map just to explain exactly what you could improve. I just know many people want save codes in their map. But they don't understand save how save codes work. In your case you clearly wanted to help those people which is fine I just posted my map for you to learn from. You clearly have a interest in save codes and your smart enough to explain it. I just think you should realize there are some flaws. I would of explained some of them but I didn't feel like reconstructing the code.

P.S. I was a bit rude in my first post but if you expect them to learn and write your code (since you didn't provided it in a map) then I think you should be teaching them a better way of doing it.

Here's my point what happens when a player tries to save hero that is level 100?
How about if they have more than 100 items?
So let me practice typing in your code

asdf-asdf-asee-asde-adfe-adfs-adfe-asfe-fgfr
seems pritty long

So if I want to crack your code then all I have to do is change the amount of gold i have and simply mark what part of your code changes each time a gain/lose gold.
Then I know what part of your code is gold and all I have to do is change that part.

Maybe I want to give myself 6 of the same item then all I have to do is move a item from slot to slot and typing -save wow that was easy.

People read tutorials for 2 reason to learn and to use. So your teaching is flawed and you offer nothing they can use without doing all the work themselves.

I think you were better off leaving it with my first post but as you wish.
01-24-2005, 02:41 AM#14
MeTaCo
Quote:
Originally Posted by neostorm
I'm not going to spend my time reconstructing your code in a map just to explain exactly what you could improve. I just know many people want save codes in their map. But they don't understand save how save codes work. In your case you clearly wanted to help those people which is fine I just posted my map for you to learn from. You clearly have a interest in save codes and your smart enough to explain it. I just think you should realize there are some flaws. I would of explained some of them but I didn't feel like reconstructing the code.

P.S. I was a bit rude in my first post but if you expect them to learn and write your code (since you didn't provided it in a map) then I think you should be teaching them a better way of doing it.

Here's my point what happens when a player tries to save hero that is level 100?
How about if they have more than 100 items?
So let me practice typing in your code

asdf-asdf-asee-asde-adfe-adfs-adfe-asfe-fgfr
seems pritty long

So if I want to crack your code then all I have to do is change the amount of gold i have and simply mark what part of your code changes each time a gain/lose gold.
Then I know what part of your code is gold and all I have to do is change that part.

Maybe I want to give myself 6 of the same item then all I have to do is move a item from slot to slot and typing -save wow that was easy.

People read tutorials for 2 reason to learn and to use. So your teaching is flawed and you offer nothing they can use without doing all the work themselves.

I think you were better off leaving it with my first post but as you wish.

ahhh not bad, I didn't see u post ur map till now, but for some reason I can't save the char on blood mage :\ well I didn't read much just tested your map, I did so because Since I can't get the save/load code from a raw map of taelrie, I decided to read up the whole thing on E-lil's save/code. a few things went wrong in his save/load, but I managed to fix them since I tried to do taelrie's save/code, a lot of confusing stuff there taelrie, but trying it and gettting no where, I actually learned some integer and stuff, got use to using array, started to think and I wrote up a fixture for e-lil's trigger, even made a random unit spawn/unit type during a specified time of the day, anyhow + rep for u neostorm for having a map demo! (p.s.) I learned crc and wut it was meant for from reading e-lil's tut, crc is a data search, searching for data as well as errors! GG
01-24-2005, 02:43 AM#15
MeTaCo
btw neostorm nice way of putting how people can find out about how the save/code works with the item and gold, a good tip for cheating, but is it worth the time trying to cheat?