ID:139453
 
Code:
mob/proc
Save()
src.Hash = md5("[src.x][src.y][src.z][src.Level][src.HP]") //we dont want to save them at the title screens!
var/savefile/S = new("GameFiles/Players/[src.key]/[src.key].sav") //creates a new savefile or overwrites an old one
S["LastX"]<<src.x //this saves a variable to the savefile, the << point at where youre sending the data
S["LastY"]<<src.y
S["LastZ"]<<src.z
S["Name"] << src:name
S["Char"]<<src.Char
S["Level"]<<src.Level
S["Experience"] << src.Exp
S["MaxExperience"] << src.MaxExp
S["Hp"] << src.HP
S["MaxHp"] << src.MaxHP
S["Ki"] << src.Ki
S["MaxKi"] << src.MaxKi
S["Str"] << src.Str
S["MaxStr"] << src.MaxStr
S["Def"] << src.Def
S["MaxDef"] << src.MaxDef
S["Zenni"] << src.Gold
S["NameColor"] <<src.NameColor
S["Seconds"] << src:seconds
S["Hours"] << src:hours
S["Days"] << src:days
S["Medals Not Earned"] << src.Medals
S["Medals Earned"] << src.MedalEarned
S["Form1"] << src.Form1
S["Form2"] << src.Form2
S["Form3"] << src.Form3
S["Form4"] << src.Form4
S["Form5"] << src.Form5
S["Fly"] << src.Fly
S["Hash"] << src.Hash
S["Clan"] << src.Clan

Write(S)
src<<"Game Saved"

Load()
if(fexists("GameFiles/Players/[src.key]/[src.key].sav"))
world<<"<b>[src] has joined us</b>"
var/savefile/S = new("GameFiles/Players/[src.key]/[src.key].sav")
var/LastX
var/LastY
var/LastZ
Read(S)
S["LastX"]>>LastX
S["LastY"]>>LastY
S["LastZ"]>>LastZ
S["Name"] >> src:name
S["Char"]>>src.Char
S["Level"]>>src.Level
S["Experience"] >> src.Exp
S["MaxExperience"] >> src.MaxExp
S["Hp"] >> src.HP
S["MaxHp"] >> src.MaxHP
S["Ki"] >> src.Ki
S["MaxKi"] >> src.MaxKi
S["Str"] >> src.Str
S["MaxStr"] >> src.MaxStr
S["Def"] >> src.Def
S["MaxDef"] >> src.MaxDef
S["Zenni"] >> src.Gold
S["NameColor"] >>src.NameColor
S["Seconds"] >> src:seconds
S["Hours"] >> src:hours
S["Days"] >> src:days
S["Medals Not Earned"] >> src.Medals
S["Medals Earned"] >> src.MedalEarned
S["Form1"] >> src.Form1
S["Form2"] >> src.Form2
S["Form3"] >> src.Form3
S["Form4"] >> src.Form4
S["Form5"] >> src.Form5
S["Fly"] >> src.Fly
S["Hash"] >> src.Hash
S["Clan"] >> src.Clan
src.loc=locate(LastX,LastY,LastZ)
src<<"Game Loaded"
src.CreateName()
if(!src.Char) src.Char="Goku";src.icon='goku.dmi'
src.Characters()
if(src.Hash == md5("[src.x][src.y][src.z][src.Level][src.HP]")) //checks if it's src.foo / src.bar * src.key
goto NEWLOC
else
usr<<"Your savefile has been deleted because someone has edited your save file."
fdel("GameFiles/Players/[src.key]/[src.key].sav")
src.Load()
NEWLOC
if(!src.loc)
src.loc=locate(/turf/Start)
return 1
else
world<<"<b>[src] has joined us for first time"
src.loc=locate(/turf/Start)
src.icon='goku.dmi'
src.CreateName(src.namecolor)
src.Medal_Earned(usr,"Player","Login To Game")
world<<"<b>[src] has joined us for first time"
return 0


Problem description:Load proc dont load all of the vars like if HP,EXP,KI etc

It's generally a bad idea to use the : operator. Also it's a bad idea to call Write() and Read() directly they're automatically called once data is inserted into the save-file.
In response to Darker Legends (#1)
When was it ever a bad idea to use a : operator? It's only a bad idea when it is used wrong (which it was used wrong in this example). However, of course, there are dozens of ways to never having to use that operator.
In response to CauTi0N (#2)
The : ignore type-casting. Which means you can reference variables in your code that don't properly exist and it will compile anyway.
In response to Darker Legends (#3)
Read the reference. It explains the use of it. Not sure why anyone would write it that way, but it's not a "bad idea".
In response to CauTi0N (#4)
You'd rather have a compile-time error than a runtime-error. Also if you type something wrong like usr:myvra instead of usr:myvar you'd get a run-time error.
In response to Darker Legends (#1)
Darker Legends wrote:
It's generally a bad idea to use the : operator.

Indeed, because it's better and almost always practical/reasonable to use the . operator which ensures you some more safety.

Aso it's a bad idea to call Write() and Read() directly they're automatically called once data is inserted into the save-file.

Not quite. They're called when objects are saved and loaded to/from a savefile (using the built-in object writing and reading system), respectively. Additionally, it's a bad idea because they can fail under certain situations while doing an instance save/load (with the savefile operators, << and >>) won't.

The : ignore type-casting.
Which means you can reference variables in your code that don't properly exist and it will compile anyway.
Also if you type something wrong like usr:myvra instead of usr:myvar you'd get a run-time error.

Taken as is, all of the above sentences are strictly wrong. This is because you think that the : operator doesn't perform any safety checks at all, but it does; it's just that it does less - i.e. it's more lenient.
For example, go ahead and try to compile a statement that tries to access a property name that only matches a property on /mob from a var defined as /obj. It will fail. To clarify:
mob/var/abcd
client/verb/test()
var/obj/o = new /obj
src << o:abcd

The above will fail to compile, while it would've worked if the type of the o var was left unspecified.

(Additionally, there's some lack of understanding of fundamentals in the thinking that it's plausible for an undefined symbol like "myvra" to compile successfully in the first place -- if the compiler doesn't know what it is, it has no way how to react to it and a compilation error will be ensured)
In response to Darker Legends (#5)
Actually if myvra doesn't exist at all you'll get an compiler-error. the ':' operator can also be used to get the variables of object types without having to create a new one if I remember correctly, so it can be useful at times. It can also be used as a shortcut which I had completely forgotten until recently :
world
mob = :player //short-cut to /mob/player

mob/player
Login()
src << "Welcome, [name]."


So it isn't necessarily a 'bad thing'.

In response to ExPixel (#7)
ExPixel wrote:
the ':' operator can also be used to get the variables of object types without having to create a new one if I remember correctly

It can't, but it can read procedure properties from the special procedure type paths. Of course, . can do the same (if you satisfy its compilation conditions), since they're the same functionally.

It can also be used as a shortcut which I had completely forgotten until recently :

That's really a different operator, the : path operator. That's the same as mixing up the / division operator and / path operator.
That's a whole lot of code for something that doesn't need a whole lot of code. What you SHOULD have is:

#define HASH_SALT "Put some different string here"

proc/hashify(var/mob/M)
return md5(HASH_SALT+"[M.x][M.y][M.z][M.Level][M.HP]"+HASH_SALT)

client/proc
Save()
var/savefile/F = new("[key].sav")
F["mob"] << mob
F["hash"] << hashify(mob)
Load()
var/savefile/F = new("[key].sav")
var/mob/M = mob
F["mob"] >> mob
// If we had an old mob, delete it
if(M)
del(M)
// Check the hash
if(F["hash"] != hashify(mob))
fdel("[key].sav")
del(mob)

mob
// Called when we do F["mob"] << mob
Write(var/savefile/F)
..()
F["x"] << x
F["y"] << y
F["z"] << z
// Any other special processing would go here
// Called when we do F["mob"] >> mob
Read(var/savefile/F)
..()
loc = locate(F["x"],F["y"],F["z"])
// Any other special processing would go here


Also: never use goto. It's bad.