Files
Bubberstation/code/modules/lost_crew/lost_crew_manager.dm
Alexis 21b4095dfd [MDB IGNORE] [IDB IGNORE] Upstream Sync - 04/17/2026 (#5453)
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>
2026-05-16 00:56:00 +02:00

174 lines
7.8 KiB
Plaintext

/// Manager for the lost crew bodies, for spawning and granting rewards
GLOBAL_DATUM_INIT(lost_crew_manager, /datum/lost_crew_manager, new)
/// Handles procs and timers for the lost crew bodies
/datum/lost_crew_manager
/// How many credits we reward the medical budget on a successful revive
var/credits_on_succes = /datum/supply_pack/medical/lost_crew::cost + CARGO_CRATE_VALUE * 2
/// How long after successful revival we check to see if theyre still alive, and give rewards
var/succes_check_time = 3 MINUTES
/// How much the revived crew start with on their cards
var/starting_funds = 200
/**
* Creates a body with random background and injuries
*
* Arguments:
* * revivable - Whether or not we can be revived to grand a ghost controle
* * container - Humans really dont like not having a loc, so please either give the container where you want to spawn it or a turf
* * forced_class - To force a specific damage class for some specific lore reason
* * recovered_items - Items recovered, such as some organs, dropped directly with the body
* * protected_items - Items that can only be recovered by the revived player
* * body_data - Debug data we can use to get a readout of what has been done
*/
/datum/lost_crew_manager/proc/create_lost_crew(revivable = TRUE, datum/corpse_damage_class/forced_class, list/recovered_items, list/protected_items, list/body_data = list())
var/mob/living/carbon/human/new_body = new()
new_body.death()
var/static/list/scenarios = list()
if(!scenarios.len)
var/list/types = subtypesof(/datum/corpse_damage_class)
for(var/datum/corpse_damage_class/scenario as anything in types)
scenarios[scenario] = initial(scenario.weight)
var/list/datum/callback/on_revive_and_player_occupancy = list()
var/datum/corpse_damage_class/scenario = forced_class || pick_weight(scenarios)
scenario = new scenario ()
new_body.living_flags |= STOP_OVERLAY_UPDATE_BODY_PARTS
scenario.apply_character(new_body, protected_items, recovered_items, on_revive_and_player_occupancy, body_data)
scenario.apply_injuries(new_body, recovered_items, on_revive_and_player_occupancy, body_data)
scenario.death_lore += "I should get a formalized assignment!"
new_body.living_flags &= ~STOP_OVERLAY_UPDATE_BODY_PARTS
new_body.update_body_parts()
. = new_body
// so bodies can also be used for runes, morgue, etc
if(!revivable)
return
//it's not necessary since we dont spawn the body until we open the bodybag, but why not be nice for once
new_body.reagents.add_reagent(/datum/reagent/toxin/formaldehyde, 5)
if(!recovered_items)
return
var/obj/item/paper/paper = new()
recovered_items += paper
if(!HAS_TRAIT(new_body, TRAIT_HUSK))
paper.name = "DO NOT REMOVE BRAIN"
paper.add_raw_text("Body swapping is not covered by medical insurance for unhusked bodies. Chemical brain explosives have been administered to enforce stipend.")
var/obj/item/organ/brain/boombrain = new_body.get_organ_by_type(/obj/item/organ/brain)
//I swear to fuck I will explode you. you're not clever
//everyone thought of this, but I am the fool for having any faith
//in people actually wanting to play the job in an interesting manner
//instead of just taking the easiest way out and learning nothing
//(no one abused it yet but I am already getting pinged by people who think they've broken the system when really I just expected better of them)
boombrain.AddElement(/datum/element/dangerous_organ_removal)
else
paper.name = "BODYSWAPPING PERMITTED"
paper.add_raw_text("Body swapping is covered by medical insurance in case of husking and a lack of skill in the practictioner.")
var/obj/item/organ/brain/hersens = new_body.get_organ_by_type(/obj/item/organ/brain)
hersens.AddComponent(
/datum/component/ghostrole_on_revive, \
/* refuse_revival_if_failed = */ TRUE, \
/*on_revival = */ CALLBACK(src, PROC_REF(on_successful_revive), hersens, scenario.death_lore, on_revive_and_player_occupancy) \
)
/// Set a timer for awarding succes and drop some awesome deathlore
/datum/lost_crew_manager/proc/on_successful_revive(obj/item/organ/brain/brain, list/death_lore, list/datum/callback/on_revive_and_player_occupancy)
var/mob/living/carbon/human/owner = brain.owner
owner.mind.add_antag_datum(/datum/antagonist/recovered_crew) //for tracking mostly
var/datum/bank_account/bank_account = new(owner.real_name, owner.mind.assigned_role, owner.dna.species.payday_modifier)
bank_account.adjust_money(starting_funds, "[starting_funds][MONEY_SYMBOL] given to [owner.name] as starting fund.")
owner.account_id = bank_account.account_id
bank_account.replaceable = FALSE
owner.add_mob_memory(/datum/memory/key/account, remembered_id = owner.account_id)
death_lore += "My account number was [owner.account_id]."
brain.RemoveElement(/datum/element/dangerous_organ_removal)
// Drop the sick ass death lore and give them an indicator of who they were and what they can do
for(var/i in 1 to death_lore.len)
addtimer(CALLBACK(src, GLOBAL_PROC_REF(to_chat), owner, span_boldnotice(death_lore[i])), 10 SECONDS + 2 SECONDS * i)
addtimer(CALLBACK(src, PROC_REF(award_succes), owner.mind, death_lore), succes_check_time)
// Run any callbacks our characters or damages may have placed for some effects for when the player is revived
for(var/datum/callback/callback as anything in on_revive_and_player_occupancy)
callback.Invoke()
/// Give medbay a happy announcement and put some money into their budget
/datum/lost_crew_manager/proc/award_succes(datum/mind/revived_mind, list/death_lore)
// I am incredibly disappointed in you
if(revived_mind.current.stat == DEAD)
aas_config_announce(/datum/aas_config_entry/medical_lost_crew_reward, list("PERSON" = revived_mind.name, "AWARD" = 0), null, list(RADIO_CHANNEL_MEDICAL), "Deceased")
return
// You are a credit to society
aas_config_announce(/datum/aas_config_entry/medical_lost_crew_reward, list("PERSON" = revived_mind.name, "AWARD" = credits_on_succes), null, list(RADIO_CHANNEL_MEDICAL), "Revived")
var/datum/bank_account/medical_budget = SSeconomy.get_dep_account(ACCOUNT_MED)
medical_budget.adjust_money(credits_on_succes)
/// A box for recovered items that can only be opened by the new crewmember
/obj/item/storage/lockbox/mind
name = "mind lockbox"
desc = "A locked box, openable only by one mind."
/// The mind needed to unlock the box
var/datum/mind/mind
/obj/item/storage/lockbox/mind/attack_hand(mob/user, list/modifiers)
if (!(src in user.held_items))
return ..()
if(atom_storage.locked && can_unlock(user, silent = TRUE))
toggle_locked(user)
return
return ..()
/obj/item/storage/lockbox/mind/attack_self(mob/user, modifiers)
if (atom_storage.locked && can_unlock(user))
toggle_locked(user)
return
return ..()
/obj/item/storage/lockbox/mind/can_unlock(mob/living/user, obj/item/card/id/id_card, silent = FALSE)
if (user.mind == mind)
return TRUE
if (!silent)
balloon_alert(user, "access denied!")
return FALSE
/obj/item/storage/lockbox/mind/toggle_locked(mob/living/user)
if(!atom_storage.locked)
return
atom_storage.set_locked(STORAGE_NOT_LOCKED)
balloon_alert(user, "unlocked")
/obj/item/storage/lockbox/mind/add_context(atom/source, list/context, obj/item/held_item, mob/user)
if(broken || user.mind != mind)
return NONE
context[SCREENTIP_CONTEXT_LMB] = "Use in-hand to unlock"
return CONTEXTUAL_SCREENTIP_SET
/datum/aas_config_entry/medical_lost_crew_reward
name = "Medical Alert: Lost Crew Revival Program"
announcement_lines_map = list(
"Deceased" = "Sensors indicate lifesigns of %PERSON have seized. Please inform their family of your failure.",
"Revived" = "Sensors indicate continued survival of %PERSON. Well done, %AWARDcr has been transferred to the medical budget."
)
vars_and_tooltips_map = list(
"PERSON" = "will be replaced with body's name",
"AWARD" = "with money that medical department receive, if any"
)
modifiable = FALSE