diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index dbe8cfbb62..fe88832e8d 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -119,8 +119,13 @@ #define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) #define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source) +// /mind signals +#define COMSIG_MIND_TRANSFER "mind_transfer" //from base of mind/transfer_to(): (new_character) + // /mob signals #define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed) +#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize() (can_reenter_corpse) + #define COMPONENT_BLOCK_GHOSTING 1 #define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj #define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (magic, holy, protection_sources) #define COMPONENT_BLOCK_MAGIC 1 @@ -130,6 +135,7 @@ #define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) #define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params) #define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target) +#define COMSIG_MOB_KEY_CHANGE "mob_key_change" //from base of /mob/transfer_key() // /mob/living signals #define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) @@ -146,6 +152,9 @@ #define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag) #define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value) +// /machinery signals +#define COMSIG_MACHINE_EJECT_OCCUPANT "eject_occupant" //from base of obj/machinery/dropContents() (occupant) + // /obj/item signals #define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) #define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 899ef16306..133d7eefc1 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -479,7 +479,7 @@ G_found.client.prefs.copy_to(new_character) new_character.dna.update_dna_identity() - new_character.key = G_found.key + G_found.transfer_key(new_character, FALSE) return new_character diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm index 1bc7d8e3be..37fbc243d2 100644 --- a/code/datums/brain_damage/imaginary_friend.dm +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -46,7 +46,7 @@ var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s imaginary friend?", ROLE_PAI, null, null, 75, friend) if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) - friend.key = C.key + C.transfer_key(friend, FALSE) friend_initialized = TRUE else qdel(src) diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm index 9ce65717f1..6a2f8682a5 100644 --- a/code/datums/brain_damage/split_personality.dm +++ b/code/datums/brain_damage/split_personality.dm @@ -26,7 +26,7 @@ var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat) if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) - stranger_backseat.key = C.key + C.transfer_key(stranger_backseat, FALSE) log_game("[key_name(stranger_backseat)] became [key_name(owner)]'s split personality.") message_admins("[ADMIN_LOOKUPFLW(stranger_backseat)] became [ADMIN_LOOKUPFLW(owner)]'s split personality.") else @@ -184,7 +184,7 @@ var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s brainwashed mind?", null, null, null, 75, stranger_backseat) if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) - stranger_backseat.key = C.key + C.transfer_key(stranger_backseat, FALSE) else qdel(src) diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm new file mode 100644 index 0000000000..0bc1f9d8ec --- /dev/null +++ b/code/datums/components/virtual_reality.dm @@ -0,0 +1,88 @@ +/datum/component/virtual_reality + dupe_mode = COMPONENT_DUPE_UNIQUE + var/datum/mind/real_mind // where is my mind t. pixies + var/datum/mind/current_mind + var/obj/machinery/vr_sleeper/vr_sleeper + var/datum/action/quit_vr/quit_action + var/you_die_in_the_game_you_die_for_real = FALSE + +/datum/component/virtual_reality/Initialize(datum/mind/mastermind, obj/machinery/vr_sleeper/gaming_pod, yolo = FALSE, new_char = TRUE) + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + + you_die_in_the_game_you_die_for_real = yolo + quit_action = new() + quit_action.Grant(parent) + if(gaming_pod) + vr_sleeper = gaming_pod + RegisterSignal(vr_sleeper, COMSIG_ATOM_EMAG_ACT, .proc/you_only_live_once) + RegisterSignal(vr_sleeper, COMSIG_MACHINE_EJECT_OCCUPANT, .proc/revert_to_reality) + +/datum/component/virtual_reality/RegisterWithParent() + var/mob/M = parent + current_mind = M.mind + RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/game_over) + RegisterSignal(parent, COMSIG_MOB_KEY_CHANGE, .proc/pass_me_the_remote) + RegisterSignal(current_mind, COMSIG_MIND_TRANSFER, .proc/pass_me_the_remote) + RegisterSignal(parent, COMSIG_MOB_GHOSTIZE, .proc/be_a_quitter) + RegisterSignal(quit_action, COMSIG_ACTION_TRIGGER, .proc/revert_to_reality) + +/datum/component/virtual_reality/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_MOB_DEATH, COMSIG_MOB_KEY_CHANGE, COMSIG_MOB_GHOSTIZE)) + UnregisterSignal(quit_action, COMSIG_ACTION_TRIGGER) + UnregisterSignal(current_mind, COMSIG_MIND_TRANSFER) + +/datum/component/virtual_reality/proc/action_trigger(datum/signal_source, datum/action/source) + if(source != quit_action) + return COMPONENT_ACTION_BLOCK_TRIGGER + revert_to_reality(signal_source) + +/datum/component/virtual_reality/proc/you_only_live_once() + if(you_die_in_the_game_you_die_for_real) + return FALSE + you_die_in_the_game_you_die_for_real = TRUE + return TRUE + +/datum/component/virtual_reality/proc/pass_me_the_remote(datum/source, mob/new_mob) + if(new_mob == real_mind.current) + revert_to_reality(source) + new_mob.TakeComponent(src) + return TRUE + +/datum/component/virtual_reality/PostTransfer() + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/virtual_reality/proc/revert_to_reality(datum/source) + quit_it(FALSE) + +/datum/component/virtual_reality/proc/game_over(datum/source) + quit_it(TRUE) + +/datum/component/virtual_reality/proc/be_a_quitter(datum/source) + quit_it(FALSE) + return COMPONENT_BLOCK_GHOSTING + +/datum/component/virtual_reality/proc/quit_it(deathcheck = FALSE) + var/mob/M = parent + if(!real_mind) + to_chat(M, "You feel as if something terrible happened, you try to wake up from this dream... but you can't...") + else + real_mind.current.audiovisual_redirect = null + real_mind.current.ckey = M.ckey + real_mind.current.stop_sound_channel(CHANNEL_HEARTBEAT) + if(deathcheck) + var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M) + if(cleanbot) + LAZYADD(cleanbot.corpse_party, M) + if(you_die_in_the_game_you_die_for_real) + to_chat(real_mind, "You feel everything fading away...") + real_mind.current.death(0) + if(vr_sleeper) + vr_sleeper.vr_mob = null + vr_sleeper = null + qdel(src) + +/datum/component/virtual_reality/Destroy() + QDEL_NULL(quit_action) + return ..() \ No newline at end of file diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index b295f5f10b..df6f2e34a1 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -63,11 +63,11 @@ if(istype(new_mob)) if(bantype && jobban_isbanned(affected_mob, bantype)) replace_banned_player(new_mob) - new_mob.a_intent = INTENT_HARM - if(affected_mob.mind) - affected_mob.mind.transfer_to(new_mob) - else - new_mob.key = affected_mob.key + new_mob.a_intent = INTENT_HARM + if(affected_mob.mind) + affected_mob.mind.transfer_to(new_mob) + else + affected_mob.transfer_key(new_mob) new_mob.name = affected_mob.real_name new_mob.real_name = new_mob.name @@ -82,7 +82,7 @@ to_chat(affected_mob, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!") message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(affected_mob)]) to replace a jobbaned player.") affected_mob.ghostize(0) - affected_mob.key = C.key + C.transfer_key(affected_mob) else to_chat(new_mob, "Your mob has been claimed by death! Appeal your job ban if you want to avoid this in the future!") new_mob.death() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 90affe0228..2844a59d61 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -19,9 +19,9 @@ - IMPORTANT NOTE 2, if you want a player to become a ghost, use mob.ghostize() It does all the hard work for you. - When creating a new mob which will be a new IC character (e.g. putting a shade in a construct or randomly selecting - a ghost to become a xeno during an event). Simply assign the key or ckey like you've always done. + a ghost to become a xeno during an event), use this mob proc. - new_mob.key = key + mob.transfer_key(new_mob) The Login proc will handle making a new mind for that mobtype (including setting up stuff like mind.name). Simple! However if you want that mind to have any special properties like being a traitor etc you will have to do that @@ -121,6 +121,7 @@ transfer_martial_arts(new_character) if(active || force_key_move) new_character.key = key //now transfer the key to link the client to our new body + SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character) //CIT CHANGE - makes arousal update when transfering bodies if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs. diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 9b5aa96b0b..ac975c2ffd 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -175,6 +175,7 @@ Class Procs: if(isliving(A)) var/mob/living/L = A L.update_canmove() + SEND_SIGNAL(src, COMSIG_MACHINE_EJECT_OCCUPANT, occupant) occupant = null /obj/machinery/proc/close_machine(atom/movable/target = null) @@ -479,6 +480,7 @@ Class Procs: /obj/machinery/Exited(atom/movable/AM, atom/newloc) . = ..() if (AM == occupant) + SEND_SIGNAL(src, COMSIG_MACHINE_EJECT_OCCUPANT, occupant) occupant = null /obj/machinery/proc/adjust_item_drop_location(atom/movable/AM) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8 diff --git a/code/game/machinery/exp_cloner.dm b/code/game/machinery/exp_cloner.dm index 45ac999a6a..4d0ec9f1d9 100644 --- a/code/game/machinery/exp_cloner.dm +++ b/code/game/machinery/exp_cloner.dm @@ -52,7 +52,7 @@ var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone?", null, null, null, 100, H) if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) - H.key = C.key + C.transfer_key(H) if(grab_ghost_when == CLONER_FRESH_CLONE) H.grab_ghost() diff --git a/code/modules/VR/vr_human.dm b/code/modules/VR/vr_human.dm deleted file mode 100644 index 53a4bbe540..0000000000 --- a/code/modules/VR/vr_human.dm +++ /dev/null @@ -1,61 +0,0 @@ -/mob/living/carbon/human/virtual_reality - var/datum/mind/real_mind // where is my mind t. pixies - var/obj/machinery/vr_sleeper/vr_sleeper - var/datum/action/quit_vr/quit_action - -/mob/living/carbon/human/virtual_reality/Initialize() - . = ..() - quit_action = new() - quit_action.Grant(src) - -/mob/living/carbon/human/virtual_reality/death() - revert_to_reality() - ..() - -/mob/living/carbon/human/virtual_reality/Destroy() - revert_to_reality() - return ..() - -/mob/living/carbon/human/virtual_reality/Life() - . = ..() - if(real_mind) - var/mob/living/real_me = real_mind.current - if (real_me && real_me.stat == CONSCIOUS) - return - revert_to_reality(FALSE) - -/mob/living/carbon/human/virtual_reality/ghostize() - stack_trace("Ghostize was called on a virtual reality mob") - -/mob/living/carbon/human/virtual_reality/ghost() - set category = "OOC" - set name = "Ghost" - set desc = "Relinquish your life and enter the land of the dead." - revert_to_reality(FALSE) - -/mob/living/carbon/human/virtual_reality/proc/revert_to_reality(deathchecks = TRUE) - if(real_mind && mind) - real_mind.current.audiovisual_redirect = null - real_mind.current.ckey = ckey - real_mind.current.stop_sound_channel(CHANNEL_HEARTBEAT) - if(deathchecks && vr_sleeper) - if(vr_sleeper.you_die_in_the_game_you_die_for_real) - to_chat(real_mind, "You feel everything fading away...") - real_mind.current.death(0) - if(deathchecks && vr_sleeper) - vr_sleeper.vr_human = null - vr_sleeper = null - real_mind = null - -/datum/action/quit_vr - name = "Quit Virtual Reality" - icon_icon = 'icons/mob/actions/actions_vr.dmi' - button_icon_state = "logout" - -/datum/action/quit_vr/Trigger() - if(..()) - if(istype(owner, /mob/living/carbon/human/virtual_reality)) - var/mob/living/carbon/human/virtual_reality/VR = owner - VR.revert_to_reality(FALSE) - else - Remove(owner) diff --git a/code/modules/VR/vr_mob.dm b/code/modules/VR/vr_mob.dm new file mode 100644 index 0000000000..4f8a7daf34 --- /dev/null +++ b/code/modules/VR/vr_mob.dm @@ -0,0 +1,42 @@ +/mob/proc/build_virtual_character(mob/M) + mind_initialize() + if(!M) + return FALSE + name = M.name + real_name = M.real_name + return TRUE + +/mob/living/carbon/build_virtual_character(mob/M) + . = ..() + if(!.) + return + if(!iscarbon(M)) + return FALSE + var/mob/living/carbon/C = M + C.dna?.transfer_identity(src) + +/mob/living/carbon/human/build_virtual_character(mob/M, datum/outfit/outfit) + . = ..() + if(!.) + return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + socks = H.socks + undershirt = H.undershirt + underwear = H.underwear + give_genitals(TRUE) + if(outfit) + var/datum/outfit/O = new outfit() + O.equip(src) + name = M.name + real_name = M.real_name + +/datum/action/quit_vr + name = "Quit Virtual Reality" + icon_icon = 'icons/mob/actions/actions_vr.dmi' + button_icon_state = "logout" + +/datum/action/quit_vr/Trigger() //this merely a trigger for /datum/component/virtual_reality + . = ..() + if(!.) + Remove(owner) diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index 4e342f6ced..afc8de6e21 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -1,5 +1,3 @@ - - //Glorified teleporter that puts you in a new human body. // it's """VR""" /obj/machinery/vr_sleeper @@ -12,9 +10,9 @@ circuit = /obj/item/circuitboard/machine/vr_sleeper var/you_die_in_the_game_you_die_for_real = FALSE var/datum/effect_system/spark_spread/sparks - var/mob/living/carbon/human/virtual_reality/vr_human + var/mob/living/vr_mob var/vr_category = "default" //Specific category of spawn points to pick from - var/allow_creating_vr_humans = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games + var/allow_creating_vr_mobs = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games var/only_current_user_can_interact = FALSE /obj/machinery/vr_sleeper/Initialize() @@ -44,7 +42,7 @@ /obj/machinery/vr_sleeper/Destroy() open_machine() - cleanup_vr_human() + cleanup_vr_mob() QDEL_NULL(sparks) return ..() @@ -57,6 +55,10 @@ return /obj/machinery/vr_sleeper/emag_act(mob/user) + . = ..() + if(!(obj_flags & EMAGGED)) + return + obj_flags |= EMAGGED you_die_in_the_game_you_die_for_real = TRUE sparks.start() addtimer(CALLBACK(src, .proc/emagNotify), 150) @@ -65,12 +67,11 @@ icon_state = "[initial(icon_state)][state_open ? "-open" : ""]" /obj/machinery/vr_sleeper/open_machine() - if(!state_open) - if(vr_human) - vr_human.revert_to_reality(FALSE) - if(occupant) - SStgui.close_user_uis(occupant, src) - ..() + if(state_open) + return + if(occupant) + SStgui.close_user_uis(occupant, src) + return ..() /obj/machinery/vr_sleeper/MouseDrop_T(mob/target, mob/user) if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser()) @@ -91,21 +92,21 @@ var/mob/living/carbon/human/human_occupant = occupant if(human_occupant && human_occupant.mind && usr == occupant) to_chat(occupant, "Transferring to virtual reality...") - if(vr_human && vr_human.stat == CONSCIOUS && !vr_human.real_mind) + if(vr_mob && vr_mob.stat == CONSCIOUS && !vr_mob.GetComponent(/datum/component/virtual_reality)) SStgui.close_user_uis(occupant, src) - human_occupant.audiovisual_redirect = vr_human - vr_human.real_mind = human_occupant.mind - vr_human.ckey = human_occupant.ckey - to_chat(vr_human, "Transfer successful! You are now playing as [vr_human] in VR!") + vr_mob.AddComponent(/datum/component/virtual_reality, human_occupant.mind, src, you_die_in_the_game_you_die_for_real) + human_occupant.audiovisual_redirect = vr_mob + vr_mob.ckey = human_occupant.ckey + to_chat(vr_mob, "Transfer successful! You are now playing as [vr_mob] in VR!") else - if(allow_creating_vr_humans) + if(allow_creating_vr_mobs) to_chat(occupant, "Virtual avatar not found, attempting to create one...") var/obj/effect/landmark/vr_spawn/V = get_vr_spawnpoint() var/turf/T = get_turf(V) if(T) SStgui.close_user_uis(occupant, src) - build_virtual_human(occupant, T, V.vr_outfit) - to_chat(vr_human, "Transfer successful! You are now playing as [vr_human] in VR!") + new_player(occupant, T, V.vr_outfit) + to_chat(vr_mob, "Transfer successful! You are now playing as [vr_mob] in VR!") else to_chat(occupant, "Virtual world misconfigured, aborting transfer") else @@ -113,8 +114,8 @@ . = TRUE if("delete_avatar") if(!occupant || usr == occupant) - if(vr_human) - cleanup_vr_human() + if(vr_mob) + cleanup_vr_mob() else to_chat(usr, "The VR Sleeper's safeties prevent you from doing that.") . = TRUE @@ -127,10 +128,10 @@ /obj/machinery/vr_sleeper/ui_data(mob/user) var/list/data = list() - if(vr_human && !QDELETED(vr_human)) + if(vr_mob && !QDELETED(vr_mob)) data["can_delete_avatar"] = TRUE var/status - switch(vr_human.stat) + switch(vr_mob.stat) if(CONSCIOUS) status = "Conscious" if(DEAD) @@ -139,7 +140,7 @@ status = "Unconscious" if(SOFT_CRIT) status = "Barely Conscious" - data["vr_avatar"] = list("name" = vr_human.name, "status" = status, "health" = vr_human.health, "maxhealth" = vr_human.maxHealth) + data["vr_avatar"] = list("name" = vr_mob.name, "status" = status, "health" = vr_mob.health, "maxhealth" = vr_mob.maxHealth) data["toggle_open"] = state_open data["emagged"] = you_die_in_the_game_you_die_for_real data["isoccupant"] = (user == occupant) @@ -153,37 +154,28 @@ for(var/obj/effect/landmark/vr_spawn/V in GLOB.landmarks_list) GLOB.vr_spawnpoints[V.vr_category] = V -/obj/machinery/vr_sleeper/proc/build_virtual_human(mob/living/carbon/human/H, location, var/datum/outfit/outfit, transfer = TRUE) - if(H) - cleanup_vr_human() - vr_human = new /mob/living/carbon/human/virtual_reality(location) - vr_human.mind_initialize() - vr_human.vr_sleeper = src - vr_human.real_mind = H.mind - H.dna.transfer_identity(vr_human) - vr_human.name = H.name - vr_human.real_name = H.real_name - vr_human.socks = H.socks - vr_human.undershirt = H.undershirt - vr_human.underwear = H.underwear - vr_human.updateappearance(TRUE, TRUE, TRUE) - vr_human.give_genitals(TRUE) //CITADEL ADD - if(outfit) - var/datum/outfit/O = new outfit() - O.equip(vr_human) - if(transfer && H.mind) - SStgui.close_user_uis(H, src) - H.audiovisual_redirect = vr_human - vr_human.ckey = H.ckey +/obj/machinery/vr_sleeper/proc/new_player(mob/living/carbon/human/H, location, datum/outfit/outfit, transfer = TRUE) + if(!H) + return + cleanup_vr_mob() + vr_mob = new /mob/living/carbon/human(location) + if(vr_mob.build_virtual_character(H, outfit)) + var/mob/living/carbon/human/vr_H = vr_mob + vr_H.updateappearance(TRUE, TRUE, TRUE) + if(!transfer || !H.mind) + return + vr_mob.AddComponent(/datum/component/virtual_reality, H.mind, src, you_die_in_the_game_you_die_for_real) + SStgui.close_user_uis(H, src) + H.audiovisual_redirect = vr_mob + vr_mob.ckey = H.ckey -/obj/machinery/vr_sleeper/proc/cleanup_vr_human() - if(vr_human) - vr_human.vr_sleeper = null // Prevents race condition where a new human could get created out of order and set to null. - QDEL_NULL(vr_human) +/obj/machinery/vr_sleeper/proc/cleanup_vr_mob() + if(vr_mob) + QDEL_NULL(vr_mob) /obj/machinery/vr_sleeper/proc/emagNotify() - if(vr_human) - vr_human.Dizzy(10) + if(vr_mob) + vr_mob.Dizzy(10) /obj/effect/landmark/vr_spawn //places you can spawn in VR, auto selected by the vr_sleeper during get_vr_spawnpoint() var/vr_category = "default" //So we can have specific sleepers, eg: "Basketball VR Sleeper", etc. @@ -215,6 +207,7 @@ color = "#00FF00" invisibility = INVISIBILITY_ABSTRACT var/area/vr_area + var/list/corpse_party /obj/effect/vr_clean_master/Initialize() . = ..() @@ -227,7 +220,8 @@ qdel(casing) for(var/obj/effect/decal/cleanable/C in vr_area) qdel(C) - for (var/mob/living/carbon/human/virtual_reality/H in vr_area) - if (H.stat == DEAD && !H.vr_sleeper && !H.real_mind) - qdel(H) + for (var/A in corpse_party) + var/mob/M = A + if(get_area(M) == vr_area && M.stat == DEAD) + qdel(M) addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES) diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index da811a1974..281fb49f05 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -61,7 +61,7 @@ to_chat(body, "Your mob has been taken over by a ghost!") message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(body)])") body.ghostize(0) - body.key = C.key + C.transfer_key(body) new /obj/effect/temp_visual/gravpush(get_turf(body)) /obj/effect/fun_balloon/sentience/emergency_shuttle diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 66358dc080..db6a5b9e88 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -744,7 +744,7 @@ var/mob/chosen = players[1] if (chosen.client) chosen.client.prefs.copy_to(spawnedMob) - spawnedMob.key = chosen.key + chosen.transfer_key(spawnedMob) players -= chosen if (ishuman(spawnedMob) && ispath(humanoutfit, /datum/outfit)) var/mob/living/carbon/human/H = spawnedMob diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index d9732818bd..5409934abf 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -412,7 +412,7 @@ //Spawn the body var/mob/living/carbon/human/ERTOperative = new ertemplate.mobtype(spawnloc) chosen_candidate.client.prefs.copy_to(ERTOperative) - ERTOperative.key = chosen_candidate.key + chosen_candidate.transfer_key(ERTOperative) if(ertemplate.enforce_human || ERTOperative.dna.species.dangerous_existence) // Don't want any exploding plasmemes ERTOperative.set_species(/datum/species/human) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index f74b31760d..bbeb6a963e 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -384,7 +384,7 @@ Traitors and the like can also be revived with the previous role mostly intact. //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 + G_found.transfer_key(new_xeno, FALSE) to_chat(new_xeno, "You have been fully respawned. Enjoy the game.") var/msg = "[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno." message_admins(msg) @@ -397,7 +397,7 @@ Traitors and the like can also be revived with the previous role mostly intact. var/mob/living/carbon/monkey/new_monkey = new SSjob.SendToLateJoin(new_monkey) 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 + G_found.transfer_key(new_monkey, FALSE) to_chat(new_monkey, "You have been fully respawned. Enjoy the game.") var/msg = "[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno." message_admins(msg) @@ -437,7 +437,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!new_character.mind.assigned_role) new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role. - new_character.key = G_found.key + G_found.transfer_key(new_character, FALSE) /* The code below functions with the assumption that the mob is already a traitor if they have a special role. diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index aa91af1dd8..8d7d5395a4 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -15,7 +15,7 @@ GLOBAL_LIST_EMPTY(antagonists) var/antag_memory = ""//These will be removed with antag datum var/antag_moodlet //typepath of moodlet that the mob will gain with their status var/can_hijack = HIJACK_NEUTRAL //If these antags are alone on shuttle hijack happens. - + //Antag panel properties var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED @@ -87,7 +87,7 @@ GLOBAL_LIST_EMPTY(antagonists) to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!") message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.") owner.current.ghostize(0) - owner.current.key = C.key + C.transfer_key(owner.current, FALSE) /datum/antagonist/proc/on_removal() remove_innate_effects() diff --git a/code/modules/antagonists/blob/blob/powers.dm b/code/modules/antagonists/blob/blob/powers.dm index 9e915ee0fa..b4affefb29 100644 --- a/code/modules/antagonists/blob/blob/powers.dm +++ b/code/modules/antagonists/blob/blob/powers.dm @@ -172,7 +172,7 @@ blobber.adjustHealth(blobber.maxHealth * 0.5) blob_mobs += blobber var/mob/dead/observer/C = pick(candidates) - blobber.key = C.key + C.transfer_key(blobber) SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg')) SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg')) to_chat(blobber, "You are a blobbernaut!") diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index 97d7f0c128..efcc8089ef 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -349,7 +349,7 @@ to_chat(L, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!") message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(L)]) to replace an inactive clock cultist.") L.ghostize(0) - L.key = C.key + C.transfer_key(L, FALSE) var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src)) animate(V, alpha = 0, transform = matrix()*2, time = 8) playsound(L, 'sound/magic/staff_healing.ogg', 50, 1) diff --git a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm index 30c84f5312..aac545c366 100644 --- a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm +++ b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm @@ -54,7 +54,7 @@ pre_spawn() visible_message(creation_message) var/mob/living/construct = new construct_type(get_turf(src)) - construct.key = user.key + user.transfer_key(construct, FALSE) post_spawn(construct) qdel(user) qdel(src) diff --git a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm index 05f3ca5917..bb17254931 100644 --- a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm +++ b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm @@ -64,7 +64,7 @@ message_admins("Admin [key_name_admin(user)] directly became the Eminence of the cult!") log_admin("Admin [key_name(user)] made themselves the Eminence.") var/mob/camera/eminence/eminence = new(get_turf(src)) - eminence.key = user.key + eminence.key = user.transfer_key(eminence, FALSE) hierophant_message("Ratvar has directly assigned the Eminence!") for(var/mob/M in servants_and_ghosts()) M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE) @@ -138,7 +138,7 @@ playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 50, FALSE) var/mob/camera/eminence/eminence = new(get_turf(src)) eminence_nominee = pick(candidates) - eminence.key = eminence_nominee.key + eminence_nominee.transfer_key(eminence) hierophant_message("A ghost has ascended into the Eminence!") for(var/mob/M in servants_and_ghosts()) M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE) diff --git a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm index 9341a7ee6a..21ece44212 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm @@ -45,7 +45,7 @@ return FALSE var/mob/living/simple_animal/drone/cogscarab/ratvar/R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src)) R.visible_message("[R] forms, and its eyes blink open, glowing bright red!") - R.key = O.key + O.transfer_key(R, FALSE) /obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A) var/turf/T = get_turf(A) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 3c11351660..4be56efd0d 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -595,7 +595,7 @@ structure_check() searches for nearby cultist structures required for the invoca to_chat(mob_to_revive.mind, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.") message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(mob_to_revive)]) to replace an AFK player.") mob_to_revive.ghostize(0) - mob_to_revive.key = C.key + C.transfer_key(mob_to_revive, FALSE) else fail_invoke() return @@ -890,7 +890,7 @@ structure_check() searches for nearby cultist structures required for the invoca visible_message("A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo":""]man.") to_chat(user, "Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely...") var/obj/structure/emergency_shield/invoker/N = new(T) - new_human.key = ghost_to_spawn.key + ghost_to_spawn.transfer_key(new_human, FALSE) SSticker.mode.add_cultist(new_human.mind, 0) to_chat(new_human, "You are a servant of the Geometer. You have been made semi-corporeal by the cult of Nar'Sie, and you are to serve them at all costs.") diff --git a/code/modules/antagonists/devil/true_devil/_true_devil.dm b/code/modules/antagonists/devil/true_devil/_true_devil.dm index 923a224b81..87925271ec 100644 --- a/code/modules/antagonists/devil/true_devil/_true_devil.dm +++ b/code/modules/antagonists/devil/true_devil/_true_devil.dm @@ -146,7 +146,7 @@ /mob/living/carbon/true_devil/attack_ghost(mob/dead/observer/user as mob) if(ascended || user.mind.soulOwner == src.mind) var/mob/living/simple_animal/imp/S = new(get_turf(loc)) - S.key = user.key + user.transfer_key(S, FALSE) S.mind.assigned_role = "Imp" S.mind.special_role = "Imp" var/datum/objective/newobjective = new diff --git a/code/modules/antagonists/disease/disease_event.dm b/code/modules/antagonists/disease/disease_event.dm index 7183ed5455..da58787fe9 100644 --- a/code/modules/antagonists/disease/disease_event.dm +++ b/code/modules/antagonists/disease/disease_event.dm @@ -18,7 +18,7 @@ var/mob/dead/observer/selected = pick_n_take(candidates) var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center()) - virus.key = selected.key + selected.transfer_key(virus, FALSE) INVOKE_ASYNC(virus, /mob/camera/disease/proc/pick_name) message_admins("[ADMIN_LOOKUPFLW(virus)] has been made into a sentient disease by an event.") log_game("[key_name(virus)] was spawned as a sentient disease by an event.") diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index 87794993a7..50b8851d3d 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -377,14 +377,15 @@ /obj/item/ectoplasm/revenant/proc/reform() if(QDELETED(src) || QDELETED(revenant) || inert) return - var/key_of_revenant + var/key_of_revenant = FALSE message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.") forceMove(drop_location()) //In case it's in a backpack or someone's hand revenant.forceMove(loc) if(old_key) for(var/mob/M in GLOB.dead_mob_list) if(M.client && M.client.key == old_key) //Only recreates the mob if the mob the client is in is dead - key_of_revenant = old_key + M.transfer_key(revenant.key, FALSE) + key_of_revenant = TRUE break if(!key_of_revenant) message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...") @@ -396,22 +397,21 @@ visible_message("[src] settles down and seems lifeless.") return var/mob/dead/observer/C = pick(candidates) - key_of_revenant = C.key - if(!key_of_revenant) + C.transfer_key(revenant.key, FALSE) + if(!revenant.key) qdel(revenant) message_admins("No ckey was found for the new revenant. Oh well!") inert = TRUE visible_message("[src] settles down and seems lifeless.") return - message_admins("[key_of_revenant] has been [old_key == key_of_revenant ? "re":""]made into a revenant by reforming ectoplasm.") - log_game("[key_of_revenant] was [old_key == key_of_revenant ? "re":""]made as a revenant by reforming ectoplasm.") + message_admins("[key_of_revenant] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.") + log_game("[key_of_revenant] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.") visible_message("[src] suddenly rises into the air before fading away.") revenant.essence = essence revenant.essence_regen_cap = essence revenant.death_reset() - revenant.key = key_of_revenant revenant = null qdel(src) diff --git a/code/modules/antagonists/revenant/revenant_spawn_event.dm b/code/modules/antagonists/revenant/revenant_spawn_event.dm index c9a892cd64..4ab2bcb30a 100644 --- a/code/modules/antagonists/revenant/revenant_spawn_event.dm +++ b/code/modules/antagonists/revenant/revenant_spawn_event.dm @@ -52,7 +52,7 @@ return MAP_ERROR var/mob/living/simple_animal/revenant/revvie = new(pick(spawn_locs)) - revvie.key = selected.key + selected.transfer_key(revvie, FALSE) message_admins("[ADMIN_LOOKUPFLW(revvie)] has been made into a revenant by an event.") log_game("[key_name(revvie)] was spawned as a revenant by an event.") spawned_mobs += revvie diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm index 40551ae2fc..3df561799e 100644 --- a/code/modules/antagonists/wizard/equipment/soulstone.dm +++ b/code/modules/antagonists/wizard/equipment/soulstone.dm @@ -218,7 +218,7 @@ newstruct.master = stoner var/datum/action/innate/seek_master/SM = new() SM.Grant(newstruct) - newstruct.key = target.key + target.transfer_key(newstruct) var/obj/screen/alert/bloodsense/BS if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode) SSticker.mode.add_cultist(newstruct.mind, 0) @@ -243,7 +243,7 @@ S.canmove = FALSE//Can't move out of the soul stone S.name = "Shade of [T.real_name]" S.real_name = "Shade of [T.real_name]" - S.key = T.key + T.transfer_key(S) S.language_holder = U.language_holder.copy(S) if(U) S.faction |= "[REF(U)]" //Add the master as a faction, allowing inter-mob cooperation diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm index 57d8420fa8..310699576c 100644 --- a/code/modules/awaymissions/mission_code/Academy.dm +++ b/code/modules/awaymissions/mission_code/Academy.dm @@ -133,7 +133,7 @@ var/mob/dead/observer/C = pick(candidates) message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Wizard Academy Defender") current_wizard.ghostize() // on the off chance braindead defender gets back in - current_wizard.key = C.key + C.transfer_key(current_wizard, FALSE) /obj/structure/academy_wizard_spawner/proc/summon_wizard() var/turf/T = src.loc @@ -274,7 +274,7 @@ if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant") - H.key = C.key + C.transfer_key(H, FALSE) var/obj/effect/proc_holder/spell/targeted/summonmob/S = new S.target_mob = H diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm index a76c75dd43..261d1fc774 100644 --- a/code/modules/events/holiday/xmas.dm +++ b/code/modules/events/holiday/xmas.dm @@ -77,7 +77,7 @@ if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) santa = new /mob/living/carbon/human(pick(GLOB.blobstart)) - santa.key = C.key + C.transfer_key(santa, FALSE) santa.equipOutfit(/datum/outfit/santa) santa.update_icons() diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index 55d8ce8b14..49ca828d35 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -48,7 +48,7 @@ spawned_animals++ - SA.key = SG.key + SG.transfer_key(SA, FALSE) SA.grant_all_languages(TRUE) diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm index 1c8ef95baa..550cce0217 100644 --- a/code/modules/events/wizard/imposter.dm +++ b/code/modules/events/wizard/imposter.dm @@ -23,7 +23,7 @@ I.name = I.dna.real_name I.updateappearance(mutcolor_update=1) I.domutcheck() - I.key = C.key + C.transfer_key(I, FALSE) var/datum/antagonist/wizard/master = M.has_antag_datum(/datum/antagonist/wizard) if(!master.wiz_team) master.create_wiz_team() diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 84be6438c0..bf768d8277 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -285,7 +285,7 @@ else to_chat(src, "Teleporting failed. Ahelp an admin please") stack_trace("There's no freaking observer landmark available on this map or you're making observers before the map is initialised") - observer.key = key + transfer_key(observer, FALSE) observer.client = client observer.set_ghost_appearance() if(observer.client && observer.client.prefs) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 55b8891534..41760cb71a 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -260,16 +260,16 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body Works together with spawning an observer, noted above. */ -/mob/proc/ghostize(can_reenter_corpse = 1) - if(key) - if(!cmptext(copytext(key,1,2),"@")) // Skip aghosts. - stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now - var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc. - SStgui.on_transfer(src, ghost) // Transfer NanoUIs. - ghost.can_reenter_corpse = can_reenter_corpse - ghost.can_reenter_round = (can_reenter_corpse && !suiciding) - ghost.key = key - return ghost +/mob/proc/ghostize(can_reenter_corpse = TRUE, send_the_signal = TRUE) + if(!key || cmptext(copytext(key,1,2),"@") || (send_the_signal && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse) & COMPONENT_BLOCK_GHOSTING)) + return //mob has no key, is an aghost or some component hijack. + stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now + var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc. + SStgui.on_transfer(src, ghost) // Transfer NanoUIs. + ghost.can_reenter_corpse = can_reenter_corpse + ghost.can_reenter_round = (can_reenter_corpse && !suiciding) + transfer_key(ghost, FALSE) + return ghost /* This is the proc mobs get to turn into a ghost. Forked from ghostize due to compatibility issues. @@ -348,7 +348,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return client.change_view(CONFIG_GET(string/default_view)) SStgui.on_transfer(src, mind.current) // Transfer NanoUIs. - mind.current.key = key + transfer_key(mind.current, FALSE) return 1 /mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE) @@ -631,7 +631,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp to_chat(src, "Someone has taken this body while you were choosing!") return 0 - target.key = key + transfer_key(target, FALSE) target.faction = list("neutral") return 1 diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 2f3ee10428..571b60317c 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -34,7 +34,7 @@ if(brainmob.mind) brainmob.mind.transfer_to(C) else - C.key = brainmob.key + brainmob.transfer_key(C) QDEL_NULL(brainmob) @@ -64,7 +64,7 @@ name = "[L.name]'s brain" if(brainmob) return - + if(!L.mind) return brainmob = new(src) diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index b4739f943e..2bdbf2515b 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -86,7 +86,7 @@ var/atom/xeno_loc = get_turf(owner) var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc) - new_xeno.key = ghost.key + ghost.transfer_key(new_xeno, FALSE) SEND_SOUND(new_xeno, sound('sound/voice/hiss5.ogg',0,0,0,100)) //To get the player's attention new_xeno.canmove = 0 //so we don't move during the bursting animation new_xeno.notransform = 1 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b6717f2932..0e35dd24d0 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -878,7 +878,7 @@ if(mind) mind.transfer_to(new_mob) else - new_mob.key = key + transfer_key(new_mob) for(var/para in hasparasites()) var/mob/living/simple_animal/hostile/guardian/G = para diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index b4524a54e6..3e72cbf875 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -86,7 +86,7 @@ var/datum/action/innate/deploy_last_shell/redeploy_action = new var/chnotify = 0 - + var/multicam_on = FALSE var/obj/screen/movable/pic_in_pic/ai/master_multicam var/list/multicam_screens = list() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 896d8674be..6ea1e96a06 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -192,7 +192,7 @@ /mob/proc/makePAI(delold) var/obj/item/paicard/card = new /obj/item/paicard(get_turf(src)) var/mob/living/silicon/pai/pai = new /mob/living/silicon/pai(card) - pai.key = key + transfer_key(pai) pai.name = name card.setPersonality(pai) if(delold) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index e9978d1e62..5fbd92c11a 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -916,7 +916,7 @@ Pass a positive integer as an argument to override a bot's default speed. if(mind && paicard.pai) mind.transfer_to(paicard.pai) else if(paicard.pai) - paicard.pai.key = key + transfer_key(paicard.pai) else ghostize(0) // The pAI card that just got ejected was dead. key = null diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index cf3742fcc5..71d4eddb27 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -159,7 +159,7 @@ if(mind) mind.transfer_to(R, 1) else - R.key = key + transfer_key(R) qdel(src) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index a655bdf231..3717d6538e 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -61,5 +61,5 @@ var/obj/item/new_hat = new hat_type(D) D.equip_to_slot_or_del(new_hat, SLOT_HEAD) D.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) - D.key = user.key + user.transfer_key(D, FALSE) qdel(src) diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 701e244f89..8a5d06392f 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -426,9 +426,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians to_chat(G, "Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.") to_chat(src, "Your [G.real_name] has been successfully reset.") message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])") - G.ghostize(0) + G.ghostize(FALSE, FALSE) G.setthemename(G.namedatum.theme) //give it a new color, to show it's a new person - G.key = C.key + C.transfer_key(G) G.reset = 1 switch(G.namedatum.theme) if("tech") diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index cfdf302d6b..bc644ba9ec 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -90,7 +90,7 @@ if(key) to_chat(user, "Someone else already took this spider.") return 1 - key = user.key + user.transfer_key(src, FALSE) return 1 //nursemaids - these create webs and eggs diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index c491b3e78d..d626af96f6 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -585,7 +585,7 @@ Difficulty: Very Hard var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No") if(be_helper == "Yes" && !QDELETED(src) && isobserver(user)) var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc)) - W.key = user.key + user.transfer_key(W, FALSE) /obj/machinery/anomalous_crystal/helpers/Topic(href, href_list) @@ -649,7 +649,7 @@ Difficulty: Very Hard L.heal_overall_damage(heal_power, heal_power) new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF") -/mob/living/simple_animal/hostile/lightgeist/ghostize() +/mob/living/simple_animal/hostile/lightgeist/ghostize(can_reenter_corpse = TRUE, send_the_signal = TRUE) . = ..() if(.) death() diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 4fdf431fa0..25b9314fb1 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -920,7 +920,7 @@ if(mind) mind.transfer_to(G) else - G.key = key + transfer_key(G) ..(gibbed) /mob/living/simple_animal/parrot/Poly/proc/Read_Memory() diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index 96e84a1754..48d9e65717 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -174,7 +174,7 @@ if(src.mind) src.mind.transfer_to(new_slime) else - new_slime.key = src.key + transfer_key(new_slime) qdel(src) else to_chat(src, "I am not ready to reproduce yet...") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 9d662b1673..113f8a54c8 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -436,7 +436,10 @@ // M.Login() //wat return - +/mob/proc/transfer_key(mob/new_mob, send_signal = TRUE) + if(send_signal) + SEND_SIGNAL(src, COMSIG_MOB_KEY_CHANGE, new_mob) + new_mob.key = key /mob/verb/cancel_camera() set name = "Cancel Camera View" diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 776bd04935..80a65f56c6 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -429,8 +429,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp var/mob/dead/observer/C = pick(candidates) to_chat(M, "Your mob has been taken over by a ghost!") message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(M)])") - M.ghostize(0) - M.key = C.key + M.ghostize(FALSE, FALSE) + C.transfer_key(M, FALSE) return TRUE else to_chat(M, "There were no ghosts willing to take control.") diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index 673548ff48..11ff21b28a 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -53,7 +53,7 @@ if(mind && isliving(M)) mind.transfer_to(M, 1) // second argument to force key move to new mob else - M.key = key + transfer_key(M) if(delete_old_mob) QDEL_IN(src, 1) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 5703e2190b..ef25aa3fd4 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -382,7 +382,7 @@ mind.active = FALSE mind.transfer_to(R) else if(transfer_after) - R.key = key + transfer_key(R) R.apply_pref_name("cyborg") @@ -425,7 +425,7 @@ new_xeno = new /mob/living/carbon/alien/humanoid/drone(loc) new_xeno.a_intent = INTENT_HARM - new_xeno.key = key + transfer_key(new_xeno) to_chat(new_xeno, "You are now an alien.") . = new_xeno @@ -457,7 +457,7 @@ else new_slime = new /mob/living/simple_animal/slime(loc) new_slime.a_intent = INTENT_HARM - new_slime.key = key + transfer_key(new_slime) to_chat(new_slime, "You are now a slime. Skreee!") . = new_slime @@ -465,7 +465,7 @@ /mob/proc/become_overmind(starting_points = 60) var/mob/camera/blob/B = new /mob/camera/blob(get_turf(src), starting_points) - B.key = key + transfer_key(B) . = B qdel(src) @@ -485,7 +485,7 @@ var/mob/living/simple_animal/pet/dog/corgi/new_corgi = new /mob/living/simple_animal/pet/dog/corgi (loc) new_corgi.a_intent = INTENT_HARM - new_corgi.key = key + transfer_key(new_corgi) to_chat(new_corgi, "You are now a Corgi. Yap Yap!") . = new_corgi @@ -512,7 +512,7 @@ if(mind) mind.transfer_to(new_gorilla) else - new_gorilla.key = key + transfer_key(new_gorilla) to_chat(new_gorilla, "You are now a gorilla. Ooga ooga!") . = new_gorilla qdel(src) @@ -542,7 +542,7 @@ var/mob/new_mob = new mobpath(src.loc) - new_mob.key = key + transfer_key(new_mob) new_mob.a_intent = INTENT_HARM @@ -561,7 +561,7 @@ var/mob/new_mob = new mobpath(src.loc) - new_mob.key = key + transfer_key(new_mob) new_mob.a_intent = INTENT_HARM to_chat(new_mob, "You feel more... animalistic") diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index ca12accbed..0af9cb9011 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -675,7 +675,7 @@ var/list/candidates = pollCandidatesForMob("Do you want to play as [SM.name]?", ROLE_SENTIENCE, null, ROLE_SENTIENCE, 50, SM, POLL_IGNORE_SENTIENCE_POTION) // see poll_ignore.dm if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) - SM.key = C.key + C.transfer_key(SM, FALSE) SM.mind.enslave_mind_to_creator(user) SM.sentience_act() to_chat(SM, "All at once it makes sense: you know what you are and who you are! Self awareness is yours!") diff --git a/code/modules/spells/spell_types/mind_transfer.dm b/code/modules/spells/spell_types/mind_transfer.dm index ffdd270994..021f57e873 100644 --- a/code/modules/spells/spell_types/mind_transfer.dm +++ b/code/modules/spells/spell_types/mind_transfer.dm @@ -70,12 +70,12 @@ Also, you never added distance checking after target is selected. I've went ahea var/mob/living/caster = user//The wizard/whomever doing the body transferring. //MIND TRANSFER BEGIN - var/mob/dead/observer/ghost = victim.ghostize(0) + var/mob/dead/observer/ghost = victim.ghostize(FALSE, FALSE) caster.mind.transfer_to(victim) ghost.mind.transfer_to(caster) if(ghost.key) - caster.key = ghost.key //have to transfer the key since the mind was not active + ghost.transfer_key(caster) //have to transfer the key since the mind was not active qdel(ghost) //MIND TRANSFER END diff --git a/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm b/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm index d2006cd12c..6b15065095 100644 --- a/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm +++ b/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm @@ -38,7 +38,7 @@ return to_chat(user, "You decide to wake up the banana spider...") awakening = 1 - + spawn(30) if(!QDELETED(src)) var/mob/living/simple_animal/banana_spider/S = new /mob/living/simple_animal/banana_spider(get_turf(src.loc)) @@ -98,7 +98,7 @@ if(be_spider == "No" || QDELETED(src) || !isobserver(user)) return sentience_act() - key = user.key + user.transfer_key(src, FALSE) density = TRUE /mob/living/simple_animal/banana_spider/ComponentInitialize() diff --git a/tgstation.dme b/tgstation.dme index 739176a457..e0acab0d6a 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -373,6 +373,7 @@ #include "code\datums\components\swarming.dm" #include "code\datums\components\thermite.dm" #include "code\datums\components\uplink.dm" +#include "code\datums\components\virtual_reality.dm" #include "code\datums\components\wearertargeting.dm" #include "code\datums\components\wet_floor.dm" #include "code\datums\components\decals\blood.dm" @@ -2798,7 +2799,7 @@ #include "code\modules\vending\toys.dm" #include "code\modules\vending\wardrobes.dm" #include "code\modules\vending\youtool.dm" -#include "code\modules\VR\vr_human.dm" +#include "code\modules\VR\vr_mob.dm" #include "code\modules\VR\vr_sleeper.dm" #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm"