ID:139570
 
Code:

LoadF()
if(fexists("savefiles/[src.ckey].sav"))
var
savefile
F = new("savefiles/[src.ckey].sav")
lx
ly
lz

mob
newmob = new()


F["lastx"] >> lx
F["lasty"] >> ly
F["lastz"] >> lz
F["mob"] >> newmob

newmob.loc = locate(lx,ly,lz)
newmob = src.client

return

else
alert("No Save File found","Error")
src.InitiateLogin()


Problem description: I just recently started to learn how to code (mostly looking over demos and libraries) and I found one system that works...for the most part..
At the moment I have it setup with just a series of Switches for players to work with when creating their characters. Creating a new character works fine, Deleting works fine, but when I Load a character, it loads the character like I expect it to, but then it goes back to the first Login switch that brings up the selections for Create Load and Delete again.
From what I can see I don't have any code that would re-initiate the Login procedure when a save file Is found -- only when it Isn't found (and I've tested it, when there's no save present, it returns with the "No Save File found" error and restarts the Login).
How can I get it to stop repeating the Login whenever a player Loads?


Pu an if() switch in your Login() proc, checking if a savefile exists. If one does, skip the character creation. If not, allow the player to create their character,
You are calling "newmob = src.client", and the only guess I have is that I'm assuming it is the same mob type as the original login type. If they are the same mob, it will reloop the same Login().

The best way to go about this is one of two ways. Set a seperate mob type, or don't create a new mob at all.
mob
Login()
src.Load(F)
mob
Thief
Login()
// procedure information here
mob
Warrior
Login()
// procedure information here

// etc, etc.

The issue with this is you do need to create a check to delete the old mob, otherwise you'll have blank mobs floating around.

A much more feasible idea, in my opinion, is to just allow the player to continue along with their current mob, and set the variables to the current mob.
src.loc=locate(lx,ly,lz)
The character creation stuff needs to be done with a mob type that is completely separate from any other mob. So, you'd use mob/login to handle all the login stuff and your players would be of type mob/player.
In response to Garthor
Ok, so a few new questions.

world
view = 10


mob

Login()
src.InitiateLogin()
src<<"Welcome to One-Piece: The New World!"


verb
Save()
src.SaveF()

proc
InitiateLogin()
switch(alert("What would you like to do?","Login","Create","Load","Delete"))
if("Create")
src.CreateF()
return
if("Load")
src.LoadF()
return
if("Delete")
src.DeleteF()
return
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SaveF()
var
savefile
F = new("savefiles/[src.ckey].sav")


F["lastx"] << src.x
F["lasty"] << src.y
F["lastz"] << src.z
F["verbs"] << src.verbs
F["overlays"] << src.overlays
src << "<font color = red> Game Saved </font color>"
Write(F)


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
CreateF()
if(fexists("savefiles/[src.ckey].sav"))
switch(alert("You already have a Save File, if you continue you will lose your current file. Would you like to continue?", "Error", "Yes", "No"))
if("Yes")
var
savefile
F = new("savefiles/[src.ckey].sav")


switch(alert("Gender?","Gender","Male","Female"))
if("Male")
switch(alert("Race?","...","Human","Giant","Fishman"))
if("Human")
usr.icon = 'Male.dmi'
if("Giant")
usr.icon = 'MGiant.dmi'
if("Fishman")
usr << "This class is currently unavailable, please try again"
CreateF()
if("Female")
switch(alert("Race?","...","Human","Giant","Fishman"))
if("Human")
usr.icon = 'Female.dmi'
if("Giant")
usr.icon = 'FGiant.dmi'
if("Fishman")
usr << "This class is currently unavailable, please try again"
CreateF()


usr.loc = locate(1,1,1)

F["lastx"] << src.x
F["lasty"] << src.y
F["lastz"] << src.z
F["mob"] << usr.client.mob
src << "Save Overwritten"

if("No")
src.InitiateLogin()
return

else
var
savefile
F = new("savefiles/[src.ckey].sav")


switch(alert("Gender?","Gender","Male","Female"))
if("Male")
switch(alert("Race?","...","Human","Giant","Fishman"))
if("Human")
usr.icon = 'Male.dmi'
if("Giant")
usr.icon = 'MGiant.dmi'
if("Fishman")
usr << "This class is currently unavailable, please try again"
CreateF()
if("Female")
switch(alert("Race?","...","Human","Giant","Fishman"))
if("Human")
usr.icon = 'Female.dmi'
if("Giant")
usr.icon = 'FGiant.dmi'
if("Fishman")
usr << "This class is currently unavailable, please try again"
CreateF()


usr.loc = locate(1,1,1)

F["lastx"] << src.x
F["lasty"] << src.y
F["lastz"] << src.z
F["mob"] << usr.client.mob
src << "Save Created"

//Still need to create Name Input
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
LoadF()
if(fexists("savefiles/[src.ckey].sav"))
var
savefile
F = new("savefiles/[src.ckey].sav")
lx
ly
lz

mob
newmob = new()


F["lastx"] >> lx
F["lasty"] >> ly
F["lastz"] >> lz
F["mob"] >> newmob

newmob.loc = locate(lx,ly,lz)
newmob = src.client


return

else
alert("No Save File found","Error")
src.InitiateLogin()

//Still need to fix Repeat on Load
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
DeleteF()
if(fexists("savefiles/[src.ckey].sav"))
var
savefile
S = "savefiles/[src.key].sav"
switch(alert("Are you sure you want to Delete your Save File?", "Delete?", "Yes", "No"))
if("Yes")
if(fdel(S) == 1)
src << "Safe File Deleted"
src.InitiateLogin()
else
src << "Could Not Delete Save File"
src.InitiateLogin()
if("No")
return
else
src << "No Save File Found"
src.InitiateLogin()
return
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
client
Del()
..()
usr.SaveF()
//Autosave
///////////////////////////////////////////////////////////////////////////////////////////////////////////////


1.)How would I switch from the Login() mob to the Player mob (which I haven't declared yet, when I tried I got a laundry list of new errors)?

2.)How would I delete the original Login() mob once the Character has been successfully created?


In response to Scatterneo
You change mobs by changing the client's mob variable.

You delete mobs using del().
In response to Scatterneo
I swear I answered that. Oh well, Garthor is apparently God on these forums.
In response to CauTi0N
You were the one I was asking Caution.
Keep in mind I haven't been coding for more than a week (and it's only been in my spare time) so I don't know how to "switch the clients mob variable" or "use del()"
I need examples of code to follow (with descriptions in the code telling me what each line does)
I would really really appreciate it.
In response to Scatterneo
Scatterneo wrote:
(...)"switch the clients mob variable"

mob.client stores a reference to the client object (representing the actual connected player) on the mob, whereas client.mob stores a reference to the mob the client (player) is currently 'using' (in lack of better terms).
Assigning a new value to a variable is one of the most basic core principles of programming. If you do not know how this works, you might want to visit and work through the guide.


Scatterneo wrote:
(...) or "use del()"

del object is a procedure that takes any data object as argument and then deletes this object, while setting all references to this object as null.
In response to Scatterneo
Right, Schnitzelnagler has given you the correct concept. Basically, the issue occurring in your code was when you were setting "src.client.mob=newmob"; this caused the normal Login() procedure to re-occur, thus causing an infinite loop of Loading()

My example is moreso like this:

mob
Login()
src.Load() // use your load procedure here

proc
Load()
// place all your Loading information here. If the file exists, Load, if not, then new character...
// now, lets assume it was found
if(fexists("file.sav"))
// grab the information (like you have in your code already)
var/mob/a = src // set a variable for the mob the client is currently controlling
src = newmob // change the player's mob to the new mob (ie; mob/Warrior, mob/Thief, etc.)
del(a) // delete your old mob, as it is unnecessary now

mob
Warrior // the path for this is mob/Warrior
Login() // separate paths can have separate Login() options
world<<"[src] the Warrior entered!"
Thief // the path for this is mob/Thief
Login()
world<<"[src] the Thief entered!"


Of course, another way you could go about this is setting a temporary variable and checking if something has been loaded. A quick example would be like so...

mob
var
tmp/isloaded // creates a temporary variable called isloaded; naturally set to 0.

mob
proc
LoadF()
if(src.isloaded) return 0 // IF THE PLAYER HAS ALREADY BEEN LOADED, THEN STOP LOADING.
if(fexists("savefiles/[src.ckey].sav"))
var
savefile
F = new("savefiles/[src.ckey].sav")
lx
ly
lz

mob
newmob = new()


F["lastx"] >> lx
F["lasty"] >> ly
F["lastz"] >> lz
F["mob"] >> newmob

newmob.loc = locate(lx,ly,lz)
newmob.isloaded=1 // SET THE ISLOADED VARIABLE TO 1, NOW THAT THE PLAYER HAS LOADED
newmob = src.client

return

else
alert("No Save File found","Error")
src.InitiateLogin()


Both ways work - The first way is more to do with you are trying to use classes or whatnot, or you can simply define mob/player as a general player mob. The second way is shorter but you have to keep up with more variables, though may run quicker.
In response to CauTi0N
Your first code snippet doesn't work and is a poor way of doing things, and your second code snippet is just a poor way of doing things. What SHOULD happen is:

world
mob = /mob/login

mob/login
Login()
//character creation stuff

client
proc
Save()
var/savefile/F = new("[ckey].sav")
F["mob"] << mob
// Do not add anything more to be saved here
Load()
if(fexists("[ckey].sav"))
var/savefile/F = new("[ckey].sav")
F["mob"] >> mob
// Do not add anything more to be loaded here

mob
Write(var/savefile/F)
..()
// Add any special processing for saving here
F["x"] << x
F["y"] << y
F["z"] << z
Read(var/savefile/F)
..()
// Add any special processing for loading here
loc = locate(F["x"], F["y"], F["z"])
In response to Garthor
Garthor, your code came up with a lot of errors (only a few of which I managed to fix, so I'm not even gonna try to play with that)

Caution, your second snippet helped a lot, but it still repeats the Login Once after clicking Load the first time.
In response to Scatterneo
The code I posted contains no errors. If you got errors when you attempted to implement it, then the fault is in your implementation, not in my code.
In response to Scatterneo
Scatterneo wrote:
Garthor, your code came up with a lot of errors (only a few of which I managed to fix, so I'm not even gonna try to play with that)

Caution, your second snippet helped a lot, but it still repeats the Login Once after clicking Load the first time.

Then the section where I said "if(src.isloaded) return"; just place that at the top of the Login(). :)
In response to CauTi0N
Now for some reason the map and player doesn't show up, the screen just stays black -- but the Login doesn't repeat anymore
In response to Scatterneo
That's because Caution's method involves overriding Login() so that it performs no action whatsoever. Seeing as the default action of Login() is what places you on the map, nixing that is Something Of An Issue. You'll need to do that yourself, now.
In response to Garthor
Garthor wrote:
Your first code snippet doesn't work and is a poor way of doing things, and your second code snippet is just a poor way of doing things. What SHOULD happen is:

world
> mob = /mob/login
>
> mob/login
> Login()
> //character creation stuff
>
> client
> proc
> Save()
> var/savefile/F = new("[ckey].sav")
> F["mob"] << mob
> // Do not add anything more to be saved here
> Load()
> if(fexists("[ckey].sav"))
> var/savefile/F = new("[ckey].sav")
> F["mob"] >> mob
> // Do not add anything more to be loaded here
>
> mob
> Write(var/savefile/F)
> ..()
> // Add any special processing for saving here
> F["x"] << x
> F["y"] << y
> F["z"] << z
> Read(var/savefile/F)
> ..()
> // Add any special processing for loading here
> loc = locate(F["x"], F["y"], F["z"])


I tried following your way and it came up with 6 errors, all of which occur at the end of this section of default code

// DM Environment file for One-PieceTheNewWorld.dme.
// All manual changes should be made outside the BEGIN_ and END_ blocks.
// New source code should be placed in .dm files: choose File/New --> Code File.

// BEGIN_INTERNALS
// END_INTERNALS

// BEGIN_FILE_DIR
#define FILE_DIR .
#define FILE_DIR "Icons"
#define FILE_DIR "Icons/Hair"
#define FILE_DIR "Icons/Mobs"
#define FILE_DIR "Icons/Mobs/Other"
#define FILE_DIR "Icons/Other"
#define FILE_DIR "Icons/Tops"
#define FILE_DIR "Icons/Turf"
// END_FILE_DIR

// BEGIN_PREFERENCES
// END_PREFERENCES

// BEGIN_INCLUDE
#include "Turf.dm"
#include "World.dm"
#include "Map.dmm"
// END_INCLUDE
In response to Scatterneo
The error would then be at the end of World.dm.