diff --git a/code/__DEFINES/_math.dm b/code/__DEFINES/_math.dm
index f3cdb06cbdb..6ce1dddaf1b 100644
--- a/code/__DEFINES/_math.dm
+++ b/code/__DEFINES/_math.dm
@@ -104,9 +104,6 @@
#define TORADIANS(degrees) ((degrees) * 0.0174532925)
-/// Gets shift x that would be required the bitflag (1< Global Antag Candidacy"
else
output += " Global Antag Candidacy"
- output += "
"
@@ -587,10 +587,10 @@ UI STUFF
continue
if(!check_rights_client(rights_needed, FALSE, X))
continue
- for(var/key in X.pm_tracker.pms)
+ for(var/key in X.persistent.pm_tracker.pms)
if(ckey(key) != ckey(T.client_ckey))
continue
- var/datum/pm_convo/convo = X.pm_tracker.pms[key]
+ var/datum/pm_convo/convo = X.persistent.pm_tracker.pms[key]
if(convo.typing)
dat += "[key] is typing
"
found_typing = TRUE
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 635634fddba..a438d8e557a 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -23,6 +23,8 @@
var/key
var/name //replaces mob/var/original_name
var/mob/living/current
+ /// A serialized copy of this mind's body when it was destroyed, for admin respawn usage.
+ var/destroyed_body_json
/// The original mob's UID. Used for example to see if a silicon with antag status is actually malf. Or just an antag put in a borg
var/original_mob_UID
/// The original mob's name. Used in Dchat messages
@@ -75,9 +77,6 @@
var/list/learned_recipes //List of learned recipe TYPES.
- /// List of people who we've received kudos from.
- var/list/kudos_received_from = list()
-
/datum/mind/New(new_key)
key = new_key
objective_holder = new(src)
@@ -86,8 +85,7 @@
SSticker.minds -= src
remove_all_antag_datums()
qdel(objective_holder)
- current = null
- kudos_received_from.Cut()
+ unbind()
return ..()
/datum/mind/proc/set_original_mob(mob/original)
@@ -126,13 +124,27 @@
return out_ckey
+/datum/mind/proc/archive_deleted_body()
+ SIGNAL_HANDLER // COMSIG_PARENT_QDELETING
+ if(isliving(current))
+ destroyed_body_json = json_encode(current.serialize())
+
+/datum/mind/proc/bind_to(mob/living/new_character)
+ current = new_character
+ new_character.mind = src
+ RegisterSignal(current, COMSIG_PARENT_QDELETING, PROC_REF(archive_deleted_body), override = TRUE)
+
+/datum/mind/proc/unbind()
+ UnregisterSignal(current, COMSIG_PARENT_QDELETING)
+ current.mind = null
+ current = null
+
/datum/mind/proc/transfer_to(mob/living/new_character)
var/datum/atom_hud/antag/hud_to_transfer = antag_hud //we need this because leave_hud() will clear this list
var/mob/living/old_current = current
if(!istype(new_character))
stack_trace("transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob.")
if(current) //remove ourself from our old body's mind variable
- current.mind = null
if(isliving(current))
current.med_hud_set_status()
leave_all_huds() //leave all the huds in the old body, so it won't get huds if somebody else enters it
@@ -141,11 +153,13 @@
new_character.job = current.job //transfer our job over to the new body
- if(new_character.mind) //remove any mind currently in our new body's mind variable
- new_character.mind.current = null
+ unbind()
+
+ if(new_character.mind) //remove any mind currently in our new body's mind variable
+ new_character.mind.unbind()
+
+ bind_to(new_character)
- current = new_character //link ourself to our new body
- new_character.mind = src //and link our new body to ourself
for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body
var/datum/antagonist/A = a
A.on_body_transfer(old_current, current)
@@ -1858,7 +1872,7 @@
error("mind_initialize(): No ticker ready yet! Please inform Carn")
if(!mind.name)
mind.name = real_name
- mind.current = src
+ mind.bind_to(src)
SEND_SIGNAL(src, COMSIG_MIND_INITIALIZE)
//HUMAN
@@ -1870,6 +1884,7 @@
/mob/proc/sync_mind()
mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
mind.active = TRUE //indicates that the mind is currently synced with a client
+ client.persistent.minds |= mind
//slime
/mob/living/simple_animal/slime/mind_initialize()
diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm
index cb4e4048bca..2c45f347277 100644
--- a/code/game/gamemodes/autotraitor/autotraitor.dm
+++ b/code/game/gamemodes/autotraitor/autotraitor.dm
@@ -73,7 +73,7 @@
traitor_count += 1
continue
if(ishuman(player) || is_ai(player))
- if((ROLE_TRAITOR in player.client.prefs.be_special) && !player.client.skip_antag && !jobban_isbanned(player, ROLE_TRAITOR) && !jobban_isbanned(player, ROLE_SYNDICATE))
+ if((ROLE_TRAITOR in player.client.prefs.be_special) && !player.client.persistent.skip_antag && !jobban_isbanned(player, ROLE_TRAITOR) && !jobban_isbanned(player, ROLE_SYNDICATE))
possible_traitors += player.mind
for(var/datum/mind/player in possible_traitors)
for(var/job in restricted_jobs)
@@ -119,7 +119,7 @@
if(SSshuttle.emergency.mode >= SHUTTLE_ESCAPE)
return
- if(character.client && (ROLE_TRAITOR in character.client.prefs.be_special) && !character.client.skip_antag && !jobban_isbanned(character, ROLE_TRAITOR) && !jobban_isbanned(character, ROLE_SYNDICATE))
+ if(character.client && (ROLE_TRAITOR in character.client.prefs.be_special) && !character.client.persistent.skip_antag && !jobban_isbanned(character, ROLE_TRAITOR) && !jobban_isbanned(character, ROLE_SYNDICATE))
var/player_count = 0
var/traitor_count = 0
for(var/mob/living/player in GLOB.mob_list)
diff --git a/code/game/gamemodes/dynamic/antag_rulesets.dm b/code/game/gamemodes/dynamic/antag_rulesets.dm
index 0e6945fb8c1..73b68a855a3 100644
--- a/code/game/gamemodes/dynamic/antag_rulesets.dm
+++ b/code/game/gamemodes/dynamic/antag_rulesets.dm
@@ -146,7 +146,7 @@
if(jobban_isbanned(player, ROLE_SYNDICATE) || jobban_isbanned(player, antagonist_type::job_rank))
continue
// Make sure they want to play antag, and that they're not already something (off station or antag)
- if(player.client.skip_antag || player.mind.offstation_role || player.mind.special_role)
+ if(player.client.persistent.skip_antag || player.mind.offstation_role || player.mind.special_role)
continue
// Make sure they actually want to be this antagonist
if(!(antagonist_type::job_rank in player.client.prefs.be_special))
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 0e77fe92352..000bbb9cc52 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -299,7 +299,7 @@
players = shuffle(players)
// Get a list of all the people who want to be the antagonist for this round
for(var/mob/eligible_player in players)
- if(!eligible_player.client.skip_antag)
+ if(!eligible_player.client.persistent.skip_antag)
if(species_exclusive && (eligible_player.client.prefs.active_character.species != species_exclusive))
continue
if(role in eligible_player.client.prefs.be_special)
@@ -339,7 +339,7 @@
// Get a list of all the people who want to be the antagonist for this round, except those with incompatible species, and those who are already antagonists
for(var/mob/living/carbon/human/player in players)
- if(player.client.skip_antag || !(allow_offstation_roles || !player.mind?.offstation_role) || player.mind?.special_role)
+ if(player.client.persistent.skip_antag || !(allow_offstation_roles || !player.mind?.offstation_role) || player.mind?.special_role)
continue
if(!(role in player.client.prefs.be_special) || (player.client.prefs.active_character.species in species_to_mindflayer))
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 8d37e5ec603..03e6eec9ac1 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1746,18 +1746,29 @@
to_chat(usr, "This will only work on /mob/dead/observer")
return
- var/posttransformoutfit = usr.client.robust_dress_shop()
+ var/list/potential_minds = list()
+ for(var/datum/mind/mind in G.client.persistent.minds)
+ if(ckey(mind.key) == G.ckey && isnull(mind.current) && mind.destroyed_body_json)
+ potential_minds += mind
+ var/outfit = usr.client.robust_dress_shop(potential_minds)
- if(!posttransformoutfit)
+ if(!outfit)
return
- var/mob/living/carbon/human/H = G.incarnate_ghost()
+ var/mob/M
+ if(istype(outfit, /datum/mind))
+ M = G.incarnate_ghost(outfit)
- if(posttransformoutfit && istype(H))
- H.equipOutfit(posttransformoutfit)
+ log_admin("[key_name(M)] was rebuilt from a mind backup by [key_name(owner)]")
+ message_admins("[key_name_admin(M)] was rebuilt from a mind backup by [key_name_admin(owner)]")
+ else
+ M = G.incarnate_ghost()
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ H.equipOutfit(outfit)
- log_admin("[key_name(G)] was incarnated by [key_name(owner)]")
- message_admins("[key_name_admin(G)] was incarnated by [key_name_admin(owner)]")
+ log_admin("[key_name(M)] was incarnated by [key_name(owner)]")
+ message_admins("[key_name_admin(M)] was incarnated by [key_name_admin(owner)]")
else if(href_list["togmutate"])
if(!check_rights(R_SPAWN)) return
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index e8de49e3c02..8a63a8e1541 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -7,8 +7,6 @@
to_chat(src, "Error: Admin-PM: You cannot send adminhelps (Muted).", MESSAGE_TYPE_ADMINPM, confidential = TRUE)
return
- adminhelped = TRUE //Determines if they get the message to reply by clicking the name.
-
var/msg
var/list/type = list("Mentorhelp", "Adminhelp")
var/selected_type = input("Pick a category.", "Admin Help") as null|anything in type
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 47955f68a22..650d84c57de 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -158,15 +158,15 @@
var/receive_message = ""
- pm_tracker.add_message(C, src, msg, mob)
- C.pm_tracker.add_message(src, src, msg, C.mob)
+ persistent.pm_tracker.add_message(C, src, msg, mob)
+ C.persistent.pm_tracker.add_message(src, src, msg, C.mob)
if(holder && !C.holder)
receive_message = "-- Click the [receive_pm_type]'s name to reply --\n"
- if(C.adminhelped)
+ to_chat(C, receive_message)
+ if(message_type == MESSAGE_TYPE_ADMINPM)
+ // Try to get their attention if they're alt-tabbed.
window_flash(C)
- to_chat(C, receive_message)
- C.adminhelped = 0
//AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
if(GLOB.configuration.general.popup_admin_pm)
@@ -181,9 +181,9 @@
adminhelp(reply) //sender has left, adminhelp instead
return
- var/ping_link = check_rights(R_ADMIN, 0, mob) ? "(PING)" : ""
+ var/ping_link = check_rights(R_ADMIN, 0, mob) ? "(PING)" : ""
var/ticket_link
- var/alert_link = check_rights(R_ADMIN, FALSE, mob) ? "(ALERT)" : ""
+ var/alert_link = check_rights(R_ADMIN, FALSE, mob) ? "(ALERT)" : ""
var/observe_link = check_rights(R_MENTOR, FALSE, mob) ? "([ADMIN_OBS(C, "OBS")])" : ""
if(ticket_id != -1)
if(message_type == MESSAGE_TYPE_MENTORPM)
@@ -192,7 +192,7 @@
ticket_link = "(TICKET)"
var/emoji_msg = "[msg]"
- var/receive_window_link = "(WINDOW)"
+ var/receive_window_link = "(WINDOW)"
if(message_type == MESSAGE_TYPE_MENTORPM && check_rights(R_ADMIN|R_MENTOR, 0, C.mob))
receive_window_link = ticket_link
else if(message_type == MESSAGE_TYPE_ADMINPM && check_rights(R_ADMIN, 0, C.mob))
@@ -204,7 +204,7 @@
receive_message = chat_box_ahelp(receive_message)
to_chat(C, receive_message)
if(C != src)
- var/send_window_link = "(WINDOW)"
+ var/send_window_link = "(WINDOW)"
if(message_type == MESSAGE_TYPE_MENTORPM && check_rights(R_ADMIN|R_MENTOR, 0, mob))
send_window_link = ticket_link
else if(message_type == MESSAGE_TYPE_ADMINPM && check_rights(R_ADMIN, 0, mob))
@@ -285,18 +285,18 @@
/client/verb/open_pms_ui()
set name = "My PMs"
set category = "OOC"
- pm_tracker.show_ui(usr)
+ persistent.pm_tracker.show_ui(usr)
/client/proc/set_typing(client/target, value)
if(!target)
return
- var/datum/pm_convo/convo = target.pm_tracker.pms[key]
+ var/datum/pm_convo/convo = target.persistent.pm_tracker.pms[key]
if(!convo)
convo = new /datum/pm_convo(src)
- target.pm_tracker.pms[key] = convo
+ target.persistent.pm_tracker.pms[key] = convo
convo.typing = value
- if(target.pm_tracker.open && target.pm_tracker.current_title == key)
- target.pm_tracker.show_ui(target.mob)
+ if(target.persistent.pm_tracker.open && target.persistent.pm_tracker.current_title == key)
+ target.persistent.pm_tracker.show_ui(target.mob)
/datum/pm_tracker
var/ckey
@@ -449,10 +449,10 @@
if(href_list["ping"])
var/client/C = pms[href_list["ping"]].client
if(C)
- C.pm_tracker.current_title = usr.key
- C.pm_tracker.forced = TRUE // We forced it open
+ C.persistent.pm_tracker.current_title = usr.key
+ C.persistent.pm_tracker.forced = TRUE // We forced it open
window_flash(C)
- C.pm_tracker.show_ui(C.mob)
+ C.persistent.pm_tracker.show_ui(C.mob)
to_chat(usr, "Forced open [C]'s messages window.")
return
diff --git a/code/modules/admin/verbs/deathsquad.dm b/code/modules/admin/verbs/deathsquad.dm
index e984f4b1ce0..174e17c8dd3 100644
--- a/code/modules/admin/verbs/deathsquad.dm
+++ b/code/modules/admin/verbs/deathsquad.dm
@@ -163,7 +163,7 @@ GLOBAL_VAR_INIT(deathsquad_sent, FALSE)
R.custom_name = borgname
R.real_name = R.name
R.mind = new
- R.mind.current = R
+ R.mind.bind_to(R)
R.mind.set_original_mob(R)
R.mind.assigned_role = SPECIAL_ROLE_DEATHSQUAD
R.mind.special_role = SPECIAL_ROLE_DEATHSQUAD
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 222124060cd..0d54cfb624f 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -621,12 +621,14 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].")
message_admins("[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].", 1)
-/client/proc/robust_dress_shop()
+/client/proc/robust_dress_shop(list/potential_minds)
var/list/special_outfits = list(
"Naked",
"As Job...",
"Custom..."
)
+ if(length(potential_minds))
+ special_outfits += "Recover destroyed body..."
var/list/outfits = list()
var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) - list(/datum/outfit/varedit, /datum/outfit/admin)
@@ -665,6 +667,9 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
dresscode = custom_names[selected_name]
if(isnull(dresscode))
return
+
+ if(dresscode == "Recover destroyed body...")
+ dresscode = input("Select body to rebuild", "Robust quick dress shop") as null|anything in potential_minds
return dresscode
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index ca0092f88ae..89597123153 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -36,7 +36,7 @@
if((M.mind.assigned_role in temp.restricted_jobs) || (M.client.prefs.active_character.species in temp.species_to_mindflayer))
return FALSE
if(role) // Don't even bother evaluating if there's no role
- if(player_old_enough_antag(M.client,role) && (role in M.client.prefs.be_special) && !M.client.skip_antag && (!jobban_isbanned(M, role)))
+ if(player_old_enough_antag(M.client,role) && (role in M.client.prefs.be_special) && !M.client.persistent.skip_antag && (!jobban_isbanned(M, role)))
return TRUE
else
return FALSE
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index 38eb3c674db..ad8d8734e02 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -6,31 +6,27 @@
////////////////
/// hides the byond verb panel as we use our own custom version
show_verb_panel = FALSE
+
+ var/datum/persistent_client/persistent
+
var/datum/admins/holder = null
var/last_message = "" //contains the last message sent by this client - used to protect against copy-paste spamming.
var/last_message_count = 0 //contains a number of how many times a message identical to last_message was sent.
var/last_message_time = 0 //holds the last time (based on world.time) a message was sent
- var/datum/pm_tracker/pm_tracker
/////////
//OTHER//
/////////
var/datum/preferences/prefs = null
- var/skip_antag = FALSE //TRUE when a player declines to be included for the selection process of game mode antagonists.
///The visual delay to use for the current client.Move(), mostly used for making a client based move look like it came from some other slower source
var/visual_delay = 0
var/move_delay = 1
var/moving = null
var/area = null
- // why the hell do we track this when you can just file > reconnect to bypass it
- var/time_died_as_mouse = null //when the client last died as a mouse
-
var/typing = FALSE // Prevents typing window stacking
- var/adminhelped = 0
-
///////////////
//SOUND STUFF//
///////////////
@@ -235,3 +231,15 @@
/// If this client has any windows scaling applied
var/window_scaling
+
+/datum/persistent_client
+ /// Holds admin/mentor PM history.
+ var/datum/pm_tracker/pm_tracker
+ /// The Global Antag Candidacy setting from the new player menu.
+ var/skip_antag = FALSE
+ /// Used to prevent rapid mouse spamming.
+ var/time_died_as_mouse = null
+ /// All of the minds this client has been associated with.
+ var/list/minds = list()
+ /// Ckeys that sent us kudos.
+ var/list/kudos_received_from = list()
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index d43679372be..f5b60b6c797 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -278,8 +278,10 @@
stat_panel = new(src, "statbrowser")
stat_panel.subscribe(src, PROC_REF(on_stat_panel_message))
- // Create a PM tracker bound to this ckey.
- pm_tracker = new(ckey)
+ persistent = GLOB.persistent_clients[ckey]
+ if(!persistent)
+ persistent = new(ckey)
+ GLOB.persistent_clients[ckey] = persistent
tgui_panel = new(src, "chat_panel")
tgui_say = new(src, "tgui_say")
@@ -1340,6 +1342,9 @@
src << link("https://secure.byond.com/download/")
+/datum/persistent_client/New(ckey)
+ // Create a PM tracker bound to this ckey.
+ pm_tracker = new(ckey)
#undef LIMITER_SIZE
#undef CURRENT_SECOND
diff --git a/code/modules/mob/dead/observer/observer_base.dm b/code/modules/mob/dead/observer/observer_base.dm
index a6ec09ea865..0b747043960 100644
--- a/code/modules/mob/dead/observer/observer_base.dm
+++ b/code/modules/mob/dead/observer/observer_base.dm
@@ -803,17 +803,19 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return TRUE
-/mob/dead/observer/proc/incarnate_ghost()
+/mob/dead/observer/proc/incarnate_ghost(datum/mind/from_mind = null)
if(!client)
return
- var/mob/living/carbon/human/new_char = new(get_turf(src))
- client.prefs.active_character.copy_to(new_char)
- if(mind)
- mind.active = TRUE
- mind.transfer_to(new_char)
+ var/mob/new_char
+ if(from_mind)
+ new_char = json_to_object(from_mind.destroyed_body_json, get_turf(src))
+ from_mind.transfer_to(new_char)
else
- new_char.key = key
+ new_char = new /mob/living/carbon/human(get_turf(src))
+ client.prefs.active_character.copy_to(new_char)
+ if(!new_char.ckey)
+ new_char.ckey = ckey
return new_char
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 0562bb5bed4..d13909c7e3c 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -57,7 +57,7 @@
S.be_replaced()
QDEL_NULL(middleClickOverride)
if(mind?.current == src)
- mind.current = null
+ mind.unbind()
UnregisterSignal(src, COMSIG_ATOM_PREHIT)
return ..()
diff --git a/code/modules/mob/living/silicon/robot/robot_mob.dm b/code/modules/mob/living/silicon/robot/robot_mob.dm
index 47d59139fa5..453455ac936 100644
--- a/code/modules/mob/living/silicon/robot/robot_mob.dm
+++ b/code/modules/mob/living/silicon/robot/robot_mob.dm
@@ -1626,7 +1626,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
custom_name = borgname
real_name = name
mind = new
- mind.current = src
+ mind.bind_to(src)
mind.set_original_mob(src)
mind.assigned_role = SPECIAL_ROLE_ERT
mind.special_role = SPECIAL_ROLE_ERT
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 3221b803cbb..8c58d1974ed 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -126,7 +126,7 @@
return FALSE
layer = MOB_LAYER
if(client)
- client.time_died_as_mouse = world.time
+ client.persistent.time_died_as_mouse = world.time
/*
* Mouse types
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 4cec48dda07..9c5d853ea20 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -965,9 +965,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
/mob/proc/is_mechanical()
return mind && (mind.assigned_role == "Cyborg" || mind.assigned_role == "AI")
-/mob/proc/is_ready()
- return client && !!mind
-
/mob/proc/is_in_brig()
if(!loc || !loc.loc)
return 0
@@ -1107,8 +1104,8 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
* Returns true if the player successfully becomes a mouse
*/
/mob/proc/become_mouse()
- var/timedifference = world.time - client.time_died_as_mouse
- if(client.time_died_as_mouse && timedifference <= GLOB.mouse_respawn_time * 600)
+ var/timedifference = world.time - client.persistent.time_died_as_mouse
+ if(client.persistent.time_died_as_mouse && timedifference <= GLOB.mouse_respawn_time * 600)
var/timedifference_text = time2text(GLOB.mouse_respawn_time * 600 - timedifference,"mm:ss")
to_chat(src, "You may only spawn again as a mouse more than [GLOB.mouse_respawn_time] minutes after your death. You have [timedifference_text] left.")
return FALSE
@@ -1519,10 +1516,10 @@ GLOBAL_LIST_INIT(holy_areas, typecacheof(list(
// Pretend we've always succeeded when we might not have.
// This should prevent people from using it to suss anything out about mobs' states
- if(!client || !target.mind)
+ if(!client || !target.client)
return
- target.mind.kudos_received_from |= ckey
+ target.client.persistent.kudos_received_from |= ckey
/mob/living/simple_animal/relaymove(mob/living/user, direction)
if(user.incapacitated())
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 280a4fa145a..c62633d9986 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -19,7 +19,8 @@
/mob/new_player/Destroy()
if(mind)
- mind.current = null // We best null their mind as well, otherwise /every/ single new player is going to explode the server a little more going in/out of the round
+ // Minds really shouldn't bind to new players, but just in case...
+ mind.unbind()
return ..()
/mob/new_player/proc/new_player_panel()
@@ -62,11 +63,11 @@
var/list/antags = client.prefs.be_special
if(length(antags))
- if(!client.skip_antag)
+ if(!client.persistent.skip_antag)
output += "
You are [client.skip_antag ? "ineligible" : "eligible"] for all antag roles.
You are [client.persistent.skip_antag ? "ineligible" : "eligible"] for all antag roles.
Observe (Please wait...)
" @@ -143,7 +144,7 @@ new_player_panel_proc() if(href_list["skip_antag"]) - client.skip_antag = !client.skip_antag + client.persistent.skip_antag = !client.persistent.skip_antag new_player_panel_proc() if(href_list["refresh"]) @@ -613,8 +614,8 @@ if(!client || !client.prefs) ..() return client.prefs.active_character.gender -/mob/new_player/is_ready() - return ready && ..() +/mob/new_player/proc/is_ready() + return ready && client // No hearing announcements /mob/new_player/can_hear() diff --git a/code/modules/mob/new_player/new_player_login.dm b/code/modules/mob/new_player/new_player_login.dm index 95225af0d00..036618d9751 100644 --- a/code/modules/mob/new_player/new_player_login.dm +++ b/code/modules/mob/new_player/new_player_login.dm @@ -3,11 +3,6 @@ if(GLOB.join_motd) to_chat(src, "