• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[System]Save and Load System

Status
Not open for further replies.
Level 8
Joined
Apr 26, 2011
Messages
403
it depend on how much you want to save, eg
- what is value range for :
Hero kill: 0-1295 ? (2 digit)
Hero Death: 0-11295 ? (2 digit)
creep kills: 0-46655? (3 digit)
creep deaths: 0-46655? (3 digit)
Ranks : 0-1295? (2 digit)

Total code length for above range : 12 digit
 
Level 8
Joined
Apr 26, 2011
Messages
403
here is simple save/load system:

1, copy code below, paste into top of the map (in GUI).

those code are basic function for convert/encrypt.


Code:
//+-----------------------------------------------------------------------------
//| Prepares the char table. Call this function once on map initialization.
//| Make sure you have a global string array variable named "CharTable"
//| ("udg_CharTable"), otherwise this function will not compile. The size of
//| the array should be 70, but that is not important since arrays are dynamic.
//+-----------------------------------------------------------------------------
function SetupCharTable takes nothing returns nothing
 //Sets the digits
 set udg_CharTable[0] = "0"
 set udg_CharTable[1] = "1"
 set udg_CharTable[2] = "2"
 set udg_CharTable[3] = "3"
 set udg_CharTable[4] = "4"
 set udg_CharTable[5] = "5"
 set udg_CharTable[6] = "6"
 set udg_CharTable[7] = "7"
 set udg_CharTable[8] = "8"
 set udg_CharTable[9] = "9"

 //Sets the capital letters
 set udg_CharTable[10] = "A"
 set udg_CharTable[11] = "B"
 set udg_CharTable[12] = "C"
 set udg_CharTable[13] = "D"
 set udg_CharTable[14] = "E"
 set udg_CharTable[15] = "F"
 set udg_CharTable[16] = "G"
 set udg_CharTable[17] = "H"
 set udg_CharTable[18] = "I"
 set udg_CharTable[19] = "J"
 set udg_CharTable[20] = "K"
 set udg_CharTable[21] = "L"
 set udg_CharTable[22] = "M"
 set udg_CharTable[23] = "N"
 set udg_CharTable[24] = "O"
 set udg_CharTable[25] = "P"
 set udg_CharTable[26] = "Q"
 set udg_CharTable[27] = "R"
 set udg_CharTable[28] = "S"
 set udg_CharTable[29] = "T"
 set udg_CharTable[30] = "U"
 set udg_CharTable[31] = "V"
 set udg_CharTable[32] = "W"
 set udg_CharTable[33] = "X"
 set udg_CharTable[34] = "Y"
 set udg_CharTable[35] = "Z"

 //Sets the small letters
 set udg_CharTable[36] = "a"
 set udg_CharTable[37] = "b"
 set udg_CharTable[38] = "c"
 set udg_CharTable[39] = "d"
 set udg_CharTable[40] = "e"
 set udg_CharTable[41] = "f"
 set udg_CharTable[42] = "g"
 set udg_CharTable[43] = "h"
 set udg_CharTable[44] = "i"
 set udg_CharTable[45] = "j"
 set udg_CharTable[46] = "k"
 set udg_CharTable[47] = "l"
 set udg_CharTable[48] = "m"
 set udg_CharTable[49] = "n"
 set udg_CharTable[50] = "o"
 set udg_CharTable[51] = "p"
 set udg_CharTable[52] = "q"
 set udg_CharTable[53] = "r"
 set udg_CharTable[54] = "s"
 set udg_CharTable[55] = "t"
 set udg_CharTable[56] = "u"
 set udg_CharTable[57] = "v"
 set udg_CharTable[58] = "w"
 set udg_CharTable[59] = "x"
 set udg_CharTable[60] = "y"
 set udg_CharTable[61] = "z"

 //Sets the special characters
 set udg_CharTable[62] = "("
 set udg_CharTable[63] = ")"

 //Sets the special characters
 //(These will NOT be encrypted)
 set udg_CharTable[64] = "."
 set udg_CharTable[65] = "-"
 set udg_CharTable[66] = "_"
 set udg_CharTable[67] = "["
 set udg_CharTable[68] = "]"
 set udg_CharTable[69] = " "

endfunction


//+-----------------------------------------------------------------------------
//| Converts an integer value (ASCII) to a character base on Character Table
//| eg, 61 -->"z",
//+-----------------------------------------------------------------------------
function ConvertIntToChar takes integer Value returns string
 return udg_CharTable[Value]
endfunction


//+-----------------------------------------------------------------------------
//| Converts Decimal to any Base.
//+-----------------------------------------------------------------------------
function ConvertToBase takes integer num, integer base returns string
	local integer m
	local string result = ""
	if(base<2)
		return result;
	endif
	if(nbase > 36)
		return result;
	endif
	loop
	    set m = ModuloInteger(num, base)
		set result = ConvertIntToChar[m] + result;
		set num = num/base
		exitwhen num >= base
	endloop
	return result
endfunction

//+-----------------------------------------------------------------------------
//| Converts a character to an integer value (ASCII)
//+-----------------------------------------------------------------------------
function ConvertCharToInt takes string Character returns integer

 local integer Index = 0

 //Traverses the ASCII table until the character is found.
 loop

   exitwhen udg_CharTable[Index] == Character
   set Index = Index + 1

   //If the character is not found, return 0
   if Index >= 70 then

     set Index = 0
     exitwhen true

   endif

 endloop

 return Index

endfunction

//+-----------------------------------------------------------------------------
//| Does a bitwise XOR on two integer values
//+-----------------------------------------------------------------------------
function BitwiseXOR takes integer Value1, integer Value2 returns integer

 local integer Index
 local integer ResultValue
 local integer array Byte1
 local integer array Byte2
 local integer array ResultByte

 //Convert Value1 to a Byte
 set Index = 8
 loop

   set Index = Index - 1
   set Byte1[Index] = ModuloInteger(Value1, 2)
   set Value1 = Value1 / 2
   exitwhen Index <= 0

 endloop

 //Convert Value2 to a Byte
 set Index = 8
 loop

   set Index = Index - 1
   set Byte2[Index] = ModuloInteger(Value2, 2)
   set Value2 = Value2 / 2
   exitwhen Index <= 0

 endloop

 //Makes a bitwise XOR on the Bytes
 set Index = 0
 loop
   if (Byte1[Index] == Byte2[Index]) then
     set ResultByte[Index] = 0
   else
     set ResultByte[Index] = 1
   endif
   set Index = Index + 1
   exitwhen Index >= 8

 endloop

 //Convert the resulting Byte back to an integer
 set Index = 0
 set ResultValue = 0
 loop

   set ResultValue = ResultValue * 2
   set ResultValue = ResultValue + ResultByte[Index]
   set Index = Index + 1
   exitwhen Index >= 8

 endloop

 return ResultValue

endfunction


//+-----------------------------------------------------------------------------
//| Takes a string and uses the key (usually a player's name) to encrypt it.
//| To get the original string back, call the function with that string and
//| the same key used in the encryption.
//+-----------------------------------------------------------------------------
function GeneratePassword takes string Code, string Key returns string

 local integer Index = 0
 local integer KeyIndex = 0
 local integer KeyLength = 0
 local integer CurrentValue = 0
 local integer CurrentKeyValue = 0
 local string CurrentCharacter = ""
 local string CurrentKeyCharacter = ""
 local string ResultCode = ""

 //Calculates the length of the Key
 loop

    exitwhen SubStringBJ(Key, KeyLength + 1, KeyLength + 1) == ""
    set KeyLength = KeyLength + 1

 endloop

 //Abort if the key length is 0 (to avoid crashes)
 if KeyLength <= 0 then

   return ""

 endif

 //Loop through every character in the string and encrypt it
 loop

   //Get a character from the code
   set CurrentCharacter = SubStringBJ(Code, Index + 1, Index + 1)

   //Exit when the end of the code string is reached
   exitwhen CurrentCharacter == ""

   //Converts a character to a value
   //Traverses the character table until the character is found
   set CurrentValue = 0
   loop
     exitwhen udg_CharTable[CurrentValue] == CurrentCharacter
     set CurrentValue = CurrentValue + 1
     //If the character is not found, set it to 0
     if CurrentValue >= 70 then
       set CurrentValue = 0
       exitwhen true
     endif
   endloop

   //Get a proper key index
   set KeyIndex = ModuloInteger(Index, KeyLength)

   //Get a character from the key
   set CurrentKeyCharacter = SubStringBJ(Key, KeyIndex + 1, KeyIndex + 1)

   //Converts a character to a value
   //Traverses the character table until the character is found
   set CurrentKeyValue = 0
   loop

     exitwhen udg_CharTable[CurrentKeyValue] == CurrentKeyCharacter
     set CurrentKeyValue = CurrentKeyValue + 1

     //If the character is not found, set it to 0
     if CurrentKeyValue >= 70 then

       set CurrentKeyValue = 0
       exitwhen true

     endif

   endloop

   //Make sure only a valid character is encrypted
   if ((CurrentKeyValue < 0) or (CurrentKeyValue >= 64)) then

     set CurrentKeyValue = 0

   endif

   //Encrypt the character using XOR
   set CurrentValue = BitwiseXOR(CurrentValue, CurrentKeyValue)

   //Convert the value to a character
   set CurrentCharacter = udg_CharTable[CurrentValue]

   //Add the character to the resulting code string
   set ResultCode = ResultCode + CurrentCharacter

   set Index = Index + 1

 endloop

 return ResultCode
 
endfunction


2, create variable :
CharTable : string array
set Hero_kill_string
set Hero_Death_string
set creep_kill_string
set creep_deaths_string
set Ranks_string

final_code_string
secured_final_code

also, call follow script to set up character table
custom script "call function SetupCharTable"


3, How to generate saving code :

then try :
set Hero_kill_string = ConvertToBase(Hero_kill_number, 36)
set Hero_Death_string = ConvertToBase(Hero_Death_number, 36)
set creep_kill_string = ConvertToBase(creep_kill_number, 36)
set creep_deaths_string = ConvertToBase(creep_deaths_number, 36)
set Ranks_string = ConvertToBase(Ranks_number, 36)

assume your range is :
Hero kill: 0-1295 ? (2 digit)
Hero Death: 0-11295 ? (2 digit)
creep kills: 0-46655? (3 digit)
creep deaths: 0-46655? (3 digit)
Ranks : 0-1295? (2 digit)

// make sure Hero_kill_string is 2 digit, if it is 1 digit, then add "0" to front. do same for other value
set final_code_string = Hero_kill_string + Hero_Death_string + creep_kill_string + creep_deaths_string + Ranks_string

set secured_final_code = GeneratePassword ( final_code_string, player_name)

4, How to Loading code:

player_enter_code // this code enter by player

set final_code_string = GeneratePassword (player_enter_code, player_name)
if(final_code_string != 12 digit)
then invalid code
Hero_kill_string = first 2 digit of (final_code_string)
Hero_Death_string = next 2 digit
......
Ranks_string = last 2 digit

Hero_kill_number = ConvertCharToInt(Hero_kill_string)
Hero_Death_number = ConvertCharToInt(Hero_Death_string)
......
Ranks = ConvertCharToInt(Ranks_string)

DONE !!!
(you can write more code verify invalid value on kill/death/rank etc

if you need higher than 46655, then you can use 4 digit (1 digit Base36 can hold 36 decimal, 4 digit base36 number can hold up to 1,679,615 decimal )
 
Level 11
Joined
Aug 1, 2009
Messages
714
here is simple save/load system:

1, copy code below, paste into top of the map (in GUI).

those code are basic function for convert/encrypt.


Code:
//+-----------------------------------------------------------------------------
//| Prepares the char table. Call this function once on map initialization.
//| Make sure you have a global string array variable named "CharTable"
//| ("udg_CharTable"), otherwise this function will not compile. The size of
//| the array should be 70, but that is not important since arrays are dynamic.
//+-----------------------------------------------------------------------------
function SetupCharTable takes nothing returns nothing
 //Sets the digits
 set udg_CharTable[0] = "0"
 set udg_CharTable[1] = "1"
 set udg_CharTable[2] = "2"
 set udg_CharTable[3] = "3"
 set udg_CharTable[4] = "4"
 set udg_CharTable[5] = "5"
 set udg_CharTable[6] = "6"
 set udg_CharTable[7] = "7"
 set udg_CharTable[8] = "8"
 set udg_CharTable[9] = "9"

 //Sets the capital letters
 set udg_CharTable[10] = "A"
 set udg_CharTable[11] = "B"
 set udg_CharTable[12] = "C"
 set udg_CharTable[13] = "D"
 set udg_CharTable[14] = "E"
 set udg_CharTable[15] = "F"
 set udg_CharTable[16] = "G"
 set udg_CharTable[17] = "H"
 set udg_CharTable[18] = "I"
 set udg_CharTable[19] = "J"
 set udg_CharTable[20] = "K"
 set udg_CharTable[21] = "L"
 set udg_CharTable[22] = "M"
 set udg_CharTable[23] = "N"
 set udg_CharTable[24] = "O"
 set udg_CharTable[25] = "P"
 set udg_CharTable[26] = "Q"
 set udg_CharTable[27] = "R"
 set udg_CharTable[28] = "S"
 set udg_CharTable[29] = "T"
 set udg_CharTable[30] = "U"
 set udg_CharTable[31] = "V"
 set udg_CharTable[32] = "W"
 set udg_CharTable[33] = "X"
 set udg_CharTable[34] = "Y"
 set udg_CharTable[35] = "Z"

 //Sets the small letters
 set udg_CharTable[36] = "a"
 set udg_CharTable[37] = "b"
 set udg_CharTable[38] = "c"
 set udg_CharTable[39] = "d"
 set udg_CharTable[40] = "e"
 set udg_CharTable[41] = "f"
 set udg_CharTable[42] = "g"
 set udg_CharTable[43] = "h"
 set udg_CharTable[44] = "i"
 set udg_CharTable[45] = "j"
 set udg_CharTable[46] = "k"
 set udg_CharTable[47] = "l"
 set udg_CharTable[48] = "m"
 set udg_CharTable[49] = "n"
 set udg_CharTable[50] = "o"
 set udg_CharTable[51] = "p"
 set udg_CharTable[52] = "q"
 set udg_CharTable[53] = "r"
 set udg_CharTable[54] = "s"
 set udg_CharTable[55] = "t"
 set udg_CharTable[56] = "u"
 set udg_CharTable[57] = "v"
 set udg_CharTable[58] = "w"
 set udg_CharTable[59] = "x"
 set udg_CharTable[60] = "y"
 set udg_CharTable[61] = "z"

 //Sets the special characters
 set udg_CharTable[62] = "("
 set udg_CharTable[63] = ")"

 //Sets the special characters
 //(These will NOT be encrypted)
 set udg_CharTable[64] = "."
 set udg_CharTable[65] = "-"
 set udg_CharTable[66] = "_"
 set udg_CharTable[67] = "["
 set udg_CharTable[68] = "]"
 set udg_CharTable[69] = " "

endfunction


//+-----------------------------------------------------------------------------
//| Converts an integer value (ASCII) to a character base on Character Table
//| eg, 61 -->"z",
//+-----------------------------------------------------------------------------
function ConvertIntToChar takes integer Value returns string
 return udg_CharTable[Value]
endfunction


//+-----------------------------------------------------------------------------
//| Converts Decimal to any Base.
//+-----------------------------------------------------------------------------
function ConvertToBase takes integer num, integer base returns string
	local integer m
	local string result = ""
	if(base<2)
		return result;
	endif
	if(nbase > 36)
		return result;
	endif
	loop
	    set m = ModuloInteger(num, base)
		set result = ConvertIntToChar[m] + result;
		set num = num/base
		exitwhen num >= base
	endloop
	return result
endfunction

//+-----------------------------------------------------------------------------
//| Converts a character to an integer value (ASCII)
//+-----------------------------------------------------------------------------
function ConvertCharToInt takes string Character returns integer

 local integer Index = 0

 //Traverses the ASCII table until the character is found.
 loop

   exitwhen udg_CharTable[Index] == Character
   set Index = Index + 1

   //If the character is not found, return 0
   if Index >= 70 then

     set Index = 0
     exitwhen true

   endif

 endloop

 return Index

endfunction

//+-----------------------------------------------------------------------------
//| Does a bitwise XOR on two integer values
//+-----------------------------------------------------------------------------
function BitwiseXOR takes integer Value1, integer Value2 returns integer

 local integer Index
 local integer ResultValue
 local integer array Byte1
 local integer array Byte2
 local integer array ResultByte

 //Convert Value1 to a Byte
 set Index = 8
 loop

   set Index = Index - 1
   set Byte1[Index] = ModuloInteger(Value1, 2)
   set Value1 = Value1 / 2
   exitwhen Index <= 0

 endloop

 //Convert Value2 to a Byte
 set Index = 8
 loop

   set Index = Index - 1
   set Byte2[Index] = ModuloInteger(Value2, 2)
   set Value2 = Value2 / 2
   exitwhen Index <= 0

 endloop

 //Makes a bitwise XOR on the Bytes
 set Index = 0
 loop
   if (Byte1[Index] == Byte2[Index]) then
     set ResultByte[Index] = 0
   else
     set ResultByte[Index] = 1
   endif
   set Index = Index + 1
   exitwhen Index >= 8

 endloop

 //Convert the resulting Byte back to an integer
 set Index = 0
 set ResultValue = 0
 loop

   set ResultValue = ResultValue * 2
   set ResultValue = ResultValue + ResultByte[Index]
   set Index = Index + 1
   exitwhen Index >= 8

 endloop

 return ResultValue

endfunction


//+-----------------------------------------------------------------------------
//| Takes a string and uses the key (usually a player's name) to encrypt it.
//| To get the original string back, call the function with that string and
//| the same key used in the encryption.
//+-----------------------------------------------------------------------------
function GeneratePassword takes string Code, string Key returns string

 local integer Index = 0
 local integer KeyIndex = 0
 local integer KeyLength = 0
 local integer CurrentValue = 0
 local integer CurrentKeyValue = 0
 local string CurrentCharacter = ""
 local string CurrentKeyCharacter = ""
 local string ResultCode = ""

 //Calculates the length of the Key
 loop

    exitwhen SubStringBJ(Key, KeyLength + 1, KeyLength + 1) == ""
    set KeyLength = KeyLength + 1

 endloop

 //Abort if the key length is 0 (to avoid crashes)
 if KeyLength <= 0 then

   return ""

 endif

 //Loop through every character in the string and encrypt it
 loop

   //Get a character from the code
   set CurrentCharacter = SubStringBJ(Code, Index + 1, Index + 1)

   //Exit when the end of the code string is reached
   exitwhen CurrentCharacter == ""

   //Converts a character to a value
   //Traverses the character table until the character is found
   set CurrentValue = 0
   loop
     exitwhen udg_CharTable[CurrentValue] == CurrentCharacter
     set CurrentValue = CurrentValue + 1
     //If the character is not found, set it to 0
     if CurrentValue >= 70 then
       set CurrentValue = 0
       exitwhen true
     endif
   endloop

   //Get a proper key index
   set KeyIndex = ModuloInteger(Index, KeyLength)

   //Get a character from the key
   set CurrentKeyCharacter = SubStringBJ(Key, KeyIndex + 1, KeyIndex + 1)

   //Converts a character to a value
   //Traverses the character table until the character is found
   set CurrentKeyValue = 0
   loop

     exitwhen udg_CharTable[CurrentKeyValue] == CurrentKeyCharacter
     set CurrentKeyValue = CurrentKeyValue + 1

     //If the character is not found, set it to 0
     if CurrentKeyValue >= 70 then

       set CurrentKeyValue = 0
       exitwhen true

     endif

   endloop

   //Make sure only a valid character is encrypted
   if ((CurrentKeyValue < 0) or (CurrentKeyValue >= 64)) then

     set CurrentKeyValue = 0

   endif

   //Encrypt the character using XOR
   set CurrentValue = BitwiseXOR(CurrentValue, CurrentKeyValue)

   //Convert the value to a character
   set CurrentCharacter = udg_CharTable[CurrentValue]

   //Add the character to the resulting code string
   set ResultCode = ResultCode + CurrentCharacter

   set Index = Index + 1

 endloop

 return ResultCode
 
endfunction


2, create variable :
CharTable : string array
set Hero_kill_string
set Hero_Death_string
set creep_kill_string
set creep_deaths_string
set Ranks_string

final_code_string
secured_final_code

also, call follow script to set up character table
custom script "call function SetupCharTable"


3, How to generate saving code :

then try :
set Hero_kill_string = ConvertToBase(Hero_kill_number, 36)
set Hero_Death_string = ConvertToBase(Hero_Death_number, 36)
set creep_kill_string = ConvertToBase(creep_kill_number, 36)
set creep_deaths_string = ConvertToBase(creep_deaths_number, 36)
set Ranks_string = ConvertToBase(Ranks_number, 36)

assume your range is :
Hero kill: 0-1295 ? (2 digit)
Hero Death: 0-11295 ? (2 digit)
creep kills: 0-46655? (3 digit)
creep deaths: 0-46655? (3 digit)
Ranks : 0-1295? (2 digit)

// make sure Hero_kill_string is 2 digit, if it is 1 digit, then add "0" to front. do same for other value
set final_code_string = Hero_kill_string + Hero_Death_string + creep_kill_string + creep_deaths_string + Ranks_string

set secured_final_code = GeneratePassword ( final_code_string, player_name)

4, How to Loading code:

player_enter_code // this code enter by player

set final_code_string = GeneratePassword (player_enter_code, player_name)
if(final_code_string != 12 digit)
then invalid code
Hero_kill_string = first 2 digit of (final_code_string)
Hero_Death_string = next 2 digit
......
Ranks_string = last 2 digit

Hero_kill_number = ConvertCharToInt(Hero_kill_string)
Hero_Death_number = ConvertCharToInt(Hero_Death_string)
......
Ranks = ConvertCharToInt(Ranks_string)

DONE !!!
(you can write more code verify invalid value on kill/death/rank etc

if you need higher than 46655, then you can use 4 digit (1 digit Base36 can hold 36 decimal, 4 digit base36 number can hold up to 1,679,615 decimal )

is there a demo map?
 
Level 8
Joined
Apr 26, 2011
Messages
403
is there a demo map?

no demo, because every map is difference.

I already give you functions requires to handle encrypt/descrypt/convert.

the functions are well document so it should be easy to understand what it do with little knowledge.

It doesn't matter what save/load system, you still have to do following work :
- combine information you want to saved in one big/long string.
- convert big/long string to shorter string (base 10 to base 36)
- encrypt shorter string with player's name so the code cannot share with other.
- after reading code, work out some simple rule to make sure the code is valid (eg, Rank should be 1-100? then 10000 rank must be invalid)
 
Status
Not open for further replies.
Top