If you haven't already read Tutorial #4, you should check it out first. Or, start at the beginning, if you're new to the series!
Saving
First we'll create a Save proc, and have it so players get automatically saved without worry.
Step 1.1 First, we'll create a new Code file named Save.dm, and add the following code to it
mob/proc/SaveProc()
var/FileName="Players/[ckey(src.key)].sav"
if(fexists(FileName)) fdel(FileName)
var/savefile/F=new(FileName)
F["Level"]<<src.Level
F["Exp"]<<src.Exp
F["Nexp"]<<src.Nexp
F["HP"]<<src.HP
F["MaxHP"]<<src.MaxHP
F["Str"]<<src.Str
F["Def"]<<src.Def
F["LastX"]<<src.x
F["LastY"]<<src.y
F["LastZ"]<<src.z
src<<"Character Saved..."
We've created procs before, so the first line should look familiar.
The next line defines a variable for the file name. ckey() is a built in proc that will remove formatting (like periods and spaces) from the text you give it.
After that, we want to check if the file already exists, and if it does, delete it. This is done mainly to remove wasted space from previous save states.
fexists() is a built in proc that will tell you if the specified file exists. fdel() is also built in, and can delete a file.
The next line creates a savefile type var, and simply names the variable "F"
The following lines reference directories in F and outputs data to them. The output operator should look familiar, we've been using it to send messages.
Create a line for each thing we want to save. In this case, all the variables we've created. We also want to save the player's location.
Step 1.2 To make sure players always (and automatically) get saved, we will call our proc in Logout(). This can be found in Main.dm
Logout()
world<<"[src] has Logged Out"
src.SaveProc() //This line is new
del src
This 1 new line of code will call the proc we wrote above, saving the player automatically when they Logout.
As mentioned when we first wrote our Logout, make sure you do things before you delete the source.
Step 1.3 We should probably let players manually save as well, otherwise they freak out! This simple code can be added in Verbs.dm
mob/verb
Save()
src.SaveProc()
Loading
Now for loading. This will work a lot like saving actually.
Step 2.1 We'll add a LoadProc() to Save.dm, below the SaveProc()
mob/proc/LoadProc()
var/FileName="Players/[ckey(src.key)].sav"
if(fexists(FileName))
var/savefile/F=new(FileName)
F["Level"]>>src.Level
F["Exp"]>>src.Exp
F["Nexp"]>>src.Nexp
F["HP"]>>src.HP
F["MaxHP"]>>src.MaxHP
F["Str"]>>src.Str
F["Def"]>>src.Def
src.loc=locate(F["LastX"],F["LastY"],F["LastZ"])
src<<"Character Loaded..."
return 1
As you can see, this is pretty similar to the SaveProc(). There are, however, some differences.
We have everything tabbed in under out fexists() this time. That way it will only happen if there is a file.
We also won't need to delete any file here. Though, we will still create a new savefile variable.
We still reference the savefile directories. This time though, we use input operators >> (they're like backwards output ones) to send the data from the file to the variables. It goes in the direction the arrows are pointing, you see.
To locate the player to their saved location, we set their built-in loc variable. We also use the built-in locate() proc here. We also directly reference the savefile values, without needing to input them to anything.
We then have another standard message to the player that they were loaded.
Finally, we "return 1" inside the if(). If no file existed, then this proc will instead return null by default.
Using return will immediately end a proc or verb. It can also be used to "return" a value, in this case 1. I'll include an example at the end for better understanding.
Step 2.2 Now we need to actually load them. We'll do this when they Login. The Login() code can be found in Main.dm
mob
Login()
//new code below
if(src.LoadProc())
world<<"[src] has Returned"
else
//end new code.
//The following lines were tabbed in
src.loc=locate(5,5,1)
world<<"[src] has Logged In"
Now in our Login we use our LoadProc(), inside an if(). Since it returns 1 if there was a file, it will be true if you loaded, and will output that the player has Returned.
Since the LoadProc will return null otherwise, that would be a false if(), and therefore the else would occur.
Inside the else (we tabbed in our existing code) our old Login code will occur.
return
Quick examples of how you can use return
//Getting a value with return
proc/Add(num1,num2)
var/Sum=num1+num2
return Sum
//You could do this without the sum variable:
//return num1+num2
mob/verb/Test_Add()
src<<Add(2,3)
src<<"3 + 5 = [Add(3,5)]"
//Stopping a proc/verb with return
mob/verb/Return2Stop()
src<<"Shows this"
return
src<<"But not this"
//It does both at the same time!
Contine to Tutorial #6: Animating Icons