mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Important!
Minds part2 - Carn loses her mind. The way datum/mind stuff works has been changed a lot. I really can't explain everything. If you have any questions it'd just be easier if you leave a comment or ask me in coderbus. Generally, minds now represent IC characters rather than following a client around constantly. Minds can change owners, mobs, (names WIP). Technical babble: The var/current and var/original variables of the mind datum must always be of type mob/living (or null). Please do not mind.transfer_to(ghost_mob). If you want to ghost somebody use ghostize()! It will do all the technical stuff for you. mob/dead/observer/var/corpse was removed. mob/dead/observer/var/mind is now used as a reference to the last mind the player had (so respawning code has something to reference), but also because mind.current is a far more useful way of tracking a corpse. If somebody triggers a mind.transfer_to() call on your corpse, your mind will be tranfered to another mob/living or something...that will then be considered your corpse. This could allow for more interesting mind_transfers. For instance, the "raise corpse" rune ghostizes any player in the corpse to be raised and selectes a random dead player to take possesion of their character! The person possesing them will have all of their memories, objectives, etc. The poor guy who was originally the owner cannot re-enter body if there is another player in his body...but if that player is ghosted he can once again return. Exorcisms anybody? Changes to cloning and hydroponics. I will likely have to rework these later as they're hacky as hell right now. A lot of stuff is now handled by Login/Logout rather than in hundreds of different places. One such example, mind datums get their variables updated at Login and Logout. Fixed a few minor bugs. I'll update the issues manually in a bit because I literally cannot think atm. TL;DR guide: -If you want to make somebody a ghost use ghostize(). Or you will need to find a doctor to stitch your bits back on. :) -You don't have to worry about making minds. Simply doing key="carnwennan" or whatever will either: A) make a new mind and initialise it if there isn't one or B) take possession of the mind currently attached to the mob. -It's safe to transfer a mind even if a key isn't in-body (e.g. they are ghosted/admin-observing etc!) Minds have an active variable which tracks whether they are currently synced with a key. This is to avoid dragging ghosts back into their bodies when say, a wizard mind_transfers them. -Transferring a mind whilst var/active=1 will cause the following: mob.key = mind.key. So no need to do that separately (in fact you'll lag things if you do, so don't) -If you do want to initialize a mind manually, say if you don't have a client to login to the mob yet, simply do new_mob.mind_initialize(). Simple! When someody is logged into that mob they will take ownership of the mind and it will sync up. NOTE: a lot is probably broken since this is a pretty massive change. Please let me know asap (with actual info! Shouting at me, "IT BORKED HALP", doesn't help) git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4342 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
@@ -246,34 +246,28 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
|
||||
else
|
||||
return 0
|
||||
|
||||
// Picks a random ghost for the role if none is specified. Mostly a copy of alien burst code.
|
||||
var/candidates_list[] = list()
|
||||
if(G)//If G exists through a passed argument.
|
||||
candidates_list += G.client
|
||||
else//Else we need to find them.
|
||||
var/selected_key
|
||||
if(G && G.key)
|
||||
selected_key = G.key
|
||||
else
|
||||
var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn
|
||||
for(G in player_list)
|
||||
if(!G.client.holder && ((G.client.inactivity/10)/60) <= 5)
|
||||
candidates_list += G.client//We want their client, not their ghost.
|
||||
if(candidates_list.len)//If there are people to spawn.
|
||||
if(!G)//If G was not passed through an argument.
|
||||
var/client/G_client = input("Pick the client you want to respawn as a xeno.", "Active Players") as null|anything in candidates_list//It will auto-pick a person when there is only one candidate.
|
||||
if(G_client)//They may have logged out when the admin was choosing people. Or were not chosen. Would run time error otherwise.
|
||||
G = G_client.mob
|
||||
else
|
||||
return 0
|
||||
|
||||
if(G)//If G exists.
|
||||
message_admins("\blue [key_name_admin(usr)] has spawned [G.key] as a filthy xeno.", 1)
|
||||
new_xeno.mind_initialize(G, alien_caste)
|
||||
new_xeno.key = G.key
|
||||
else//We won't be reporting duds.
|
||||
del(new_xeno)
|
||||
if(G.client.be_alien)
|
||||
if(((G.client.inactivity/10)/60) <= 5)
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
candidates += G.key
|
||||
if(candidates.len)
|
||||
selected_key = input("Pick the client you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates
|
||||
|
||||
if(selected_key)
|
||||
new_xeno.key = selected_key
|
||||
message_admins("\blue [key_name_admin(usr)] has spawned [selected_key] as a filthy xeno.", 1)
|
||||
return 1
|
||||
|
||||
alert("There are no available ghosts to throw into the xeno. Aborting command.")
|
||||
del(new_xeno)
|
||||
return 0
|
||||
else
|
||||
//we couldn't find a candidate
|
||||
usr << "<font color='red'>Error: create_xeno(): no suitable players.</font>"
|
||||
del(new_xeno)
|
||||
return 0
|
||||
|
||||
/*
|
||||
If a guy was gibbed and you want to revive him, this is a good way to do so.
|
||||
@@ -287,130 +281,96 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
return
|
||||
var/input = input(src, "Please specify which key will be respawned.", "Key", "")
|
||||
var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", ""))
|
||||
if(!input)
|
||||
return
|
||||
|
||||
var/mob/dead/observer/G_found
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
if(G.client&&G.ckey==ckey(input))
|
||||
if(G.ckey == input)
|
||||
G_found = G
|
||||
break
|
||||
|
||||
if(!G_found)//If a ghost was not found.
|
||||
alert("There is no active key like that in the game or the person is not currently a ghost. Aborting command.")
|
||||
usr << "<font color='red'>There is no active key like that in the game or the person is not currently a ghost.</font>"
|
||||
return
|
||||
|
||||
//First we spawn a dude.
|
||||
var/mob/living/carbon/human/new_character = new(src)//The mob being spawned.
|
||||
if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
|
||||
//Check if they were an alien
|
||||
if(G_found.mind.assigned_role=="Alien")
|
||||
if(alert("This character appears to have been an alien. Would you like to respawn them as such?",,"Yes","No")=="Yes")
|
||||
var/turf/T
|
||||
if(xeno_spawn.len) T = pick(xeno_spawn)
|
||||
else T = pick(latejoin)
|
||||
|
||||
//Second, we check if they are an alien or monkey.
|
||||
var/adj_name = copytext(G_found.real_name,1,7)//What is their name?
|
||||
if(G_found.mind&&G_found.mind.special_role=="Alien")//If they have a mind, are they an alien?
|
||||
adj_name="alien "
|
||||
if( adj_name==("alien "||"monkey"))
|
||||
if(alert("This character appears to either be an an alien or monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes")//If you do.
|
||||
switch(adj_name)//Let's check based on adjusted name.
|
||||
if("monkey")//A monkey. Monkeys don't have a mind, so we can safely spawn them here if needed.
|
||||
//TO DO: Monkeys may have a mind now. May need retooling.
|
||||
var/mob/living/carbon/monkey/M = new(pick(latejoin))//Spawn a monkey at latejoin.
|
||||
M.mind = G_found.mind
|
||||
if(M.mind)//If the mind is not null.
|
||||
M.mind.current = M
|
||||
M.key = G_found.key//They are now a monkey. Nothing else needs doing.
|
||||
if("alien ")//An alien. Aliens can have a mind which can be used to determine a few things.
|
||||
if(G_found.mind)
|
||||
var/turf/location = xeno_spawn.len ? pick(xeno_spawn) : pick(latejoin)//Location where they will be spawned.
|
||||
var/mob/living/carbon/alien/new_xeno//Null alien mob first.
|
||||
switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were.
|
||||
if("Hunter")
|
||||
new_xeno = new/mob/living/carbon/alien/humanoid/hunter(location)
|
||||
if("Sentinel")
|
||||
new_xeno = new/mob/living/carbon/alien/humanoid/sentinel(location)
|
||||
if("Drone")
|
||||
new_xeno = new/mob/living/carbon/alien/humanoid/drone(location)
|
||||
if("Queen")
|
||||
new_xeno = new/mob/living/carbon/alien/humanoid/queen(location)
|
||||
else//If we don't know what special role they have, for whatever reason, or they're a larva.
|
||||
create_xeno(G_found)
|
||||
return
|
||||
//Now to give them a new mind.
|
||||
new_xeno.mind = new
|
||||
new_xeno.mind.assigned_role = "Alien"
|
||||
new_xeno.mind.special_role = G_found.mind.special_role
|
||||
new_xeno.mind.key = G_found.key
|
||||
new_xeno.mind.current = new_xeno
|
||||
new_xeno.key = G_found.key
|
||||
new_xeno << "You have been fully respawned. Enjoy the game."
|
||||
message_admins("\blue [key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.", 1)
|
||||
//And we're done. Announcing other stuff is handled by spawn_xeno.
|
||||
else
|
||||
create_xeno(G_found)//Else we default to the standard command for spawning a xenomorph.
|
||||
var/mob/living/carbon/alien/new_xeno
|
||||
switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were.
|
||||
if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T)
|
||||
if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T)
|
||||
if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(T)
|
||||
if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen(T)
|
||||
else//If we don't know what special role they have, for whatever reason, or they're a larva.
|
||||
create_xeno(G_found)
|
||||
return
|
||||
del(G_found)
|
||||
return
|
||||
//Monkeys aren't terribly important so we won't be announcing them. The proc basically ends here.
|
||||
else//Or not.
|
||||
G_found.mind=null//Null their mind so we don't screw things up ahead.
|
||||
G_found.real_name="[pick(pick(first_names_male,first_names_female))] [pick(last_names)]"//Give them a random real name.
|
||||
|
||||
/*Third, we try and locate a record for the person being respawned through data_core.
|
||||
This isn't an exact science but it does the trick more often than not.*/
|
||||
var/datum/data/record/record_found//Referenced to later to either randomize or not randomize the character.
|
||||
if(G_found.mind)//They must have a mind to reference the record. Here we also double check for aliens.
|
||||
//Now to give them their mind back.
|
||||
G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
|
||||
new_xeno.key = G_found.key
|
||||
new_xeno << "You have been fully respawned. Enjoy the game."
|
||||
message_admins("\blue [key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.", 1)
|
||||
return //all done. The ghost is auto-deleted
|
||||
|
||||
//check if they were a monkey
|
||||
else if(findtext(G_found.real_name,"monkey"))
|
||||
if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes")
|
||||
var/mob/living/carbon/monkey/new_monkey = new(pick(latejoin))
|
||||
G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
|
||||
new_monkey.key = G_found.key
|
||||
new_monkey << "You have been fully respawned. Enjoy the game."
|
||||
message_admins("\blue [key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno.", 1)
|
||||
return //all done. The ghost is auto-deleted
|
||||
|
||||
|
||||
//Ok, it's not a xeno or a monkey. So, spawn a human.
|
||||
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
|
||||
|
||||
var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character.
|
||||
if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
|
||||
/*Try and locate a record for the person being respawned through data_core.
|
||||
This isn't an exact science but it does the trick more often than not.*/
|
||||
var/id = md5("[G_found.real_name][G_found.mind.assigned_role]")
|
||||
for(var/datum/data/record/t in data_core.locked)
|
||||
if(t.fields["id"]==id)
|
||||
record_found = t//We shall now reference the record.
|
||||
break
|
||||
|
||||
//Now we do some mind locating to see how to set up the rest of the character.
|
||||
if(G_found.mind)//If they had a previous mind.
|
||||
new_character.mind = G_found.mind
|
||||
new_character.mind.special_verbs = list()//New list because they will receive them again.
|
||||
if(record_found)//If they have a record we can determine a few things.
|
||||
new_character.real_name = record_found.fields["name"]
|
||||
new_character.gender = record_found.fields["sex"]
|
||||
new_character.age = record_found.fields["age"]
|
||||
new_character.b_type = record_found.fields["b_type"]
|
||||
else
|
||||
new_character.mind = new()
|
||||
ticker.minds += new_character.mind//And we'll add it to the minds database.
|
||||
new_character.mind.original = new_character//If they are respawning with a new character.
|
||||
if(!record_found)//We have to pick their role if they have no record.
|
||||
if(G_found.mind&&G_found.mind.assigned_role)//But they may have an assigned role already.
|
||||
new_character.mind.assigned_role = G_found.mind.assigned_role//Also makes sure our MODE people are equipped right later on.
|
||||
else
|
||||
var/assigned_role = input("Please specify which job the character will be respawned as.", "Assigned role") as null|anything in get_all_jobs()
|
||||
if(!assigned_role) new_character.mind.assigned_role = "Assistant"//Defaults to assistant.
|
||||
else new_character.mind.assigned_role = assigned_role
|
||||
new_character.gender = pick(MALE,FEMALE)
|
||||
var/datum/preferences/A = new()
|
||||
A.randomize_appearance_for(new_character)
|
||||
new_character.real_name = G_found.real_name
|
||||
|
||||
if(!new_character.real_name)
|
||||
if(new_character.gender == MALE)
|
||||
new_character.real_name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
|
||||
else
|
||||
new_character.real_name = capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
|
||||
new_character.name = new_character.real_name
|
||||
new_character.original_name = new_character.real_name
|
||||
|
||||
if(G_found.mind && !G_found.mind.active)
|
||||
G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use
|
||||
new_character.mind.special_verbs = list()
|
||||
else
|
||||
new_character.mind_initialize()
|
||||
if(!new_character.mind.assigned_role) new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role.
|
||||
new_character.mind.key = G_found.key//In case it's someone else playing as that character.
|
||||
new_character.mind.current = new_character//So that it can properly reference later if needed.
|
||||
new_character.mind.memory = ""//Memory erased so it doesn't get clunkered up with useless info. This means they may forget their previous mission--this is usually handled through objective code and recalling memory.
|
||||
|
||||
//Here we either load their saved appearance or randomize it.
|
||||
var/datum/preferences/A = new()
|
||||
if(A.savefile_load(G_found))//If they have a save file. This will automatically load their parameters.
|
||||
//Note: savefile appearances are overwritten later on if the character has a data_core entry. By appearance, I mean the physical appearance.
|
||||
var/name_safety = G_found.real_name//Their saved parameters may include a random name. Also a safety in case they are playing a character that got their name after round start.
|
||||
A.copy_to(new_character)
|
||||
new_character.real_name = name_safety
|
||||
new_character.name = name_safety
|
||||
else
|
||||
if(record_found)//If they have a record we can determine a few things.
|
||||
new_character.real_name = record_found.fields["name"]//Not necessary to reference the record but I like to keep things uniform.
|
||||
new_character.name = record_found.fields["name"]
|
||||
new_character.gender = record_found.fields["sex"]//Sex
|
||||
new_character.age = record_found.fields["age"]//Age
|
||||
new_character.b_type = record_found.fields["b_type"]//Blood type
|
||||
//We will update their appearance when determining DNA.
|
||||
else
|
||||
new_character.gender = MALE
|
||||
if(alert("Save file not detected. Record data not detected. Please specify [G_found.real_name]'s gender.",,"Male","Female")=="Female")
|
||||
new_character.gender = FEMALE
|
||||
var/name_safety = G_found.real_name//Default is a random name so we want to save this.
|
||||
A.randomize_appearance_for(new_character)//Now we will randomize their appearance since we have no way of knowing what they look/looked like.
|
||||
new_character.real_name = name_safety
|
||||
new_character.name = name_safety
|
||||
|
||||
//After everything above, it's time to initialize their DNA.
|
||||
//DNA
|
||||
if(record_found)//Pull up their name from database records if they did have a mind.
|
||||
new_character.dna = new()//Let's first give them a new DNA.
|
||||
new_character.dna.unique_enzymes = record_found.fields["b_dna"]//Enzymes are based on real name but we'll use the record for conformity.
|
||||
@@ -420,10 +380,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
else//If they have no records, we just do a random DNA for them, based on their random appearance/savefile.
|
||||
new_character.dna.ready_dna(new_character)
|
||||
|
||||
//Here we need to find where to spawn them.
|
||||
var/spawn_here = pick(latejoin)//"JoinLate" is a landmark which is deleted on round start. So, latejoin has to be used instead.
|
||||
new_character.loc = spawn_here
|
||||
//If they need to spawn elsewhere, they will be transferred there momentarily.
|
||||
new_character.key = G_found.key
|
||||
|
||||
/*
|
||||
The code below functions with the assumption that the mob is already a traitor if they have a special role.
|
||||
@@ -435,8 +392,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
var/admin = key_name_admin(src)
|
||||
var/player_key = G_found.key
|
||||
|
||||
new_character.key = player_key//Throw them into the mob.
|
||||
|
||||
//Now for special roles and equipment.
|
||||
switch(new_character.mind.special_role)
|
||||
if("Changeling")
|
||||
@@ -497,7 +452,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
|
||||
new_character << "You have been fully respawned. Enjoy the game."
|
||||
|
||||
del(G_found)//Don't want to leave ghosts around.
|
||||
feedback_add_details("admin_verb","RSPCH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return new_character
|
||||
|
||||
|
||||
Reference in New Issue
Block a user