ID:2432780
 
(See the best response by Kaiochao.)
Code:
mob/verb
Set_Contact(var/mob/M in oview(6))
set category = "Player"
if(!M.client)
return
if(M == src)
return
if(M.AdminBody == 1)
return
else
if(src.Contacts.Find("[M.name]"))
return
else
var/mob/contacts/contact = new/mob/contacts/Contact
contact.Contact_Points = 1
contact.icon = M.icon
contact.icon_state = M.icon_state
contact.name = "[M.name]"
contact.key = "[M.key]"
contact.overlays += M.overlays
contact.underlays += M.underlays
src.Contacts.Add(contact)


Problem description:

So I'm trying to implement a contact system so that you can keep track of who you know, as well as having a point system that effects certain skills, for the most part it seems to work how I want it to, but for whatever reason instead of just making a new mob to place in their inventory, it's making their target into a new mob, and placing them at spawn. Above is my code for actually setting a contact up, which is where the issue occurs.
Hey Blackclaw, long time no see!

Is it absolutely necessary for the contact to be a mob? You could just as easily add it as a new object instead, and it would retain all of that information you need.
Best response
contact.key = "[M.key]"

When setting the key of a mob to the key of an existing client, that client logs out of its mob and logs into the mob whose key was just set. Logout is called on the old mob, Login is called on the new one.

It might be best to not use a mob as a contact. If all you want is something that looks like a mob and remembers the key of the mob:
obj/contact
var
key

New(loc, mob/source)
if(source)
// If src were a mob, this would be bad.
key = source.key

// Quick and easy way to copy the entire appearance
// from one atom to another, overlays and all.
appearance = source

I noticed you're checking the Contacts list for the name of M, but Contacts only contains contact objects, so it's not going to find any text. You can use list associations instead, by associating names to contacts in the Contacts list.
mob
verb
Set_Contact(mob/M in oview(6))
if(M.client && !M.AdminBody && !Contacts[M.name])
// Did you want the contact obj to go into src's contents?
// If so, use src as the first argument, the initial loc
// of the new obj.
Contacts[M.name] = new/obj/contact(src, M)
In response to Spevacus
Spevacus wrote:
Hey Blackclaw, long time no see!

Is it absolutely necessary for the contact to be a mob? You could just as easily add it as a new object instead, and it would retain all of that information you need.

It has been a while! I was thinking it needed to be, but the obj route was definitely the way to go, was able to get it functioning how I wanted it to.

Kaiochao wrote:
When setting the key of a mob to the key of an existing client, that client logs out of its mob and logs into the mob whose key was just set. Logout is called on the old mob, Login is called on the new one.

That is good to know, I'll keep it in mind for the future! It would certainly explain what was going on with the teleporting.

Kaiochao wrote:
I noticed you're checking the Contacts list for the name of M, but Contacts only contains contact objects, so it's not going to find any text. You can use list associations instead, by associating names to contacts in the Contacts list.

It does seem to have issues reading the names of the objects, but seemed to work fine for mobs, which was how I had it originally. Even using your below example, I ended up still just having to do a for loop to check the users current Contacts.