From 3ea6c1ddea3d5f59456afe31fecedff6f8bee893 Mon Sep 17 00:00:00 2001 From: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Date: Wed, 20 May 2026 12:15:17 -0400 Subject: [PATCH] Fixes tempbody taking aghosted bodies (#95996) ## About The Pull Request If you're an adminghosted body, you will no longer be sent back to your corpse afterwards. The Mind will still move over, but you wont immediately re-enter your body. Just as an example, an Admin is aghosted on Centcom after testing some stuff, plays a round of Mafia, then is suddenly back in their body in Centcom. Also fixes temp body not working for Mafia (due to the corpse locking) ## Why It's Good For The Game You're going to the THUNDERDOME. ## Changelog :cl: fix: Mafia players now get sent back to their bodies again post-game. admin: Admin players aren't forcefully put back into aghosted bodies after using a temporary body spawner. /:cl: --- code/datums/components/temporary_body.dm | 4 ++-- code/datums/mind/_mind.dm | 1 + .../antagonists/changeling/powers/absorb.dm | 4 ++-- code/modules/mob/dead/observer/observer.dm | 20 +++++++++++-------- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/code/datums/components/temporary_body.dm b/code/datums/components/temporary_body.dm index d069116cf0a..bf1dc618d48 100644 --- a/code/datums/components/temporary_body.dm +++ b/code/datums/components/temporary_body.dm @@ -79,7 +79,7 @@ SIGNAL_HANDLER var/mob/new_body = parent - var/mob/dead/observer/ghost = new_body.get_ghost() || new_body.ghostize() + var/mob/dead/observer/ghost = new_body.get_ghost() || new_body.ghostize(forced = TRUE) 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 @@ -90,7 +90,7 @@ 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) + if(old_body.stat != DEAD && !IS_FAKE_KEY(old_body.key)) ghost.reenter_corpse() qdel(src) // we're done here diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm index 04accafce44..f64b235e552 100644 --- a/code/datums/mind/_mind.dm +++ b/code/datums/mind/_mind.dm @@ -472,6 +472,7 @@ if(G.can_reenter_corpse || even_if_they_cant_reenter) return G break + return null /datum/mind/proc/grab_ghost(force) var/mob/dead/observer/G = get_ghost(even_if_they_cant_reenter = force) diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index 23dad3450c3..3e34de497fe 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -227,9 +227,9 @@ return ghostize(TRUE) -/mob/eye/imaginary_friend/hivemind/ghostize(can_reenter_corpse, admin_ghost) +/mob/eye/imaginary_friend/hivemind/ghostize(can_reenter_corpse, forced) . = ..() - if(admin_ghost) + if(forced) return alert_hivemind("You sense the presence of [real_name] disappear from the hivemind.") diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 6ed6d482964..cde8790ee63 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -254,18 +254,22 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) lum = max(read_color[3], 80) return rgb(read_color[1], sat, lum, space = COLORSPACE_HSL) -/* -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 = TRUE, admin_ghost = FALSE) +/** + * # Ghostize + * + * Creates a /mob/dead/observer and moves the player's key into it (among other handling for player->observer) + * Ignores things like adminghosts and corpselocked (ethereal) players. + * Args: + * can_reenter_corse: Whether the new Ghost will be able to click "Re-enter body", TRUE by default. + * forced: Whether we are forcing this player to be ghosted, ignoring things like corpselocking, FALSE by default. + */ +/mob/proc/ghostize(can_reenter_corpse = TRUE, forced = FALSE) if(!key) return if(IS_FAKE_KEY(key)) // Skip aghosts. return - if(HAS_TRAIT(src, TRAIT_CORPSELOCKED) && !admin_ghost) + if(HAS_TRAIT(src, TRAIT_CORPSELOCKED) && !forced) if(can_reenter_corpse) //If you can re-enter the corpse you can't leave when corpselocked return if(ishuman(usr)) //following code only applies to those capable of having an ethereal heart, ie humans @@ -293,7 +297,7 @@ Works together with spawning an observer, noted above. SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZED) return ghost -/mob/living/ghostize(can_reenter_corpse = TRUE) +/mob/living/ghostize(can_reenter_corpse = TRUE, forced = FALSE) . = ..() if(. && can_reenter_corpse) var/mob/dead/observer/ghost = .