mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-11 10:11:09 +00:00
## About The Pull Request Revival of https://github.com/tgstation/tgstation/pull/79691 A while back, I made this PR, but lost motivation after diving too deep into the code soup of can_breathe and related procs. Now, I have removed those parts, and have simplified that part of the code to the point I think it's ready for review. Many reviews from the previous PR have been addressed in this PR. <hr> <details> <summary>Details</summary> Asthma is a 4 point negative quirk that emulates real life asthma. It works by slowly decreasing the amount of pressure each breath you take receives, until your lungs completely seal, ensuring death if you dont get oxyloss meds/windpipe surgery. Inflammation (the tracker for intensity) increases whenever you breathe smoke, use a cigarette, metabolize histimine, or suffer an asthma attack. Asthma attacks have a low chance of happening every second, starting 10 minutes after you spawn and with a 20-30 grace period between attacks. They are "diseases" that cant be outright cured by albuterol, only put into remission. They increase inflammation at varying rates depending on their severity, with extreme asthma attacks being a immediate threat to your life while mild ones might not even cause inflammation. The response to these is always the same - use your inhaler before you start choking. Asthmatics start with a rescue inhaler, a low-capacity inhaler loaded with albuterol, which I will get to later. Albuterol is a new medicine thats a little tricky to make but still doable. It can be efficiently created with inverse convermol, or transmutated from salbutamol and convermol. The opposite is true, with albuterol able to be turned into salbutamol. Two canisters are available in chemvends. Upon use, it increases the virtual pressure of all breaths taken by 40%. This allows for you to breathe in lower pressure environments, as well as enhancing the effects of things like healium. It's OD causes your diaphram to spasm, causing sporadic losebreath and forced breathing. Inhalers are a fancy new reagent application apparatus that uses the INHALE reagent bitflag. Inhalers themselves are rather unremarkable, they are merely the method of using inhaler canisters (they also have a rotary display approximating the uses left in a canister - just like real life inhalers). Inhaler canisters are the reagent containers, and are generally low capacity. They can only be used in a inhaler, and contain aerosolized chemicals. Inhaler canisters and inhalers are unlocked from chemical synthesis, and are printable for cheap from a medlathe. In order to use a inhaler, one must uncover the mouth of a carbon and wait a few seconds (its faster if its a self-application) before a small amount of the reagents are delivered via the INHALE bitflag. This only works on things currently breathing - if theyre dead, have no lungs, or just, arent breathing - it will fail. This includes asthmatics with 100% inflammation. </details> <img width="181" height="74" alt="282863233-77a7cd6b-44d2-458e-9966-06d485df1521" src="https://github.com/user-attachments/assets/293b6659-0834-4e9a-b033-cc3b0cfde18e" /> <img width="1465" height="202" alt="282863346-2a247736-0c3a-43b0-a60b-7cff10ce4963" src="https://github.com/user-attachments/assets/5d9a13dc-b7b2-4de2-adda-8fbc8276e667" /> Sprites are not mine; they are from swanni and I can NOT sprite for the life of me ## Why It's Good For The Game 1. Asthma is just cool. One of my favorite features on bay was the fact lung damage required you to turn up the pressure on your O2 tank to survive, and this does precisely that. 2. Its always fun to add new ways to interact with atmos as a player that arent grossly broken, and I fail to see how a 40% increase of gas intake will really affect balance too badly. 3. Inhalers are badass. ## Changelog 🆑 add: Asthma quirk, based on IRL asthma add: Inhalers, a new reagent administering method that uses INHALE add: Albuterol, a new reagent that increases the amount of gas you inhale by 40% balance: Inverse convermol now forms once the reaction is done, not on metabolize /🆑 --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
263 lines
8.1 KiB
Plaintext
263 lines
8.1 KiB
Plaintext
/datum/disease/asthma_attack
|
|
form = "Bronchitis"
|
|
name = "Asthma attack"
|
|
desc = "Subject is undergoing a autoimmune response which threatens to close the esophagus and halt all respiration, leading to death. \
|
|
Minor asthma attacks may disappear on their own, but all are dangerous."
|
|
cure_text = "Albuterol/Surgical intervention"
|
|
cures = list(/datum/reagent/medicine/albuterol)
|
|
agent = "Inflammatory"
|
|
viable_mobtypes = list(/mob/living/carbon/human)
|
|
disease_flags = CURABLE
|
|
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
|
|
spread_text = "Inflammatory"
|
|
visibility_flags = HIDDEN_PANDEMIC
|
|
bypasses_immunity = TRUE
|
|
disease_flags = CURABLE|INCREMENTAL_CURE
|
|
required_organ = ORGAN_SLOT_LUNGS
|
|
infectable_biotypes = MOB_ROBOTIC|MOB_ORGANIC|MOB_MINERAL|MOB_UNDEAD
|
|
|
|
/// The world.time after which we will begin remission.
|
|
var/time_to_start_remission
|
|
|
|
/// The max time, after initial infection, it will take for us to begin remission
|
|
var/max_time_til_remission
|
|
/// The min time, after initial infection, it will take for us to begin remission
|
|
var/min_time_til_remission
|
|
|
|
/// Are we in remission, where we stop progressing and instead slowly degrade in intensity until we remove ourselves?
|
|
var/in_remission = FALSE
|
|
|
|
/// The current progress to stage demotion. Resets to 0 and reduces our stage by 1 when it exceeds [progress_needed_to_demote]. Only increases when in remission.
|
|
var/progress_to_stage_demotion = 0
|
|
/// The amount of demotion progress we receive per second while in remission.
|
|
var/progress_to_demotion_per_second = 1
|
|
/// Once [progress_to_stage_demotion] exceeds or meets this, we reduce our stage.
|
|
var/progress_needed_to_demote = 10
|
|
|
|
/// Do we alert ghosts when we are applied?
|
|
var/alert_ghosts = FALSE
|
|
|
|
/// A assoc list of (severity -> string), where string will be suffixed to our name in (suffix) format.
|
|
var/static/list/severity_to_suffix = list(
|
|
DISEASE_SEVERITY_MEDIUM = "Minor",
|
|
DISEASE_SEVERITY_HARMFUL = "Moderate",
|
|
DISEASE_SEVERITY_DANGEROUS = "Severe",
|
|
DISEASE_SEVERITY_BIOHAZARD = "EXTREME",
|
|
)
|
|
/// A assoc list of (stringified number -> number), where the key is the stage and the number is how much inflammation we will cause the asthmatic per second.
|
|
var/list/stage_to_inflammation_per_second
|
|
|
|
/datum/disease/asthma_attack/New()
|
|
. = ..()
|
|
|
|
suffix_name()
|
|
|
|
time_to_start_remission = world.time + rand(min_time_til_remission, max_time_til_remission)
|
|
|
|
/datum/disease/asthma_attack/try_infect(mob/living/infectee, make_copy)
|
|
if (!get_asthma_quirk())
|
|
return FALSE
|
|
if (HAS_TRAIT(infectee, TRAIT_NOBREATH))
|
|
return FALSE
|
|
|
|
return ..()
|
|
|
|
/// Adds our suffix via [severity_to_suffix] in the format of (suffix) to our name.
|
|
/datum/disease/asthma_attack/proc/suffix_name()
|
|
name += " ([severity_to_suffix[severity]])"
|
|
|
|
/// Returns the asthma quirk of our victim. As we can only be applied to asthmatics, this should never return null.
|
|
/datum/disease/asthma_attack/proc/get_asthma_quirk(mob/living/target = affected_mob)
|
|
RETURN_TYPE(/datum/quirk/item_quirk/asthma)
|
|
|
|
return (locate(/datum/quirk/item_quirk/asthma) in target.quirks)
|
|
|
|
/datum/disease/asthma_attack/stage_act(seconds_per_tick, times_fired)
|
|
. = ..()
|
|
if (!.)
|
|
return
|
|
|
|
if (HAS_TRAIT(affected_mob, TRAIT_NOBREATH))
|
|
cure()
|
|
return FALSE
|
|
|
|
var/datum/quirk/item_quirk/asthma/asthma_quirk = get_asthma_quirk()
|
|
var/inflammation = stage_to_inflammation_per_second["[stage]"]
|
|
if (inflammation)
|
|
asthma_quirk.adjust_inflammation(inflammation * seconds_per_tick)
|
|
|
|
if (!(world.time >= time_to_start_remission))
|
|
return
|
|
|
|
if (!in_remission)
|
|
in_remission = TRUE
|
|
stage_prob = 0
|
|
name += " (Remission)"
|
|
desc += " <i>The attack has entered remission. It will slowly decrease in intensity before vanishing.</i>"
|
|
progress_to_stage_demotion += (progress_to_demotion_per_second * seconds_per_tick)
|
|
if (progress_to_stage_demotion >= progress_needed_to_demote)
|
|
progress_to_stage_demotion = 0
|
|
update_stage(stage - 1)
|
|
|
|
// TYPES OF ASTHMA ATTACK
|
|
|
|
/datum/disease/asthma_attack/minor
|
|
severity = DISEASE_SEVERITY_MEDIUM
|
|
stage_prob = 4
|
|
|
|
max_time_til_remission = 120 SECONDS
|
|
min_time_til_remission = 80 SECONDS
|
|
max_stages = 3
|
|
|
|
cure_chance = 20
|
|
|
|
stage_to_inflammation_per_second = list(
|
|
"2" = 0.3,
|
|
"3" = 0.6,
|
|
)
|
|
|
|
/datum/disease/asthma_attack/minor/stage_act(seconds_per_tick, times_fired)
|
|
. = ..()
|
|
if (!.)
|
|
return FALSE
|
|
|
|
if (SPT_PROB(5, seconds_per_tick))
|
|
to_chat(affected_mob, span_warning(pick("Mucous runs down the back of your throat.", "You swallow excess mucus.")))
|
|
|
|
/datum/disease/asthma_attack/moderate
|
|
severity = DISEASE_SEVERITY_HARMFUL
|
|
stage_prob = 5
|
|
|
|
max_time_til_remission = 120 SECONDS
|
|
min_time_til_remission = 80 SECONDS
|
|
max_stages = 4
|
|
|
|
cure_chance = 20
|
|
|
|
stage_to_inflammation_per_second = list(
|
|
"2" = 1,
|
|
"3" = 2,
|
|
"4" = 4,
|
|
)
|
|
|
|
/datum/disease/asthma_attack/moderate/stage_act(seconds_per_tick, times_fired)
|
|
. = ..()
|
|
if (!.)
|
|
return FALSE
|
|
|
|
if (SPT_PROB(15, seconds_per_tick))
|
|
to_chat(affected_mob, span_warning(pick("Mucous runs down the back of your throat.", "You swallow excess mucus.")))
|
|
|
|
if (stage < 4 || !SPT_PROB(10, seconds_per_tick))
|
|
return
|
|
to_chat(affected_mob, span_warning("You briefly choke on the mucus piling in your throat!"))
|
|
affected_mob.losebreath++
|
|
|
|
|
|
/datum/disease/asthma_attack/severe
|
|
severity = DISEASE_SEVERITY_DANGEROUS
|
|
stage_prob = 6
|
|
|
|
max_time_til_remission = 80 SECONDS
|
|
min_time_til_remission = 60 SECONDS
|
|
max_stages = 5
|
|
|
|
cure_chance = 20
|
|
|
|
stage_to_inflammation_per_second = list(
|
|
"2" = 1,
|
|
"3" = 3,
|
|
"4" = 6,
|
|
"5" = 8,
|
|
)
|
|
|
|
visibility_flags = HIDDEN_SCANNER
|
|
alert_ghosts = TRUE
|
|
|
|
/datum/disease/asthma_attack/severe/stage_act(seconds_per_tick, times_fired)
|
|
. = ..()
|
|
if (!.)
|
|
return FALSE
|
|
|
|
if (stage > 1)
|
|
visibility_flags &= ~HIDDEN_SCANNER // revealed
|
|
|
|
if (SPT_PROB(15, seconds_per_tick))
|
|
to_chat(affected_mob, span_warning(pick("Mucous runs down the back of your throat.", "You swallow excess mucus.")))
|
|
else if (SPT_PROB(20, seconds_per_tick))
|
|
affected_mob.emote("cough")
|
|
|
|
if (stage < 4 || !SPT_PROB(15, seconds_per_tick))
|
|
return
|
|
to_chat(affected_mob, span_warning("You briefly choke on the mucus piling in your throat!"))
|
|
affected_mob.losebreath++
|
|
|
|
/datum/disease/asthma_attack/critical
|
|
severity = DISEASE_SEVERITY_BIOHAZARD
|
|
stage_prob = 85
|
|
|
|
max_time_til_remission = 60 SECONDS // this kills you extremely quickly, so its fair
|
|
min_time_til_remission = 40 SECONDS
|
|
max_stages = 6
|
|
|
|
cure_chance = 30
|
|
|
|
stage_to_inflammation_per_second = list(
|
|
"1" = 5,
|
|
"2" = 6,
|
|
"3" = 7,
|
|
"4" = 10,
|
|
"5" = 20,
|
|
"6" = 500, // youre fucked frankly
|
|
)
|
|
|
|
/// Have we warned our user of the fact they are at stage 5? If no, and are at or above stage five, we send a warning and set this to true.
|
|
var/warned_user = FALSE
|
|
/// Have we ever reached our max stage? If no, and we are at our max stage, we send a ominous message warning them of their imminent demise.
|
|
var/max_stage_reached = FALSE
|
|
|
|
/datum/disease/asthma_attack/critical/stage_act(seconds_per_tick, times_fired)
|
|
. = ..()
|
|
if (!.)
|
|
return FALSE
|
|
|
|
if (stage < 5)
|
|
if (SPT_PROB(75, seconds_per_tick))
|
|
to_chat(affected_mob, span_warning(pick("Mucous runs down the back of your throat.", "You swallow excess mucus.")))
|
|
|
|
var/wheeze_chance
|
|
if (!warned_user && stage >= 5)
|
|
to_chat(affected_mob, span_userdanger("You feel like your lungs are filling with fluid! It's getting incredibly hard to breathe!"))
|
|
warned_user = TRUE
|
|
|
|
switch (stage)
|
|
if (1)
|
|
wheeze_chance = 0
|
|
if (2)
|
|
wheeze_chance = 20
|
|
if (3)
|
|
wheeze_chance = 40
|
|
if (4)
|
|
wheeze_chance = 60
|
|
if (5)
|
|
wheeze_chance = 80
|
|
if (!in_remission)
|
|
stage_prob = 10 // slow it down significantly
|
|
if (6)
|
|
if (!max_stage_reached)
|
|
max_stage_reached = TRUE
|
|
to_chat(affected_mob, span_userdanger("You feel your windpipe squeeze shut!"))
|
|
wheeze_chance = 0
|
|
if (SPT_PROB(10, seconds_per_tick))
|
|
affected_mob.emote("gag")
|
|
var/datum/quirk/item_quirk/asthma/asthma_quirk = get_asthma_quirk()
|
|
asthma_quirk.adjust_inflammation(INFINITY)
|
|
|
|
if (SPT_PROB(wheeze_chance, seconds_per_tick))
|
|
affected_mob.emote("wheeze")
|
|
|
|
if (stage < 4 || !SPT_PROB(15, seconds_per_tick))
|
|
return
|
|
to_chat(affected_mob, span_warning("You briefly choke on the mucus piling in your throat!"))
|
|
affected_mob.losebreath++
|