mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-14 09:35:30 +01:00
21b4095dfd
Upstream 04/17/2026 fixes https://github.com/Bubberstation/Bubberstation/issues/5549 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com> Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com> Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com> Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com> Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com> Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com> Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com> Co-authored-by: loganuk <fakeemail123@aol.com> Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com> Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com> Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> Co-authored-by: Lucy <lucy@absolucy.moe> Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com> Co-authored-by: Isratosh <Isratosh@hotmail.com> Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com> Co-authored-by: Alexander V. <volas@ya.ru> Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com> Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: Iamgoofball <iamgoofball@gmail.com> Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com> Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com> Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com> Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com> Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com> Co-authored-by: Josh <josh.adam.powell@gmail.com> Co-authored-by: Josh Powell <josh.powell@softwire.com> Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com> Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com> Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
198 lines
7.0 KiB
Plaintext
198 lines
7.0 KiB
Plaintext
/// Proc ghosts to enter the body when it get's revived
|
|
/datum/component/ghostrole_on_revive
|
|
/// If revived and no ghosts, just die again?
|
|
var/refuse_revival_if_failed
|
|
/// Callback for when the mob is revived and has their body occupied by a ghost
|
|
var/datum/callback/on_successful_revive
|
|
/// The chance to twitch when orbiting the spawn
|
|
var/twitch_chance = 30
|
|
/// The title shown to ghosts when polled to enter the body
|
|
var/revive_title
|
|
|
|
// Text displayed in the spawners menu
|
|
var/spawn_text
|
|
var/you_are_text
|
|
var/flavor_text
|
|
var/important_text
|
|
|
|
/datum/component/ghostrole_on_revive/Initialize(
|
|
refuse_revival_if_failed = FALSE,
|
|
datum/callback/on_successful_revive,
|
|
revive_title = "a recovered crewmember",
|
|
spawn_text = "Recovered Crew",
|
|
you_are_text = "You are a long dead crewmember, but are soon to be revived to rejoin the crew!",
|
|
flavor_text = "Get a job and get back to work!",
|
|
important_text = "Do your best to help the station. You still roll for midround antagonists."
|
|
)
|
|
src.refuse_revival_if_failed = refuse_revival_if_failed
|
|
src.on_successful_revive = on_successful_revive
|
|
src.revive_title = revive_title
|
|
src.spawn_text = spawn_text
|
|
src.you_are_text = you_are_text
|
|
src.flavor_text = flavor_text
|
|
src.important_text = important_text
|
|
|
|
if(ismob(parent))
|
|
prepare_mob(parent)
|
|
return
|
|
|
|
if(!istype(parent, /obj/item/organ/brain))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
var/obj/item/organ/brain/brain_parent = parent
|
|
if(brain_parent.owner)
|
|
prepare_mob(brain_parent.owner)
|
|
else
|
|
prepare_brain(brain_parent)
|
|
|
|
/// Give the appropriate signals, and watch for organ removal
|
|
/datum/component/ghostrole_on_revive/proc/prepare_mob(mob/living/to_prepare)
|
|
RegisterSignal(to_prepare, COMSIG_LIVING_REVIVE, PROC_REF(on_revive))
|
|
RegisterSignal(to_prepare, COMSIG_MOB_REAGENT_TICK, PROC_REF(block_formaldehyde_metabolism))
|
|
if(istype(parent, /obj/item/organ/brain))
|
|
RegisterSignal(to_prepare, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_remove))
|
|
ADD_TRAIT(to_prepare, TRAIT_GHOSTROLE_ON_REVIVE, REF(src))
|
|
|
|
add_orbit_twitching(to_prepare)
|
|
to_prepare.med_hud_set_status()
|
|
|
|
/datum/component/ghostrole_on_revive/proc/unprepare_mob(mob/living/to_unprepare)
|
|
REMOVE_TRAIT(to_unprepare, TRAIT_GHOSTROLE_ON_REVIVE, REF(src))
|
|
UnregisterSignal(to_unprepare, list(
|
|
COMSIG_LIVING_REVIVE,
|
|
COMSIG_MOB_REAGENT_TICK,
|
|
COMSIG_CARBON_LOSE_ORGAN,
|
|
))
|
|
|
|
to_unprepare.med_hud_set_status()
|
|
remove_orbit_twitching(to_unprepare)
|
|
|
|
/datum/component/ghostrole_on_revive/proc/on_remove(mob/living/carbon/source, obj/item/organ/removed_brain)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!istype(removed_brain, /obj/item/organ/brain))
|
|
return
|
|
|
|
unprepare_mob(source)
|
|
|
|
// we might have some lingering blinking eyes
|
|
var/obj/item/bodypart/head/head = source.get_bodypart(BODY_ZONE_HEAD)
|
|
if(head)
|
|
var/soul_eyes = locate(/datum/bodypart_overlay/simple/soul_pending_eyes) in head.bodypart_overlays
|
|
if(soul_eyes)
|
|
head.remove_bodypart_overlay(soul_eyes)
|
|
|
|
prepare_brain(removed_brain)
|
|
|
|
/datum/component/ghostrole_on_revive/proc/prepare_brain(obj/item/organ/source)
|
|
ADD_TRAIT(source, TRAIT_GHOSTROLE_ON_REVIVE, REF(src))
|
|
RegisterSignal(source, COMSIG_ORGAN_IMPLANTED, PROC_REF(prepare_mob_from_brain))
|
|
RegisterSignal(source, COMSIG_ATOM_EXAMINE, PROC_REF(brain_examine))
|
|
UnregisterSignal(source, COMSIG_ORGAN_REMOVED)
|
|
|
|
/datum/component/ghostrole_on_revive/proc/unprepare_brain(obj/item/organ/source)
|
|
REMOVE_TRAIT(source, TRAIT_GHOSTROLE_ON_REVIVE, REF(src))
|
|
UnregisterSignal(source, COMSIG_ORGAN_IMPLANTED)
|
|
UnregisterSignal(source, COMSIG_ATOM_EXAMINE)
|
|
RegisterSignal(source, COMSIG_ORGAN_REMOVED, PROC_REF(prepare_brain))
|
|
source.owner?.med_hud_set_status()
|
|
|
|
/datum/component/ghostrole_on_revive/proc/prepare_mob_from_brain(obj/item/organ/brain/source, mob/living/owner)
|
|
SIGNAL_HANDLER
|
|
|
|
REMOVE_TRAIT(source, TRAIT_GHOSTROLE_ON_REVIVE, REF(src))
|
|
UnregisterSignal(source, COMSIG_ORGAN_IMPLANTED)
|
|
prepare_mob(owner)
|
|
|
|
/datum/component/ghostrole_on_revive/proc/brain_examine(datum/source, mob/user, list/examine_list)
|
|
SIGNAL_HANDLER
|
|
|
|
examine_list += span_info("Another soul may take [source.p_their()] place if put in a body...")
|
|
|
|
/datum/component/ghostrole_on_revive/proc/on_revive(mob/living/source)
|
|
SIGNAL_HANDLER
|
|
|
|
INVOKE_ASYNC(src, PROC_REF(poll_ghosts), source)
|
|
|
|
/datum/component/ghostrole_on_revive/proc/poll_ghosts(mob/living/reviving)
|
|
var/datum/bodypart_overlay/simple/soul_pending_eyes/soul_eyes
|
|
// adds soulful SOUL PENDING eyes to indicate what's happening to observers
|
|
var/obj/item/bodypart/head/head = reviving.get_bodypart(BODY_ZONE_HEAD)
|
|
if(head)
|
|
soul_eyes = new()
|
|
head.add_bodypart_overlay(soul_eyes)
|
|
|
|
var/list/jobbans = list(ROLE_RECOVERED_CREW)
|
|
if(reviving.mind)
|
|
jobbans |= reviving.mind.assigned_role.title
|
|
for(var/datum/antagonist/antag as anything in reviving.mind.antag_datums)
|
|
if(antag.jobban_flag)
|
|
jobbans |= antag.jobban_flag
|
|
if(antag.pref_flag)
|
|
jobbans |= antag.pref_flag
|
|
if(!(antag.antag_flags & ANTAG_FAKE))
|
|
jobbans |= ROLE_SYNDICATE
|
|
|
|
var/mob/dead/observer/chosen_one = SSpolling.poll_ghosts_for_target(
|
|
question = "Would you like to play as [revive_title]?",
|
|
check_jobban = jobbans,
|
|
poll_time = 15 SECONDS,
|
|
checked_target = reviving,
|
|
ignore_category = POLL_IGNORE_RECOVERED_CREW,
|
|
alert_pic = reviving,
|
|
role_name_text = revive_title,
|
|
)
|
|
|
|
if(head)
|
|
head.remove_bodypart_overlay(soul_eyes)
|
|
if(soul_eyes)
|
|
qdel(soul_eyes)
|
|
|
|
if(isobserver(chosen_one))
|
|
reviving.PossessByPlayer(chosen_one.ckey)
|
|
on_successful_revive?.Invoke(reviving)
|
|
qdel(src)
|
|
|
|
else if(refuse_revival_if_failed)
|
|
reviving.death()
|
|
reviving.visible_message(span_deadsay("[reviving]'s soul is struggling to return!"))
|
|
|
|
|
|
/datum/component/ghostrole_on_revive/proc/add_orbit_twitching(mob/living/parent_mob)
|
|
parent_mob.AddElement(/datum/element/orbit_twitcher, twitch_chance)
|
|
// Add it to the ghostrole spawner menu. Note that we can't directly spawn from it, but we can make it twitch to alert bystanders to defib it
|
|
LAZYADDASSOCLIST(GLOB.joinable_mobs, spawn_text, parent_mob)
|
|
RegisterSignal(parent_mob, COMSIG_LIVING_GHOSTROLE_INFO, PROC_REF(set_spawner_info))
|
|
|
|
/datum/component/ghostrole_on_revive/proc/set_spawner_info(datum/spawners_menu/menu, list/string_info)
|
|
SIGNAL_HANDLER
|
|
|
|
string_info["you_are_text"] = src.you_are_text
|
|
string_info["flavor_text"] = src.flavor_text
|
|
string_info["important_text"] = src.important_text
|
|
|
|
/datum/component/ghostrole_on_revive/proc/remove_orbit_twitching(mob/living/parent_mob)
|
|
parent_mob.RemoveElement(/datum/element/orbit_twitcher, twitch_chance)
|
|
LAZYREMOVEASSOC(GLOB.joinable_mobs, spawn_text, parent_mob)
|
|
UnregisterSignal(parent_mob, COMSIG_LIVING_GHOSTROLE_INFO)
|
|
|
|
// Block formaldehyde from being metabolized, Coroner QoL
|
|
/datum/component/ghostrole_on_revive/proc/block_formaldehyde_metabolism(mob/living/source, datum/reagent/chem)
|
|
SIGNAL_HANDLER
|
|
|
|
if(istype(chem, /datum/reagent/toxin/formaldehyde))
|
|
return COMSIG_MOB_STOP_REAGENT_TICK
|
|
|
|
/datum/component/ghostrole_on_revive/Destroy(force)
|
|
if(isliving(parent))
|
|
unprepare_mob(parent)
|
|
|
|
else if(istype(parent, /obj/item/organ/brain))
|
|
var/obj/item/organ/brain/brain = parent
|
|
if(brain.owner)
|
|
unprepare_mob(brain.owner)
|
|
else
|
|
unprepare_brain(brain)
|
|
|
|
return ..()
|