Allo all, so as usual ive been tweaking things and ive been doing some debugging with some mates on my game and some times it required logging out and since i didn't have any form of deleting in the actual logout the mobs always just stayed there. so i decided it go and pull up the logout/deathavoid code someone asked about awhile ago and pull it into play for my needs.

The following code as you will be able to see when posted below will on client/del save the player as a check and then create a new datum called logoutter this is just a simple datum that watches over the player mob until the time for deletion comes. anyway onto the code.

Code: First up we have the datum and client/del
if(!istype(mob,/mob/human/player)) return //just making sure it only does players.
mob.Save() //saving the mob.
new /logoutter(src.mob) //creating the datum using the mob as a argument.
mob.key = null //i wipe the key here so that its not connected to any client. this is so that on relog it doesn't put them back into the mob.
//the reason it is done like this is because i have 3 slots and they may not want to be in the same mob. despite it being 10secs before deletion.

var/mob/human/reffer //holding the mob for later use.
src.tag = "logoutter |[p.ckey]|[]|" //safety check later it needs to match both the name and ckey.
reffer = p //set the mob reference here for later use.
world << "0.[reffer] = [reffer.x] - [reffer.y] - [reffer.z]" // IMPORTANT DBG TEXT -- when ran this displays the mobs co-ords properly as there meant to be. lets say its 7-7-7 for this
src.DelayedSaveDel(p) //launch proc
Del(client/c) //del with a client argument.
if(c) //make sure it has a client.
world << "1.[reffer] = [reffer.x] - [reffer.y] - [reffer.z]" // IMPORTANT DBG TEXT -- For some reason reffer's co-ords become 0-0-0
reffer.key = c.key //make the inactive zombie mob have the players key. inturn swapping the client over.
world << "2.[reffer] = [reffer.x] - [reffer.y] - [reffer.z]" //it becomes 2-2-2 here.
world << "[P] has Successfully logged out."
del P

Code: next up is the load and other stuff.
client/proc/Load(playerslot, playername)  //first is slot from 1-3, second is the name so "Midgetbuster"
var/savefile/F = new(savedir)

var/logoutter/loutter = locate("logoutter |[src.ckey]|[playername]|") //match "logoutter |midgetbuster|Midgetbuster|" to a logutter datum
loutter.Del(src) // run the del
src << "System: You have reconnected to your mob."
F["/Slot[playerslot]"] >> src.mob //otherwise we just pull it from the savefile.
world << "[src.mob]/[ckey] has Logged into the world"

Now im unsure if its clear in there in any case what is happening is when the mob regains a client it is meant to stay in the same location. instead it gets hurled back to the first available tile and im unsure why this is the case.

I have looked over most of my code and i cant seem to figure out why this is occuring.

If anyone has insight onto this or ways to improve this it would be greatly appreciated.

In logoutter/Del(), is the "it becomes 2-2-2 here" the first available space, or is that where you wanted to turn up?

Also, where do you call client/Load?
In response to Murrawhip
That is the first available space. The map is lined with a dense object thats invisible for mapping purposes instead of altering turfs to do the job.

the usual place is meant to be 7-7-7

//ill stick some notes in that arnt usually in my code.

//its called via an interface button though.

var/savefile/F = new(savedir)
if(F.dir.Find("Slot[loadslot]")) //try and find the saveslot in the savefile from 1-3
client.Screenchanger_ToMap() //change it to the map screen.
client.Load(loadslot, src.track_names["Slot[loadslot]"]) // run the load proc with the slot and the playername as arguments.
login_create(loadslot) //otherwise create new account under slot 1-3
login_create(1) //if no file make new save with save slot 1.
In response to Midgetbuster
Are you sure the empty mob is remaining in place when you logout? Check with another key.
In response to Murrawhip
I used 2 Keys.

here are the results in order of doing them.

Compile DM to ensure its up-to-date
Launch Dream Daemon.
Select the exe to run, then run.
Create a player on the key currently on.
Navigate abit away from start point (which is dead center in a ring of test items and the ring starts approx 5 tiles away from where it throws me back to)
Move screen so i can view both screens at once.
Launch client again.
Create a char
navigate to 2-3 tiles from first key. ensuring in view.
Close client.
Relaunch client.

After i relaunch i get moved to to 2-2-2 which is the first available square.

If i allow it wait 10seconds it deletes the character likes its meant to, the only known problem i can see is that its slingshotting me to 2-2-2

In response to Midgetbuster
That's confusing to me.

"After i relaunch i get moved to to 2-2-2 which is the first available square." So you're positive the old mob is moved ATER you login, and not when you logout?
In response to Murrawhip
NoKey has been born into a nooby village as a Gladiator
HasKey has been born into a bigger village as a Mage
0.HasKey = 13 - 7 - 1
HasKey = 0-0-0
1.HasKey = 0 - 0 - 0
2.HasKey = 2 - 2 - 1

From those small debug results i can deduct that.

On the first result when reffer becomes an actual reference its location is 13-7-1 but inbetween the creation of the datum and clicking of "login" reffers x,y,z become null yet the mob itself does not move on the map. EVER

And yes it moves soon as i click login

The mob does not move until it meets one of these 2 criteria currently.
1. The datum deletes the mob in which case it no longer exists in the world.
2. The player clicks login in which case it gets hurled to the first available square instead its meant to put you back comfortably in your body as if you had an out o body experience.

In response to Midgetbuster
Okay, so it seems to me that the empty /mob loses its loc sometime before you try to relog into it.
Then when you try to log into it, its Login() is called which by default, if it doesn't already have a loc, will move the mob to 1,1,1 or as close as it can get.

What occurs in /mob/human/player/Logout() and/or /mob/Logout()?
In response to Murrawhip
mob/human/logging //when your logging in.
var/tmp/list/track_names = new
..() = "Loading"
src.loc = locate_tag("tag_waiting")


mob/human/creation //when creating your player.
var/track_name = 0
var/track_preview = 0
var/track_class = 1
var/track_village = 1

src.loc = locate_tag("tag_waiting")
src.Builder_Preview() = "[key]"
src.track_preview = 1


mob/human/player // the main mob for players
spawn() src.Update_Inventory()
spawn() src.Update_Buttons()
if(timer_mute) src.Timer_Mute()

They are all the references of Logout() in use currently.
In response to Midgetbuster
Does anything in /mob/human/player/Builder_Player() mess with loc/x,y,z/Move?
In response to Murrawhip
Nope, It creates the overlays from the equipment list using the references inside the equipment list items. the reference is a simple link to another object that contains the proper icon for use.
In response to Midgetbuster
Further debugging text shows its when a new client launches.

NoKey being the name of the mob im testing.. this is set on a 0.5 loop it donks to 0-0-0 soon as the client goes in

3.NoKey = 8 - 6 - 1
3.NoKey = 8 - 6 - 1
New Client
3.NoKey = 8 - 6 - 1
3.NoKey = 0 - 0 - 0

but still dunno how to fix it :(
In response to Midgetbuster
Seeing client/New() and any procedures that one calls would be helpful.
In response to Garthor
Found the problem, It was inside my preview code. But it did not move the mob on its own will was clashing

I have a number of client/new that gets called from different libraries. ill post the snippet and its related library, i have not altered client/new myself other then what the libraries do.

//From HDK Mouse and Keys.
src << browse(\
<script type="text/javascript">
var wtl=
var skc=0;
var ckc=0;
var akc=0;
function setTickLag(v) {wtl=1000/(10/v);}
function doKeys() {document.getElementById('Keys').click()}
function getKeys() {
var sk=0;
var ck=0;
var ak=0;
if(event.shiftKey&&!skc) {skc=1;sk=1}
else {if(!event.shiftKey&&skc) {skc=0;sk=2}}
if(event.ctrlKey&&!ckc) {ckc=1;ck=1}
else {if(!event.ctrlKey&&ckc) {ckc=0;ck=2}}
if(event.altKey&&!akc) {akc=1;ak=1}
else {if(!event.altKey&&akc) {akc=0;ak=2}}
setTimeout(doKeys, 1)}
function doMouse() {document.getElementById('Mouse').click()}
function getMouse() {
setTimeout(doMouse, wtl)}
<button id="Mouse" onclick="getMouse()"></button>
<button id="Keys" onclick="getKeys()"></button>
<html><body onload="doMouse();doKeys()" ></body></html>
, "window=javascript")
winset(src, "javascript", "is-visible=false")

//from Forum accounts pixel movement.

. = ..()

// This proc defines keyboard macros for pressing and releasing
// the following keys: 0-9, a-z, arrow keys, space bar. These
// macros take the place of the pre-defined macros in the old
// common\keyboard.dmf file but they work exactly the same: they
// call the mob's KeyUp and KeyDown verbs.
// If you don't like the idea of dynamically creating macros you
// can hardcode them like they used to be. It'll work the same it's
// just more tedious. This method makes the library more flexible
// as you can now use your own interface file without losing the
// pre-defined macros.
// var/windows = winget(src, null, "windows")
// var/macros = params2list(winget(src, windows, "macro"))

// This should get us the list of all macro sets that
// are used by all windows in the interface. We can cut
// out the first winget call to get the set of windows.
var/macros = params2list(winget(src, null, "macro"))

var/list/keys = list("0","1","2","3","4","5","6","7","8","9","q","w","e","r","t","y","u","i","o","p","a","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m","west","east","north","south","space","escape")
for(var/m in macros)
for(var/k in keys)
winset(src, "[m][k]Down", "parent=[m];name=[k];command=KeyDown+\"[k]\"")
winset(src, "[m][k]Up", "parent=[m];name=[k]+UP;command=KeyUp+\"[k]\"")

This is the only modification i did to client/new myself. this was to see when the client logged on.

world << "New Client"