diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 6d9cb8e2255..74ad478db45 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1241,8 +1241,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// This item is currently under the control of telekinesis #define TRAIT_TELEKINESIS_CONTROLLED "telekinesis_controlled" -/// changelings with this trait can no longer talk over the hivemind -#define TRAIT_CHANGELING_HIVEMIND_MUTE "ling_mute" +/// mobs with this trait can talk over the hivemind +#define TRAIT_CHANGELING_HIVEMIND "ling_hivemind" /// This guy is a hulk! (Bulky and green, lacks tact) #define TRAIT_HULK "hulk" /// Isn't attacked harmfully by blob structures diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index da19eacc3cc..bbde567880c 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -226,7 +226,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CAN_THROW_ITEMS" = TRAIT_CAN_THROW_ITEMS, "TRAIT_CAN_USE_NUKE" = TRAIT_CAN_USE_NUKE, "TRAIT_CATLIKE_GRACE" = TRAIT_CATLIKE_GRACE, - "TRAIT_CHANGELING_HIVEMIND_MUTE" = TRAIT_CHANGELING_HIVEMIND_MUTE, + "TRAIT_CHANGELING_HIVEMIND" = TRAIT_CHANGELING_HIVEMIND, "TRAIT_CHASM_DESTROYED" = TRAIT_CHASM_DESTROYED, "TRAIT_CHEF_KISS" = TRAIT_CHEF_KISS, "TRAIT_CHUNKYFINGERS" = TRAIT_CHUNKYFINGERS, diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm index 3df17cb204e..b8691007d2c 100644 --- a/code/datums/brain_damage/imaginary_friend.dm +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -89,13 +89,17 @@ see_invisible = SEE_INVISIBLE_LIVING invisibility = INVISIBILITY_MAXIMUM has_emotes = TRUE - var/icon/human_image + var/icon/human_icon var/image/current_image var/hidden = FALSE var/move_delay = 0 var/mob/living/owner var/bubble_icon = "default" + /// Max distance we can be from our owner before we teleport to them + var/distance_allowance = 9 + /// If TRUE, we must keep line of sight with the owner + var/require_los = FALSE /// Whether our host and other imaginary friends can hear us only when nearby or practically anywhere. var/extended_message_range = TRUE @@ -145,7 +149,7 @@ gender = pick(MALE, FEMALE) real_name = generate_random_name_species_based(gender, FALSE, /datum/species/human) name = real_name - human_image = get_flat_human_icon(null, pick(SSjob.joinable_occupations)) + human_icon = get_flat_human_icon(null, pick(SSjob.joinable_occupations)) Show() /** @@ -176,11 +180,11 @@ appearance_job = SSjob.get_job(JOB_ASSISTANT) if(istype(appearance_job, /datum/job/ai)) - human_image = icon('icons/mob/silicon/ai.dmi', icon_state = resolve_ai_icon(appearance_from_prefs.read_preference(/datum/preference/choiced/ai_core_display)), dir = SOUTH) + human_icon = icon('icons/mob/silicon/ai.dmi', icon_state = resolve_ai_icon(appearance_from_prefs.read_preference(/datum/preference/choiced/ai_core_display)), dir = SOUTH) else if(istype(appearance_job, /datum/job/cyborg)) - human_image = icon('icons/mob/silicon/robots.dmi', icon_state = "robot") + human_icon = icon('icons/mob/silicon/robots.dmi', icon_state = "robot") else - human_image = get_flat_human_icon(null, appearance_job, appearance_from_prefs) + human_icon = get_flat_human_icon(null, appearance_job, appearance_from_prefs) Show() /// Returns all member clients of the imaginary_group @@ -200,7 +204,7 @@ remove_image_from_clients(current_image, friend_clients) //Generate image from the static icon and the current dir - current_image = image(human_image, src, , MOB_LAYER, dir=src.dir) + current_image = image(human_icon, src, , MOB_LAYER, dir=src.dir) current_image.override = TRUE current_image.name = name if(hidden) @@ -213,10 +217,8 @@ src.client.images |= current_image /mob/eye/imaginary_friend/Destroy() - if(owner?.client) - owner.client.images.Remove(human_image) - if(client) - client.images.Remove(human_image) + owner.client?.images -= current_image + client?.images -= current_image owner.imaginary_group -= src return ..() @@ -431,7 +433,7 @@ if(world.time < move_delay) return FALSE setDir(Dir) - if(get_dist(src, owner) > 9) + if(get_dist(src, owner) > distance_allowance || (require_los && !can_see(owner, src, distance_allowance))) recall() move_delay = world.time + 10 return FALSE @@ -541,7 +543,7 @@ /mob/eye/imaginary_friend/trapped/setup_friend() real_name = "[owner.real_name]?" name = real_name - human_image = icon('icons/mob/simple/lavaland/lavaland_monsters.dmi', icon_state = "curseblob") + human_icon = icon('icons/mob/simple/lavaland/lavaland_monsters.dmi', icon_state = "curseblob") #undef IMAGINARY_FRIEND_RANGE #undef IMAGINARY_FRIEND_SPEECH_RANGE diff --git a/code/datums/components/temporary_body.dm b/code/datums/components/temporary_body.dm index deadf90e6f9..d069116cf0a 100644 --- a/code/datums/components/temporary_body.dm +++ b/code/datums/components/temporary_body.dm @@ -1,63 +1,101 @@ /** - * ##temporary_body + * ## temporary_body * - * Used on living mobs when they are meant to be a 'temporary body' - * Holds a reference to an old mind & body, to put them back in + * Used on mobs when they are meant to be a 'temporary body' + * Holds a reference to an old mind, to put them back in * once the body this component is attached to, is being deleted. */ /datum/component/temporary_body ///The old mind we will be put back into when parent is being deleted. - var/datum/weakref/old_mind_ref + var/datum/mind/old_mind ///The old body we will be put back into when parent is being deleted. - var/datum/weakref/old_body_ref - /// Returns the mind if the parent dies by any means - var/delete_on_death = FALSE + var/mob/old_body + /// Returns the mind if the PARENT dies by any means + var/return_on_death = FALSE + /// Returns the mind if the OLD_BODY is revived + var/return_on_revive = FALSE -/datum/component/temporary_body/Initialize(datum/mind/old_mind, mob/living/old_body, delete_on_death = FALSE) - if(!isliving(parent)) +/datum/component/temporary_body/Initialize(datum/mind/old_mind, return_on_death = FALSE, return_on_revive = FALSE) + if(!ismob(parent)) return COMPONENT_INCOMPATIBLE - src.old_mind_ref = WEAKREF(old_mind) - if(istype(old_body)) - ADD_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src)) - src.old_body_ref = WEAKREF(old_body) - src.delete_on_death = delete_on_death + if(isnull(old_mind)) + stack_trace("Tried to create a temporary_body component without an old_mind!") + return COMPONENT_INCOMPATIBLE + + src.old_mind = old_mind + src.old_body = old_mind.current + src.return_on_death = return_on_death + src.return_on_revive = return_on_revive /datum/component/temporary_body/RegisterWithParent() - RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_parent_destroy)) + RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(return_mind)) + if(return_on_death) + RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(return_mind)) - if(delete_on_death) - RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_parent_destroy)) + RegisterSignal(old_mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transfer)) + + if(!isnull(old_body)) + register_body_signals() + +/datum/component/temporary_body/proc/register_body_signals() + ADD_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src)) + RegisterSignal(old_body, COMSIG_QDELETING, PROC_REF(on_body_destroy)) + if(return_on_revive) + RegisterSignal(old_body, COMSIG_LIVING_REVIVE, PROC_REF(return_mind)) /datum/component/temporary_body/UnregisterFromParent() UnregisterSignal(parent, COMSIG_QDELETING) + UnregisterSignal(parent, COMSIG_LIVING_DEATH) + UnregisterSignal(old_mind, COMSIG_MIND_TRANSFERRED) + if(!isnull(old_body)) + unregister_body_signals() + +/datum/component/temporary_body/proc/unregister_body_signals() + REMOVE_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src)) + UnregisterSignal(old_body, COMSIG_QDELETING) + UnregisterSignal(old_body, COMSIG_LIVING_REVIVE) + +/datum/component/temporary_body/Destroy() + . = ..() + old_mind = null + old_body = null + +/// Swap the target of old_body if old_mind is transferred somewhere while we're away +/datum/component/temporary_body/proc/on_mind_transfer(...) + SIGNAL_HANDLER + + if(!isnull(old_body)) + unregister_body_signals() + old_body = old_mind.current + if(!isnull(old_body)) + register_body_signals() /** * Sends the mind of the temporary body back into their previous host - * If the previous host is alive, we'll force them into the body. + * If the previous host is alive, we'll also force them into the body. * Otherwise we'll let them hang out as a ghost still. */ -/datum/component/temporary_body/proc/on_parent_destroy() +/datum/component/temporary_body/proc/return_mind(...) SIGNAL_HANDLER - var/datum/mind/old_mind = old_mind_ref?.resolve() - var/mob/living/old_body = old_body_ref?.resolve() || old_mind.current - if(!old_mind) + var/mob/new_body = parent + var/mob/dead/observer/ghost = new_body.get_ghost() || new_body.ghostize() + if(QDELETED(ghost)) + stack_trace("[src] belonging to [parent] was completely unable to find a ghost to put back into a body!") + qdel(src) // i guess this is useless now return - var/mob/living/living_parent = parent - var/mob/dead/observer/ghost = living_parent.ghostize() - if(!ghost) - ghost = living_parent.get_ghost() - if(!ghost) - CRASH("[src] belonging to [parent] was completely unable to find a ghost to put back into a body!") ghost.mind = old_mind - if(old_body?.stat != DEAD) - old_mind.transfer_to(old_body, force_key_move = TRUE) - else - old_mind.set_current(old_body) - if(old_body) - REMOVE_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src)) + if(old_mind.current != old_body) + stack_trace("Temporary body returning mind to old body, but the mind's current body doesn't match the old body!") + old_mind.set_current(old_body) + if(old_body.stat != DEAD) + ghost.reenter_corpse() - old_mind = null + qdel(src) // we're done here + +/// Body reference handling +/datum/component/temporary_body/proc/on_body_destroy(...) + SIGNAL_HANDLER old_body = null diff --git a/code/datums/saymode.dm b/code/datums/saymode.dm index 951c805f0af..9ca4568ac2b 100644 --- a/code/datums/saymode.dm +++ b/code/datums/saymode.dm @@ -35,20 +35,32 @@ mode = MODE_CHANGELING /datum/saymode/changeling/can_be_used_by(mob/living/user) - if(!user.mind) - return FALSE - if(user.mind.has_antag_datum(/datum/antagonist/fallen_changeling)) + if(user.mind?.has_antag_datum(/datum/antagonist/fallen_changeling)) + // special message for you to_chat(user, span_changeling("We're cut off from the hivemind! We've lost everything! EVERYTHING!!")) return FALSE - var/datum/antagonist/changeling/ling_sender = IS_CHANGELING(user) - if(!ling_sender) + if(!HAS_TRAIT(user, TRAIT_CHANGELING_HIVEMIND)) return FALSE - if(HAS_TRAIT(user, TRAIT_CHANGELING_HIVEMIND_MUTE)) + if(is_muted(user)) to_chat(user, span_warning("The poison in the air hinders our ability to interact with the hivemind.")) return FALSE return TRUE -/datum/saymode/changeling/handle_message/handle_message( +/datum/saymode/changeling/proc/is_muted(mob/living/user) + return user.reagents?.has_reagent(/datum/reagent/bz_metabolites, needs_metabolizing = TRUE) + +/datum/saymode/changeling/proc/get_lings() + . = list() + for(var/mob/ling_mob as anything in GLOB.mob_list) + //removes types that override the presence of being changeling (for example, borged lings still can't hivemind chat) + if(!HAS_TRAIT(ling_mob, TRAIT_CHANGELING_HIVEMIND) || issilicon(ling_mob) || isbrain(ling_mob) ) + continue + // can't receive messages on the hivemind right now + if(is_muted(ling_mob)) + continue + . += ling_mob + +/datum/saymode/changeling/handle_message( mob/living/user, message, list/spans = list(), @@ -56,20 +68,14 @@ list/message_mods = list() ) var/datum/antagonist/changeling/ling_sender = IS_CHANGELING(user) - user.log_talk(message, LOG_SAY, tag = "changeling [ling_sender.changelingID]") - var/msg = span_changeling("[ling_sender.changelingID]: [message]") + + var/id = ling_sender?.changelingID || user.real_name + + user.log_talk(message, LOG_SAY, tag = "[id]") + var/msg = span_changeling("[id]: [message]") // Send the message to our other changelings. - for(var/datum/antagonist/changeling/ling_receiver in GLOB.antagonists) - if(!ling_receiver.owner) - continue - var/mob/living/ling_mob = ling_receiver.owner.current - //removes types that override the presence of being changeling (for example, borged lings still can't hivemind chat) - if(!isliving(ling_mob) || issilicon(ling_mob) || isbrain(ling_mob)) - continue - // can't receive messages on the hivemind right now - if(HAS_TRAIT(ling_mob, TRAIT_CHANGELING_HIVEMIND_MUTE)) - continue + for(var/mob/ling_mob as anything in get_lings()) to_chat(ling_mob, msg, type = MESSAGE_TYPE_RADIO, avoid_highlighting = ling_mob == user) for(var/mob/dead/ghost as anything in GLOB.dead_mob_list) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 4374213117b..dd6b874786f 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -145,6 +145,7 @@ RegisterSignals(living_mob, list(COMSIG_MOB_MIDDLECLICKON, COMSIG_MOB_ALTCLICKON), PROC_REF(on_click_sting)) ADD_TRAIT(living_mob, TRAIT_FAKE_SOULLESS, CHANGELING_TRAIT) ADD_TRAIT(living_mob, TRAIT_BRAINLESS_CARBON, CHANGELING_TRAIT) + ADD_TRAIT(living_mob, TRAIT_CHANGELING_HIVEMIND, CHANGELING_TRAIT) if(living_mob.hud_used) var/datum/hud/hud_used = living_mob.hud_used @@ -205,6 +206,10 @@ UnregisterSignal(living_mob, list(COMSIG_MOB_LOGIN, COMSIG_LIVING_LIFE, COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_MOB_GET_STATUS_TAB_ITEMS, COMSIG_MOB_MIDDLECLICKON, COMSIG_MOB_ALTCLICKON)) REMOVE_TRAIT(living_mob, TRAIT_FAKE_SOULLESS, CHANGELING_TRAIT) REMOVE_TRAIT(living_mob, TRAIT_BRAINLESS_CARBON, CHANGELING_TRAIT) + REMOVE_TRAIT(living_mob, TRAIT_CHANGELING_HIVEMIND, CHANGELING_TRAIT) + + for(var/mob/eye/imaginary_friend/hivemind/hivemind_member in living_mob.imaginary_group) + qdel(hivemind_member) if(living_mob.hud_used) var/datum/hud/hud_used = living_mob.hud_used diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index d8ebc7c5998..23dad3450c3 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -40,7 +40,15 @@ SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "4")) owner.visible_message(span_danger("[owner] sucks the fluids from [target]!"), span_notice("We have absorbed [target].")) - to_chat(target, span_userdanger("You are absorbed by the changeling!")) + + if(target.client && target.mind) + var/mob/eye/imaginary_friend/hivemind/new_member = new(target.loc) + new_member.AddComponent(/datum/component/temporary_body, old_mind = target.mind, return_on_revive = TRUE) + new_member.real_name = target.real_name + new_member.gender = target.gender + new_member.human_icon = get_flat_human_icon(null, target.mind.assigned_role, target.client.prefs) + new_member.PossessByPlayer(target.ckey) + new_member.attach_to_owner(owner) var/true_absorbtion = (!isnull(target.client) || !isnull(target.mind) || !isnull(target.last_mind)) if (!true_absorbtion) @@ -160,3 +168,128 @@ is_absorbing = FALSE return FALSE return TRUE + +/mob/eye/imaginary_friend/hivemind + name = "hivemind member" + desc = "A drifting thought in the ocean that is the changeling hivemind." + distance_allowance = 5 + require_los = TRUE + hidden = TRUE + /// Don't spam the hivemind on login logout + var/alerted = FALSE + +/mob/eye/imaginary_friend/hivemind/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_CHANGELING_HIVEMIND, INNATE_TRAIT) + var/datum/action/innate/exit_hivemind/exit_action = new(src) + exit_action.Grant(src) + +/mob/eye/imaginary_friend/hivemind/Login() + . = ..() + client.eye = owner || src + +/mob/eye/imaginary_friend/hivemind/greet() + + var/greet_message = "" + greet_message += separator_hr(span_danger(span_slightly_larger("You are absorbed by the changeling!"))) + greet_message += "You are now a part of the changeling hivemind, and can communicate with them freely by speaking. \ + Your knowledge may be useful to them..." + greet_message += "
You may also choose to exit the hivemind \ + if you prefer to observe instead." + greet_message += "
Either way, if your body or brain is revived, you will be returned to it as normal." + + to_chat(src, boxed_message(span_changeling(greet_message))) + + if(!alerted) + alerted = TRUE + alert_hivemind("You sense the presence of [real_name] in the hivemind.") + +/mob/eye/imaginary_friend/hivemind/send_speech(message, range, obj/source, bubble_type, list/spans, datum/language/message_language, list/message_mods = list(), forced) + // chops any message mods, even though they won't actually do anything + message = get_message_mods(message, message_mods) + // forces message through the changeling saymode + var/datum/saymode/changeling/saymode = SSradio.saymodes[/datum/saymode/changeling::key] + saymode.handle_message(src, message, spans, message_language, message_mods) + +/mob/eye/imaginary_friend/hivemind/Topic(href, list/href_list) + . = ..() + if(href_list["exit_hivemind"] && !QDELETED(src)) + exit_hivemind() + +/mob/eye/imaginary_friend/hivemind/verb/exit_hivemind() + set category = "IC" + set name = "Exit Hivemind" + set desc = "Leave the hivemind behind and enter the land of the dead." + + var/response = tgui_alert(src, "Are you sure you want to exit the hivemind? \ + You can't re-enter it, though you can still be revived.", "Confirm Exit", list("Exit", "Stay")) + if(response != "Exit" || QDELETED(src)) + return + ghostize(TRUE) + +/mob/eye/imaginary_friend/hivemind/ghostize(can_reenter_corpse, admin_ghost) + . = ..() + if(admin_ghost) + return + + alert_hivemind("You sense the presence of [real_name] disappear from the hivemind.") + if(!QDELING(src)) + qdel(src) + +/mob/eye/imaginary_friend/hivemind/proc/alert_hivemind(message) + var/datum/saymode/changeling/saymode = SSradio.saymodes[/datum/saymode/changeling::key] + for(var/mob/ling_mob as anything in saymode.get_lings() - src) + to_chat(ling_mob, span_changeling("[message]")) + +/mob/eye/imaginary_friend/hivemind/attach_to_owner(mob/living/imaginary_friend_owner) + . = ..() + client?.eye = owner + if(locate(/datum/action/changeling/eject_from_hivemind) in owner.actions) + return + var/datum/action/changeling/eject_from_hivemind/ejector = new(owner) + ejector.Grant(owner) + +/mob/eye/imaginary_friend/hivemind/Destroy() + for(var/mob/eye/imaginary_friend/hivemind/other_member in owner.imaginary_group - src) + return ..() + + var/datum/action/changeling/eject_from_hivemind/ejector = locate() in owner.actions + qdel(ejector) + return ..() + +/datum/action/innate/exit_hivemind + name = "Exit Hivemind" + desc = "Exit the changeling hivemind permanently. You may still be revived later." + // button_icon_state = "exit_hivemind" + +/datum/action/innate/exit_hivemind/Activate() + var/mob/eye/imaginary_friend/hivemind/member = owner + member.exit_hivemind() + +/// Allow the changeling to nuke people griffing them +/datum/action/changeling/eject_from_hivemind + name = "Eject from Hivemind" + desc = "Eject an unwanted member from the hivemind." + // button_icon_state = "eject_hivemind" + chemical_cost = 0 + dna_cost = CHANGELING_POWER_UNOBTAINABLE + +/datum/action/changeling/eject_from_hivemind/sting_action(mob/living/user) + var/list/freeloaders = list() + for(var/mob/eye/imaginary_friend/hivemind/freeloader in user.imaginary_group) + freeloaders[freeloader.real_name] = freeloader + + if(!length(freeloaders)) + stack_trace("Tried to eject from hivemind with no hivemind members!") + qdel(src) + return FALSE + + var/chosen = tgui_input_list(owner, "Choose a member to eject from the hivemind.", "Eject Hivemind Member", freeloaders) + var/mob/eye/imaginary_friend/hivemind/freeloader = freeloaders[chosen] + if(QDELETED(freeloader) || QDELETED(src)) + return FALSE + + to_chat(freeloader, span_userdanger("You have been ejected from the changeling hivemind!")) + qdel(freeloader) + ..() + return TRUE diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index be3a5b92d2d..ab217c39956 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -1016,7 +1016,6 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0) new_human.AddComponent( \ /datum/component/temporary_body, \ old_mind = ghost_to_spawn.mind, \ - old_body = ghost_to_spawn.mind.current, \ ) new_human.PossessByPlayer(ghost_to_spawn.key) var/datum/antagonist/cult/created_cultist = new_human.mind?.add_antag_datum(/datum/antagonist/cult) diff --git a/code/modules/basketball/controller.dm b/code/modules/basketball/controller.dm index de32aa766bb..078624e775e 100644 --- a/code/modules/basketball/controller.dm +++ b/code/modules/basketball/controller.dm @@ -196,7 +196,6 @@ GLOBAL_VAR(basketball_game) baller.AddComponent( \ /datum/component/temporary_body, \ old_mind = player_client.mob.mind, \ - old_body = player_client.mob.mind.current, \ ) baller.PossessByPlayer(player_key) minigame_basketball_mobs |= baller diff --git a/code/modules/bitrunning/server/threats.dm b/code/modules/bitrunning/server/threats.dm index c8d21785960..34583aa358d 100644 --- a/code/modules/bitrunning/server/threats.dm +++ b/code/modules/bitrunning/server/threats.dm @@ -114,7 +114,7 @@ new_mob.PossessByPlayer(ghost.key) if(ghost_mind) - new_mob.AddComponent(/datum/component/temporary_body, ghost_mind, ghost_mind.current, TRUE) + new_mob.AddComponent(/datum/component/temporary_body, ghost_mind, return_on_death = TRUE) var/datum/mind/antag_mind = new_mob.mind antag_mind.add_antag_datum(chosen_role) diff --git a/code/modules/bitrunning/spawners.dm b/code/modules/bitrunning/spawners.dm index a7f742d9d42..36fd7ba2b2c 100644 --- a/code/modules/bitrunning/spawners.dm +++ b/code/modules/bitrunning/spawners.dm @@ -12,7 +12,7 @@ /obj/effect/mob_spawn/ghost_role/human/virtual_domain/special(mob/living/spawned_mob, mob/mob_possessor, apply_prefs) var/datum/mind/ghost_mind = mob_possessor.mind if(ghost_mind) // Preserves any previous bodies before making the switch - spawned_mob.AddComponent(/datum/component/temporary_body, ghost_mind, ghost_mind.current, TRUE) + spawned_mob.AddComponent(/datum/component/temporary_body, ghost_mind, return_on_death = TRUE) ..() diff --git a/code/modules/capture_the_flag/ctf_game.dm b/code/modules/capture_the_flag/ctf_game.dm index 56636f28a73..b10513eca27 100644 --- a/code/modules/capture_the_flag/ctf_game.dm +++ b/code/modules/capture_the_flag/ctf_game.dm @@ -157,7 +157,6 @@ player_mob.AddComponent( \ /datum/component/temporary_body, \ old_mind = new_member_mind, \ - old_body = new_member_mind.current, \ ) player_mob.ckey = new_team_member.ckey diff --git a/code/modules/deathmatch/deathmatch_lobby.dm b/code/modules/deathmatch/deathmatch_lobby.dm index af4408ef58c..3bb15bd8105 100644 --- a/code/modules/deathmatch/deathmatch_lobby.dm +++ b/code/modules/deathmatch/deathmatch_lobby.dm @@ -145,7 +145,6 @@ new_player.AddComponent( \ /datum/component/temporary_body, \ old_mind = observer.mind, \ - old_body = observer.mind.current, \ ) new_player.equipOutfit(loadout) // Loadout new_player.PossessByPlayer(ckey) diff --git a/code/modules/mafia/roles/roles.dm b/code/modules/mafia/roles/roles.dm index 5f22153a03e..a26c6f40d38 100644 --- a/code/modules/mafia/roles/roles.dm +++ b/code/modules/mafia/roles/roles.dm @@ -130,7 +130,6 @@ body.AddComponent( \ /datum/component/temporary_body, \ old_mind = player.mob.mind, \ - old_body = player.mob.mind.current, \ ) body.PossessByPlayer(player.key) ADD_TRAIT(body, TRAIT_CORPSELOCKED, MAFIA_TRAIT) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 5157eee170c..fe3effbc61f 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2641,7 +2641,6 @@ taste_description = "acrid cinnamon" metabolization_rate = 0.2 * REAGENTS_METABOLISM chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE - metabolized_traits = list(TRAIT_CHANGELING_HIVEMIND_MUTE) /datum/reagent/bz_metabolites/on_mob_life(mob/living/carbon/target, seconds_per_tick, metabolization_ratio) . = ..()