From 11f8eff319ef3252e6681bbb5440a1d167acfc41 Mon Sep 17 00:00:00 2001 From: smellie Date: Sat, 13 Apr 2024 17:14:51 +0100 Subject: [PATCH] Cryonics Additions + IV Bag Stuff (#18415) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Summary: This PR fleshes out cryonics, both inside a cryotube and outside of a cryotube, and gives a pharmacist a lot more to do during those high energy rounds as they will be required to prepare and oversee any cryonic mixes. Lots of ways you can go about doing with the biggest reward being brain regeneration that bypasses oxygenation requirements, at the cost of significant downsides if done improperly. This generally empowers pharmacists and physicians and offers non-surgical treatment alternatives, though often incurs a penalty or takes a little longer than surgical treatment, so it doesn't make surgeons redundant. This list'll be exhaustive so medical players aren't left in the dark and can just refer to this while a wiki update is worked on, instead of digging through code. **Changes to Stasis/Cryotubes:** - Stasis at temperates between 120K and 200K has been reduced to between 5 and 10, as opposed to 10 and 20. This means chemicals still have a good chance of metabolising if you set a cryotube to above ~140K. Cryotubes will still achieve good stasis if you cool below 120K - upgraded stockparts from the workshop/R&D will help with this. - (Bugfix) IPCs will not longer be knocked unconscious if they enter an active cryotube. **Misc. Reagent Additions/Tweaks:** - Bicaridine now only requires 30u in the blood to begin attempting to repair arterial bleeds, as opposed to 50u. - Adds a Blood Thinning chemical effect. This prevents Coagzolug's blood clotting effect from working and works in the opposite way - increasing how much blood you lose per blood loss tick. Fluvectionem and Synaptizine apply Blood Thinning at a strength of 25, translating to 25% faster blood loss. **Cryonic Chemicals:** - Cryoxadone and Clonexadone both overdose at 5u. **_This is not a problem when using a cryotube due to how cryotubes administer reagents._** Overdosing either results in genetic damage and severe eye damage. - Cryoxadone and Clonexadone's organ healing capabilities have been significantly nerfed. The organ healing is still noticable and useful for pharmacist/surgeonless rounds; they cannot heal the brain though. - Cryosurfactant has been renamed to Cryosilicate, mimicking Pyrosilicate - the recipe now uses silicate instead of surfactant. - Cryosilicate and Pyrosilicate now have an effect when used in the body: cryosilicate will supercool a patient; pyrosilicate will chemically incinerate someone. Leporazine will inhibit these functions. - Bicaridine will repair arterial bleeds when used in cryogenic conditions. - Kelotane will repair disfigurement when used in cryogenic conditions. - Peridaxon 2x effective in cryogenic conditions. Peridaxon can denecrotise livers and kidneys in extracool cryogenic conditions - it cannot denecrotise other organs. Using peridaxon in cryogenic conditions will result in benign tumour growth (see below). - Red Nightshade can repair bone breaks in cryogenic conditions. It will still put a patient into a berserk state. - Cataleptinol - see below. **Cataleptinol Rework:** Cataleptinol has been reworked from the ground up and is where pharmacist's will be able to shine by making fancy cryotube beaker mixers or cryonic mixtures for use in IV stands. - The new recipe is 2 parts Alkysine, 0.5 parts Phoron, 1 part Clonexadone and a 5u Cryosilicate catalyst. This translates to: 120u Alkysine + 60u Clonexadone + 30u Phoron w/ 5u Cryosilicate = 60u (1 bottle) of Cataleptinol - expensive and lots of tricky precursors, leaves enough left over to make a 2nd bottle without having to remake all of the precursors. - **In cryogenic conditions**, Cataleptinol will restore 7.5% brain activity per metabolisation tick. This _bypasses the 85% oxygenation requirement_, at the cost of hallucinations, blood thinning and liver damage. The trade is roughly 40% brain activity (assuming nothing is causing brain damage) for total liver failure. - **Outside of cryogenic conditions**, Cataleptinol becomes a lot less reliable and a lot more dangerous to use, with only a 75% chance of restoring 2% brain activity per metabolisation tick. It will still bypass oxygenation requirements, making it useful during _**severe emergencies**_, at the cost of inducing painshock in addition to the above hallucinations, blood thinning and liver damage. The trade is roughly 25% brain activity (assuming nothing is causing brain damage) for total liver failure. - Cataleptinol _**overdoses at 3u**_ and has a fast metabolisation of 0.6u/tick - this makes it hard to dose without using an IV drip. If you overdose Cataleptinol by using another method of administration, then the patient's liver will crash, brain regeneration undone and the patient will have severe seizures resulting in more pain. Using Cataleptinol outside of cryogenic conditions **is high risk and only potentially high reward**, but it could buy a couple more minutes. **Tumours:** - Adds Benign Tumours. Benign tumours simply drain nutrition and cause frequent pain; they do not spread or affect nearby organs. - Adds Malignant Tumours. Malignant tumours will begin by draining nutrition then effecting symptoms based on the tumour's location (chest tumours -> coughing, gasping, chest pain; brain tumours -> disorientation, memory loss; abdominal -> vomiting, abdominal pain; anywhere else -> lethargy). In the later stages, malignant tumours will begin to damage the organs they are close to, then will eventually enter the circulatory _~~and lymphatic~~_ system and spawn more malignant tumours in other parts of the body. - Peridaxon will result in benign tumour growth when overdosed or used in cryogenic conditions. - Genetic damage will result in malignant tumour growth. - Ryetalyn is the anti-tumour drug and will put both benign and malignant tumours into recession. You can also surgically intervene and excise tumours as you would k'ois mycosis or fluke parasites. - You cannot have more than 3 of any tumour - things won't get too out of hand. **IV Bag Stuff:** - Adds 2 labels for IV bags: Cryonics Mixture, denoted by a CR; Other Mixture, denoted by an M. - Renames `blood packs` to `IV bags` and changes their formatting. What was `blood pack O+` will now appear as `IV bag - O+ Blood`; `blood pack Saline Plus` -> `IV bag - Saline Plus`. **Misc.:** - Only 20 genetic degradation on a limb is required to deform it instead of 30. This should make it slightly more common, as 30 is a large number to reach when this number is calculated per limb. - Seizures can be given variable strengths. - (Bugfix) Coolant tanks no longer just set a room's temperature to 0K when destroyed. The amount it cools a room scales with the amount of coolant still in the tank but cannot go below 173K/-100°C. - Cryocells now have stockparts and can be upgraded/deconstructed. --- aurorastation.dme | 1 + code/__DEFINES/chemistry.dm | 2 + code/__DEFINES/mobs.dm | 2 + code/datums/uplink/medical.dm | 1 + code/game/machinery/body_scanner.dm | 22 ++- code/game/machinery/cryo.dm | 36 ++++- .../circuitboards/machinery/miscboards.dm | 1 + .../items/weapons/storage/pill_bottle.dm | 5 + .../modules/cargo/random_stock/t2_uncommon.dm | 2 +- code/modules/materials/material_recipes.dm | 2 +- .../mob/living/carbon/human/human_helpers.dm | 8 +- code/modules/mob/living/living.dm | 10 +- code/modules/organs/internal/eyes.dm | 1 + code/modules/organs/internal/heart.dm | 4 +- code/modules/organs/organ_external.dm | 8 +- .../organs/subtypes/parasite/_parasite.dm | 22 +++ .../organs/subtypes/parasite/tumours.dm | 141 ++++++++++++++++ .../Chemistry-Reagents-Drugs.dm | 2 +- .../Chemistry-Reagents-Medicine.dm | 151 +++++++++++++----- .../Chemistry-Reagents-Other.dm | 18 ++- .../Chemistry-Reagents-Toxins.dm | 30 ++++ code/modules/reagents/Chemistry-Recipes.dm | 49 +++--- .../reagents/reagent_containers/blood_pack.dm | 22 +-- .../reagent_containers/glass/bottle.dm | 12 +- .../reagents/reagent_containers/hypospray.dm | 2 +- .../reagents/reagent_containers/pill.dm | 5 + code/modules/reagents/reagent_dispenser.dm | 7 +- html/changelogs/kermit-cryonicsadditions.yml | 21 +++ icons/obj/bloodpack.dmi | Bin 1682 -> 1880 bytes icons/obj/organs/organs.dmi | Bin 11293 -> 11550 bytes maps/sccv_horizon/sccv_horizon-2_deck_2.dmm | 1 + 31 files changed, 466 insertions(+), 122 deletions(-) create mode 100644 code/modules/organs/subtypes/parasite/tumours.dm create mode 100644 html/changelogs/kermit-cryonicsadditions.yml diff --git a/aurorastation.dme b/aurorastation.dme index 4621ac0b28b..dd8ed153cb0 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -2918,6 +2918,7 @@ #include "code\modules\organs\subtypes\parasite\black_kois.dm" #include "code\modules\organs\subtypes\parasite\heart_fluke.dm" #include "code\modules\organs\subtypes\parasite\kois.dm" +#include "code\modules\organs\subtypes\parasite\tumours.dm" #include "code\modules\organs\subtypes\parasite\worms.dm" #include "code\modules\organs\subtypes\parasite\zombie.dm" #include "code\modules\overmap\_defines.dm" diff --git a/code/__DEFINES/chemistry.dm b/code/__DEFINES/chemistry.dm index 6ad8dcec322..c448ae48e15 100644 --- a/code/__DEFINES/chemistry.dm +++ b/code/__DEFINES/chemistry.dm @@ -71,6 +71,7 @@ #define CE_STRAIGHTWALK "straightwalk" // prevents the confused walking chem side effect #define CE_NOSTUTTER "nostutter" // helps alleviate stuttering #define CE_HAUNTED "haunted" // Spectrocybin's ghost vision +#define CE_BLOODTHIN "bloodthin" // Makes you bleed out quicker // Apply healing effects #define CE_ANTIBIOTIC "antibiotic" // Thetamycin @@ -92,6 +93,7 @@ #define CE_HEPATOTOXIC "livertoxic" // Liver damage #define CE_CARDIOTOXIC "hearttoxic" // Heart damage #define CE_PNEUMOTOXIC "lungtoxic" // Lung damage +#define CE_OCULOTOXIC "eyetoxic" // Eye damage //Alcohol #define INTOX_BUZZED 0.01 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index b1fe0de45d1..5f76e7f0ad8 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -146,6 +146,8 @@ #define BP_ZOMBIE_PARASITE "black tumour" #define BP_WORM_HEART "heart fluke" #define BP_WORM_NERVE "nerve fluke" +#define BP_TUMOUR_NONSPREADING "benign tumour" +#define BP_TUMOUR_SPREADING "malignant tumour" //Augment organs #define BP_AUG_TIMEPIECE "integrated timepiece" diff --git a/code/datums/uplink/medical.dm b/code/datums/uplink/medical.dm index 964c16e768f..1ba670a0335 100644 --- a/code/datums/uplink/medical.dm +++ b/code/datums/uplink/medical.dm @@ -19,6 +19,7 @@ bluecrystal_cost = 3 item_limit = 2 path = /obj/item/reagent_containers/hypospray/autoinjector/sanasomnum + desc = "A special autoinjector loaded with outlawed biomechanical stem cells, inducing a regenerative coma so intense it can heal almost any injury - even broken bones, organ and brain damage, severed tendons, and arterial damage. Upon use one will fall immediately into a state of unconsciousness lasting roughly three to five minutes, arising completely healed. The only thing it cannot fix are organs that have been destroyed outright, or so much cumulative damage that death is all but certain. In the short-term, it will save your life; in the long term, the cancerous tumours immediately onset by the drug will invariable cause death down the line." /datum/uplink_item/item/medical/combathypo name = "Combat Hypospray" diff --git a/code/game/machinery/body_scanner.dm b/code/game/machinery/body_scanner.dm index 6d565dc649b..93debc50e3a 100644 --- a/code/game/machinery/body_scanner.dm +++ b/code/game/machinery/body_scanner.dm @@ -479,19 +479,6 @@ return data /obj/machinery/body_scanconsole/proc/get_internal_damage(var/obj/item/organ/internal/I) - if(istype(I, /obj/item/organ/internal/parasite)) - var/obj/item/organ/internal/parasite/P = I - switch(P.stage) - if(1) - return "Tiny" - if(2) - return "Small" - if(3) - return "Large" - if(4) - return "Massive" - else - return "Present" if(I.is_broken()) return "Severe" if(I.is_bruised()) @@ -614,6 +601,15 @@ if(A.inflamed) wounds += "inflamed" + if(istype(O, /obj/item/organ/internal/parasite)) + var/obj/item/organ/internal/parasite/P = O + if(P.stage) + wounds += "stage [P.stage]" + if(P.parent_organ) + wounds += "growing in [P.parent_organ]" + if(istype(P, /obj/item/organ/internal/parasite/malignant_tumour) && P.stage >= 4) + wounds += "metastasising" + if(O.status & ORGAN_DEAD) if(O.can_recover()) wounds += "necrotic; debridable" diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 481cfa800e2..dcf02797c63 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -31,6 +31,15 @@ clicksound = 'sound/machines/buttonbeep.ogg' clickvol = 30 + component_types = list( + /obj/item/circuitboard/cryotube, + /obj/item/stock_parts/scanning_module, + /obj/item/stock_parts/scanning_module, + /obj/item/stock_parts/manipulator, + /obj/item/stock_parts/console_screen, + /obj/item/reagent_containers/glass/beaker/large + ) + var/temperature_archived var/mob/living/carbon/human/occupant = null var/obj/item/reagent_containers/glass/beaker = null @@ -40,8 +49,8 @@ var/temperature_warning_threshold = 170 var/temperature_danger_threshold = T0C - var/fast_stasis_mult = 0.8 - var/slow_stasis_mult = 1.25 + var/fast_stasis_mult = 0.6 + var/slow_stasis_mult = 1.7 var/current_stasis_mult = 1 var/global/list/screen_overlays @@ -343,6 +352,10 @@ return occupant.bodytemperature += 2*(air_contents.temperature - occupant.bodytemperature)*current_heat_capacity/(current_heat_capacity + air_contents.heat_capacity()) occupant.bodytemperature = max(occupant.bodytemperature, air_contents.temperature) // this is so ugly i'm sorry for doing it i'll fix it later i promise + + if(occupant.isSynthetic()) + return + occupant.set_stat(UNCONSCIOUS) var/has_cryo = REAGENT_VOLUME(occupant.reagents, /singleton/reagent/cryoxadone) >= 1 var/has_clonexa = REAGENT_VOLUME(occupant.reagents, /singleton/reagent/clonexadone) >= 1 @@ -451,14 +464,29 @@ if(loc) return loc.return_air() +/obj/machinery/atmospherics/unary/cryo_cell/attackby(obj/item/attacking_item, mob/user) + if(default_deconstruction_screwdriver(user, attacking_item)) + return TRUE + if(default_deconstruction_crowbar(user, attacking_item)) + return TRUE + if(default_part_replacement(user, attacking_item)) + return TRUE + + return ..() + +/obj/machinery/atmospherics/unary/cryo_cell/get_examine_text(mob/user, distance, is_adjacent, infix, suffix) + . = ..() + if(panel_open) + . += "The maintenance hatch is open." + /obj/machinery/atmospherics/unary/cryo_cell/RefreshParts() ..() var/man_rating = 0 for(var/obj/item/stock_parts/P in component_parts) if(ismanipulator(P)) man_rating += P.rating - fast_stasis_mult = max(1 - (man_rating * 0.06), 0.66) - slow_stasis_mult = min(1 + (man_rating * 0.06), 1.5) + fast_stasis_mult = max(0.6/man_rating, 0.2) + slow_stasis_mult = min(1.6+(man_rating/10), 2) /datum/data/function/proc/reset() return diff --git a/code/game/objects/items/weapons/circuitboards/machinery/miscboards.dm b/code/game/objects/items/weapons/circuitboards/machinery/miscboards.dm index b80fe75a2b8..0e706ddfdae 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/miscboards.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/miscboards.dm @@ -43,6 +43,7 @@ req_components = list( "/obj/item/stock_parts/scanning_module" = 2, "/obj/item/stock_parts/console_screen" = 1, + "/obj/item/stock_parts/manipulator" = 1, "/obj/item/reagent_containers/glass/beaker/large" = 1) diff --git a/code/game/objects/items/weapons/storage/pill_bottle.dm b/code/game/objects/items/weapons/storage/pill_bottle.dm index fb1ce121d53..cbff2b3156d 100644 --- a/code/game/objects/items/weapons/storage/pill_bottle.dm +++ b/code/game/objects/items/weapons/storage/pill_bottle.dm @@ -175,3 +175,8 @@ name = "bottle of 5u Steramycin pills" desc = "Contains prophylactic antibiotic pills." starts_with = list(/obj/item/reagent_containers/pill/steramycin = 3) + +/obj/item/storage/pill_bottle/ryetalyn + name = "bottle of 10u Ryetalyn pills" + desc = "Contains pills used to treat genetic and immune diseases." + starts_with = list(/obj/item/reagent_containers/pill/ryetalyn = 4) diff --git a/code/modules/cargo/random_stock/t2_uncommon.dm b/code/modules/cargo/random_stock/t2_uncommon.dm index 3781f46b4e3..abd2da67fc7 100644 --- a/code/modules/cargo/random_stock/t2_uncommon.dm +++ b/code/modules/cargo/random_stock/t2_uncommon.dm @@ -92,7 +92,7 @@ STOCK_ITEM_UNCOMMON(chempack, 5) var/list/exclusion = list(/singleton/reagent/drink, /singleton/reagent, /singleton/reagent/adminordrazine, /singleton/reagent/polysomnine/beer2, /singleton/reagent/azoth, /singleton/reagent/elixir,\ /singleton/reagent/liquid_fire, /singleton/reagent/philosopher_stone, /singleton/reagent/toxin/undead, /singleton/reagent/love_potion, /singleton/reagent/shapesand, /singleton/reagent/usolve,\ /singleton/reagent/sglue, /singleton/reagent/black_matter, /singleton/reagent/drugs/cocaine, /singleton/reagent/drugs/raskara_dust, /singleton/reagent/drugs/heroin, /singleton/reagent/drugs/joy, /singleton/reagent/toxin/stimm, /singleton/reagent/drugs/impedrezene, /singleton/reagent/bottle_lightning, /singleton/reagent/toxin/hylemnomil, /singleton/reagent/toxin/nanites, /singleton/reagent/nitroglycerin, - /singleton/reagent/aslimetoxin, /singleton/reagent/sanasomnum, /singleton/reagent/rezadone, /singleton/reagent/kois/black, /singleton/reagent/toxin/carpotoxin) + /singleton/reagent/aslimetoxin, /singleton/reagent/sanasomnum, /singleton/reagent/rezadone, /singleton/reagent/kois/black, /singleton/reagent/toxin/carpotoxin, /singleton/reagent/toxin/malignant_tumour_cells) chems -= exclusion for (var/i in 1 to rand(2, 4)) var/obj/item/reagent_containers/chem_disp_cartridge/C = new /obj/item/reagent_containers/chem_disp_cartridge(L) diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index c6efca70b07..d3b564ffb78 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -139,7 +139,7 @@ new /datum/stack_recipe("plastic rack", /obj/structure/table/rack, BUILD_AMT, time = 5, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("plastic crate", /obj/structure/closet/crate/plastic, BUILD_AMT, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("plastic bag", /obj/item/storage/bag/plasticbag, 3, on_floor = 1), - new /datum/stack_recipe("blood pack", /obj/item/reagent_containers/blood/empty, 4, on_floor = 0), + new /datum/stack_recipe("IV bag", /obj/item/reagent_containers/blood/empty, 4, on_floor = 0), new /datum/stack_recipe("reagent dispenser cartridge (large)", /obj/item/reagent_containers/chem_disp_cartridge, 5, on_floor=0), // 500u new /datum/stack_recipe("reagent dispenser cartridge (med)", /obj/item/reagent_containers/chem_disp_cartridge/medium, 3, on_floor=0), // 250u new /datum/stack_recipe("reagent dispenser cartridge (small)", /obj/item/reagent_containers/chem_disp_cartridge/small, 1, on_floor=0), // 100u diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index c1fd25a65c2..2123025a992 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -254,13 +254,13 @@ return 0 else if(bodytemperature > species.cold_level_2) . = 5 * (1 - (bodytemperature - species.cold_level_2) / (species.cold_level_1 - species.cold_level_2)) - . = max(2, .) + . = max(2, .) //stasis factor range: 2 to 5 after rounding else if(bodytemperature > species.cold_level_3) - . = 20 * (1 - (bodytemperature - species.cold_level_3) / (species.cold_level_2 - species.cold_level_3)) - . = max(5, .) + . = 11 * (1 - (bodytemperature - species.cold_level_3) / (species.cold_level_2 - species.cold_level_3)) + . = max(5, .) //stasis factor range: 5 to 10 after rounding. we still want chemicals to metabolise at a bearable speed for those sick pharmacy beaker mixes. else . = 80 * (1 - bodytemperature / species.cold_level_3) - . = max(20, .) + . = max(20, .) //stasis factor range: 20 to 80 after rounding. irl cryonics ''achieves full stasis'' in bodies at 80K. if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) var/obj/machinery/atmospherics/unary/cryo_cell/cryo = loc if(cryo.current_stasis_mult) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 6fc8d60b4fa..e05662fe2da 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -970,12 +970,12 @@ default behaviour is: /mob/living/proc/get_resist_power() return 1 -/mob/living/proc/seizure() +/mob/living/proc/seizure(var/severity_multiplier = 1) if(!paralysis && stat == CONSCIOUS) - visible_message("\The [src] starts having a seizure!") - Paralyse(rand(16,24)) - make_jittery(rand(150,200)) - adjustHalLoss(rand(50,60)) + visible_message(SPAN_HIGHDANGER("\The [src] starts having a seizure!")) + Paralyse(24*severity_multiplier) + make_jittery(200*severity_multiplier) + adjustHalLoss(60*severity_multiplier) /mob/living/proc/InStasis() return FALSE diff --git a/code/modules/organs/internal/eyes.dm b/code/modules/organs/internal/eyes.dm index 834edfac4d1..ab6c4d06710 100644 --- a/code/modules/organs/internal/eyes.dm +++ b/code/modules/organs/internal/eyes.dm @@ -8,6 +8,7 @@ max_damage = 45 min_broken_damage = 25 relative_size = 5 + toxin_type = CE_OCULOTOXIC var/list/eye_colour = list(0,0,0) var/singular_name = "eye" diff --git a/code/modules/organs/internal/heart.dm b/code/modules/organs/internal/heart.dm index a6160998ea4..0daf7b31c12 100644 --- a/code/modules/organs/internal/heart.dm +++ b/code/modules/organs/internal/heart.dm @@ -148,8 +148,10 @@ if(temp.status & ORGAN_ARTERY_CUT) var/bleed_amount = FLOOR((owner.vessel.total_volume / (temp.applied_pressure || !open_wound ? 450 : 250)) * temp.arterial_bleed_severity, 1) if(bleed_amount) - if(CE_BLOODCLOT in owner.chem_effects) + if((CE_BLOODCLOT in owner.chem_effects) && !(owner.chem_effects[CE_BLOODTHIN])) bleed_amount *= 0.8 // won't do much, but it'll help + if(CE_BLOODTHIN in owner.chem_effects) + bleed_amount *= 1+(owner.chem_effects[CE_BLOODTHIN]/100) if(open_wound) blood_max += bleed_amount do_spray += "[temp.name]" diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 4137e3cc7e3..ef06e9deec1 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -1526,7 +1526,7 @@ Note that amputating the affected organ does in fact remove the infection from t if(genetic_degradation <= 30) if(status & ORGAN_MUTATED) unmutate() - to_chat(src, "Your [name] is shaped normally again.") + to_chat(src, SPAN_NOTICE("Your [name] is shaped normally again.")) return -(genetic_degradation - last_gene_dam) /obj/item/organ/external/proc/add_genetic_damage(var/amount) @@ -1536,10 +1536,12 @@ Note that amputating the affected organ does in fact remove the infection from t return var/last_gene_dam = genetic_degradation genetic_degradation = min(100,max(0,genetic_degradation + amount)) - if(genetic_degradation > 30) + if(genetic_degradation > 10) + owner.infest_with_parasite(owner, BP_TUMOUR_SPREADING, src) + if(genetic_degradation > 20) if(!(status & ORGAN_MUTATED) && prob(genetic_degradation)) mutate() - to_chat(owner, "Something is not right with your [name]...") + to_chat(owner, SPAN_NOTICE("Something is not right with your [name]...")) return (genetic_degradation - last_gene_dam) // Pain/halloss diff --git a/code/modules/organs/subtypes/parasite/_parasite.dm b/code/modules/organs/subtypes/parasite/_parasite.dm index 763893bbc28..c99da42443f 100644 --- a/code/modules/organs/subtypes/parasite/_parasite.dm +++ b/code/modules/organs/subtypes/parasite/_parasite.dm @@ -73,3 +73,25 @@ /obj/item/organ/internal/parasite/proc/stage_effect() return + +/mob/living/carbon/human/proc/infest_with_parasite(var/mob/living/carbon/victim, var/parasite_type, var/obj/item/organ/external/organ_to_infest, var/chance_to_infest = 100, var/parasite_limit = 3) + if(ishuman(victim)) + var/mob/living/carbon/human/H = victim + if(BP_IS_ROBOTIC(organ_to_infest)) + return + var/i = 0 + for(var/obj/item/organ/internal/O in H.internal_organs) //dont want there to be a silly amount of parasites + if(istype(O, /obj/item/organ/internal/parasite)) + i++ + if((i < parasite_limit) && prob(chance_to_infest)) + switch(parasite_type) //such a shitty way to do this but i couldnt get a better alternative to work in a sane amount of time :/ + if("malignant tumour") + var/obj/item/organ/internal/parasite/malignant_tumour/P = new() + P.parent_organ = organ_to_infest + P.replaced(H, organ_to_infest) + P.generate_name() + if("benign tumour") + var/obj/item/organ/internal/parasite/benign_tumour/P = new() + P.parent_organ = organ_to_infest + P.replaced(H, organ_to_infest) + P.generate_name() diff --git a/code/modules/organs/subtypes/parasite/tumours.dm b/code/modules/organs/subtypes/parasite/tumours.dm new file mode 100644 index 00000000000..df5cd9012dd --- /dev/null +++ b/code/modules/organs/subtypes/parasite/tumours.dm @@ -0,0 +1,141 @@ +/obj/item/organ/internal/parasite/benign_tumour + name = "benign tumour" + icon = 'icons/obj/organs/organs.dmi' + icon_state = "tumour" + dead_icon = "tumour" + + organ_tag = BP_TUMOUR_NONSPREADING + parent_organ = BP_CHEST + subtle = 1 + + drug_resistance = 1 + + max_stage = 3 + stage_interval = 300 //~5 minutes minutes/stage + + origin_tech = list(TECH_BIO = 2) + +/obj/item/organ/internal/parasite/benign_tumour/proc/generate_name() + if(parent_organ) + switch(parent_organ) + if(BP_CHEST) + name = "benign chest lipoma" + if(BP_GROIN) + name = "benign abdominal tumour" + if(BP_HEAD) + name = "benign skull cavity tumour" + if(BP_L_ARM) + name = "benign lipoma (left arm)" + if(BP_R_ARM) + name = "benign lipoma (right arm)" + if(BP_L_HAND) + name = "benign chondroma (left hand)" + if(BP_R_HAND) + name = "benign chondroma (right hand)" + if(BP_L_LEG) + name = "benign lipoma (left leg)" + if(BP_R_LEG) + name = "benign lipoma (right leg)" + if(BP_L_FOOT) + name = "benign plantar fibroma (left foot)" + if(BP_R_FOOT) + name = "benign plantar fibroma (right foot)" + +/obj/item/organ/internal/parasite/benign_tumour/process() + ..() + if (!owner) + return + if(REAGENT_VOLUME(owner.reagents, /singleton/reagent/ryetalyn)) //10u will treat most tumours, 20u will nuke fully developed tumours + recession = 20 + if(prob(2)) + owner.adjustNutritionLoss(5) + if(stage >= 2) //after ~5 minutes + if(prob(5)) + owner.adjustHalLoss(10*stage) + +/obj/item/organ/internal/parasite/malignant_tumour + name = "malignant tumour" + icon = 'icons/obj/organs/organs.dmi' + icon_state = "tumour" + dead_icon = "tumour" + + organ_tag = BP_TUMOUR_SPREADING + parent_organ = BP_CHEST + subtle = 1 + + drug_resistance = 1 + + max_stage = 4 + stage_interval = 300 //~5 minutes minutes/stage + + origin_tech = list(TECH_BIO = 3) + + egg = /singleton/reagent/toxin/malignant_tumour_cells + +/obj/item/organ/internal/parasite/malignant_tumour/proc/generate_name() + if(parent_organ) + switch(parent_organ) + if(BP_CHEST) + name = "malignant chest wall sarcoma" + if(BP_GROIN) + name = "gastric cancer" + if(BP_HEAD) + name = "malignant brain tumour" + if(BP_L_ARM) + name = "malignant melanoma (left arm)" + if(BP_R_ARM) + name = "malignant melanoma (right arm)" + if(BP_L_HAND) + name = "malignant chondrosarcoma (left hand)" + if(BP_R_HAND) + name = "malignant chondrosarcoma (right hand)" + if(BP_L_LEG) + name = "malignant melanoma (left leg)" + if(BP_R_LEG) + name = "malignant melanoma (right leg)" + if(BP_L_FOOT) + name = "malignant chondrosarcoma (left foot)" + if(BP_R_FOOT) + name = "malignant chondrosarcoma (right foot)" + +/obj/item/organ/internal/parasite/malignant_tumour/process() + ..() + if (!owner) + return + if(REAGENT_VOLUME(owner.reagents, /singleton/reagent/ryetalyn)) //10u will treat most tumours, 20u will nuke fully developed tumours + recession = 20 + if(prob(5)) + owner.adjustNutritionLoss(5) + if(prob(5)) + owner.adjustHalLoss((10*stage)/2) + if(stage >= 2) //after ~5 minutes + switch(parent_organ) + if(BP_HEAD) + owner.confused = min(owner.confused + (stage*2), 10) + owner.slurring = min(owner.slurring + (stage*2), 50) + if(prob(5)) + to_chat(owner, SPAN_WARNING(pick("You struggle to remember the last several moments.", "You smell something funny.", "You taste something funny.", "You can't figure out how to properly string words together.", "What was I just doing?"))) + owner.emote("drool") + if(BP_CHEST) + if(prob(3)) + to_chat(owner, SPAN_WARNING(pick("You feel a tightness in your chest.", "You feel a little lightheaded.", "You need to take larger breaths than normal."))) + owner.emote(pick("cough", "gasp")) + if(BP_GROIN) + if(prob(3)) + to_chat(owner, SPAN_WARNING(pick("You feel a sharp pain in your gut.", "You feel a little bloated."))) + owner.visible_message("[owner] winces slightly.") + owner.delayed_vomit() + else + if(prob(stage*2)) + to_chat(owner, SPAN_WARNING("You feel very lethargic.")) + if(stage >= 3) //after ~10 minutes + for(var/obj/item/organ/internal/O in owner.internal_organs) + if(O.parent_organ == parent_organ) + if(BP_IS_ROBOTIC(O)) + continue + if(prob(stage*stage)) + O.damage = min(O.damage+stage, O.max_damage) + + if(stage >= 4) //after 15 minutes + if(prob(3)) + owner.reagents.add_reagent(egg, 2) //malignant cells breaking off, enter circulatory/lymphatic nodes to spread diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm index 80e0da49d26..fac7a7eb166 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm @@ -284,7 +284,7 @@ if(prob(85)) M.emote(pick("twitch", "shiver")) else - M.seizure() + M.seizure(rand(2,3)) /singleton/reagent/drugs/colorspace name = "Colorspace" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 633d12b08e8..0102ce3d398 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -40,6 +40,12 @@ M.add_chemical_effect(CE_ITCH, M.chem_doses[type] * 2) M.adjustHydrationLoss(2*removed) M.adjustCloneLoss(2.5*removed) // Cell regeneration spiralling out of control resulting in genetic damage. + if(((M.chem_doses[type] > 30) && prob(2)) || ((M.bodytemperature < 189) && prob(10))) //Bicaridine treats arterial bleeding when dose is greater than 30u. Alternatively, if the drug is used in a cryotube. + var/mob/living/carbon/human/H = M + for(var/obj/item/organ/external/E in H.organs) + if(E.status & ORGAN_ARTERY_CUT) + E.status &= ~ORGAN_ARTERY_CUT + M.visible_message("[M] spasms!", SPAN_DANGER("You feel a stabbing pain in your [E.name]!")) /singleton/reagent/bicaridine/overdose(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) M.dizziness = max(100, M.dizziness) @@ -47,12 +53,6 @@ M.adjustHydrationLoss(5*removed) M.adjustNutritionLoss(5*removed) - var/mob/living/carbon/human/H = M - if(M.chem_doses[type] > 30) //Bicaridine treats arterial bleeding when dose is greater than 30u and when the drug is overdosing (chemical volume in blood greater than 20). - for(var/obj/item/organ/external/E in H.organs) - if(E.status & ORGAN_ARTERY_CUT && prob(2)) - E.status &= ~ORGAN_ARTERY_CUT - /singleton/reagent/butazoline name = "Butazoline" description = "Butazoline, a recent improvement upon Bicaridine, is specialised at treating the most traumatic of wounds, though less so for treating severe bleeding." @@ -86,6 +86,13 @@ M.adjustHydrationLoss(2*removed) M.adjustCloneLoss(2.5*removed) //Cell regeneration spiralling out of control resulting in genetic damage. + if((M.bodytemperature < 192)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/external/head = H.get_organ(BP_HEAD) + if(head.disfigured && prob(10)) + M.visible_message("[M]'s face begins to contort back into it's original shape.", SPAN_DANGER("You feel a truly disgusting sensation as the skin and muscles of your face twist, crawl and turn.")) + head.disfigured = FALSE + /singleton/reagent/kelotane/overdose(var/mob/living/carbon/M, var/alien, var/datum/reagents/holder) var/mob/living/carbon/human/H = M var/obj/item/organ/external/head = H.get_organ(BP_HEAD) @@ -217,13 +224,14 @@ description = "Cryoxadone is a ground-breaking and complex medication that, when acting on bodies cooler than 170K, is capable of increasing the rate at which wounds regenerate, as well as treating genetic damage. Cryoxadone, alongside Clonexadone, are the backbones of the cloning industry." reagent_state = LIQUID color = "#8080FF" - metabolism = REM * 0.5 + metabolism = REM*3 //0.6u/t + overdose = 5 scannable = TRUE taste_description = "sludge" /singleton/reagent/cryoxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) M.add_chemical_effect(CE_CRYO, 1) - if(M.bodytemperature < 170 && !M.is_diona()) + if(M.bodytemperature < 170 && !M.is_diona() && (REAGENT_VOLUME(holder, type) < overdose)) M.add_chemical_effect(CE_PULSE, -2) M.add_chemical_effect(CE_OXYGENATED, 1) M.adjustCloneLoss(-100 * removed) @@ -232,22 +240,30 @@ var/mob/living/carbon/human/H = M for(var/obj/item/organ/internal/I in H.internal_organs) if(!BP_IS_ROBOTIC(I)) - I.heal_damage(20*removed) + if(I.organ_tag == BP_BRAIN) + if(I.damage > I.max_damage/2) //will only treat brain activity above 50% brain activity + continue + I.heal_damage(4*removed) else if(M.is_diona() && M.bodytemperature < 170) M.adjustFireLoss(5 * removed)//Cryopods kill diona. This damage combines with the normal cold temp damage, and their disabled regen +/singleton/reagent/cryoxadone/overdose(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) + M.adjustCloneLoss(10*removed) //'genetic healing' spirals out of control. + M.add_chemical_effect(CE_OCULOTOXIC, 4*removed) + /singleton/reagent/clonexadone name = "Clonexadone" description = "Clonexadone is a ground-breaking, complex medication that improved upon Cryoxadone. When acting on bodies cooler than 170K, the drug is capable of increasing the rate at which wounds regenerate, as well as treating genetic damage. Clonexadone, alongside Cryoxadone, are the backbones of the cloning industry." reagent_state = LIQUID color = "#80BFFF" - metabolism = REM * 0.5 + metabolism = REM*2 //0.4u/t + overdose = 5 scannable = TRUE taste_description = "slime" /singleton/reagent/clonexadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) M.add_chemical_effect(CE_CRYO, 1) - if(M.bodytemperature < 170 && !M.is_diona()) + if(M.bodytemperature < 170 && !M.is_diona() && (REAGENT_VOLUME(holder, type) < overdose)) M.add_chemical_effect(CE_PULSE, -2) M.add_chemical_effect(CE_OXYGENATED, 2) M.adjustCloneLoss(-300 * removed) @@ -256,10 +272,17 @@ var/mob/living/carbon/human/H = M for(var/obj/item/organ/internal/I in H.internal_organs) if(!BP_IS_ROBOTIC(I)) - I.heal_damage(30*removed) + if(I.organ_tag == BP_BRAIN) + if(I.damage > I.max_damage/2) //will only treat brain activity above 50% brain activity + continue + I.heal_damage(4*removed) else if(M.is_diona() && M.bodytemperature < 170) M.adjustFireLoss(15 * removed)//Cryopods kill diona. This damage combines with the normal cold temp damage, and their disabled regen +/singleton/reagent/clonexadone/overdose(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) + M.adjustCloneLoss(20*removed) //'genetic healing' spirals out of control. + M.add_chemical_effect(CE_OCULOTOXIC, 8*removed) + /* Painkillers */ /singleton/reagent/perconol @@ -552,6 +575,7 @@ M.add_chemical_effect(CE_PAINKILLER, 30) M.add_chemical_effect(CE_HALLUCINATE, -1) M.add_up_to_chemical_effect(CE_ADRENALINE, 1) + M.add_chemical_effect(CE_BLOODTHIN, 25) /singleton/reagent/synaptizine/overdose(var/mob/living/carbon/M, var/alien, var/datum/reagents/holder) if(prob(M.chem_doses[type] / 2)) @@ -560,7 +584,7 @@ if(prob(75)) M.emote(pick("twitch", "shiver")) else - M.seizure() + M.seizure(rand(1,2)) /singleton/reagent/alkysine name = "Alkysine" @@ -647,31 +671,47 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M H.add_chemical_effect(CE_CLUMSY, 1) + for(var/obj/item/organ/internal/I in H.internal_organs) if(I.organ_tag == BP_BRAIN) if(I.damage >= I.min_bruised_damage) continue if((I.damage > 0) && (I.robotic != 2)) //Peridaxon heals only non-robotic organs - I.damage = max(I.damage - removed, 0) + var/damage_healed = ((M.bodytemperature < 186) && M.chem_effects[CE_CRYO]) ? 2 : 1 //2x effective if administered in cryogenic conditions + I.damage = max(I.damage - damage_healed*removed, 0) + + if((M.bodytemperature < 153) && M.chem_effects[CE_ANTIBIOTIC]) //peridaxon in extracool cryogenic conditions alongside antibiotics will have a chance to de-nercotise liver and kidneys, though will incur overdose symptoms + H.infest_with_parasite(H, BP_TUMOUR_NONSPREADING, pick(H.organs), 10) + for(var/obj/item/organ/internal/O in H.internal_organs) + if((O.organ_tag == BP_LIVER) || (O.organ_tag == BP_KIDNEYS)) + if(O.damage && prob(5)) + if((O.status & ORGAN_DEAD) && !BP_IS_ROBOTIC(O)) + if(O.can_recover()) + O.status &= ~ORGAN_DEAD + O.heal_damage(5) + M.visible_message("[M] spasms!", SPAN_DANGER("You feel a stabbing pain!")) /singleton/reagent/peridaxon/overdose(var/mob/living/carbon/M, var/alien, var/datum/reagents/holder) M.dizziness = max(150, M.dizziness) M.make_dizzy(5) - if(prob(M.chem_doses[type] / 2)) - to_chat(M, SPAN_DANGER("You feel your insides twisting and burning.")) - M.adjustHalLoss(5) + if(REAGENT_VOLUME(M.reagents, /singleton/reagent/ryetalyn)) + return + var/mob/living/carbon/human/H = M + H.infest_with_parasite(H, BP_TUMOUR_NONSPREADING, pick(H.organs), 5) /singleton/reagent/ryetalyn name = "Ryetalyn" - description = "Ryetalyn is a novel, highly advanced, broad-spectrum medication, developed by Dominian scientists, which has varying clinical uses in treating genetic abnormalities including certain cancers, autoimmune conditions, and Hulk Syndrome." + description = "Ryetalyn is a highly advanced, broad-spectrum medication developed by Dominian scientists, which has varying clinical uses in treating genetic abnormalities including certain cancers, autoimmune conditions, and Hulk Syndrome." reagent_state = SOLID color = "#004000" overdose = REAGENTS_OVERDOSE taste_description = "acid" - metabolism = 1 + metabolism = REM metabolism_min = 0.25 /singleton/reagent/ryetalyn/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) + holder.remove_reagent(/singleton/reagent/toxin/malignant_tumour_cells, 2) + var/needs_mutation_update = M.mutations > 0 M.mutations = 0 M.disabilities = 0 @@ -1048,6 +1088,8 @@ description = "Leporazine is a complex medication which improves thermal homeostasis, stabilising and regulating the body's core temperature. Leporazine often results in hyperventilation which should be monitored." reagent_state = LIQUID color = "#C8A5DC" + metabolism = REM/2 //0.1u/t + breathe_met = REM/4 //0.05u/t overdose = REAGENTS_OVERDOSE scannable = TRUE taste_description = "bitterness" @@ -1056,7 +1098,7 @@ if(!check_min_dose(M)) return M.add_up_to_chemical_effect(CE_NOFEVER, 5) //Also handles the effects of fevers - if(!(REAGENT_VOLUME(holder, type) > 20)) + if(!(REAGENT_VOLUME(holder, type) > overdose)) if(M.bodytemperature > 310) M.bodytemperature = max(310, M.bodytemperature - (40 * TEMPERATURE_DAMAGE_COEFFICIENT)) else if(M.bodytemperature < 311) @@ -1315,34 +1357,58 @@ /singleton/reagent/cataleptinol name = "Cataleptinol" - description = "Cataleptinol is a highly advanced, expensive medication capable of regenerating the most damaged of brain tissues. Cataleptinol is used in the treatment of dumbness, cerebral blindness, cerebral paralysis and aphasia. The drug is more effective when the patient's core temperature is below 170K." + description = "Cataleptinol is a highly advanced, expensive medication recently developed by Yomi Genetics. Originally developed as a drug to facilitate the advanced cloning of non-human animal brains for wealthy pet owners, some doctors have found it exceptional at treating significant brain injuries in humans. The drug is licensed as a safe medication for use in cryogenics; outside of cryogenic conditions, the drug performs worse, though emergency, off-label uses of cataleptinol can prove lifesaving." reagent_state = LIQUID color = "#FFFF00" - metabolism = REM //0.2u/tick - overdose = 15 + metabolism = REM*3 //0.6u/t + od_minimum_dose = 2.4 + overdose = 3 scannable = TRUE - taste_description = "bitterness" + taste_description = "sharp cardamom" metabolism_min = REM * 0.25 - /singleton/reagent/cataleptinol/affect_blood(var/mob/living/carbon/human/M, var/alien, var/removed, var/datum/reagents/holder) - M.add_chemical_effect(CE_PAINKILLER, 10) - M.dizziness = max(100, M.dizziness) - M.make_dizzy(5) - var/chance = M.chem_doses[type]*removed - if(M.bodytemperature < 170) - chance = (chance*4) + 5 - M.add_chemical_effect(CE_BRAIN_REGEN, 30) //1 unit of cryo-tube Cataleptinol will raise brain activity by 10%. - else - M.add_chemical_effect(CE_BRAIN_REGEN, 20) //1 unit of Cataleptinol will raise brain activity by 5%. + if(REAGENT_VOLUME(M.reagents, /singleton/reagent/alkysine)) //don't mix alkysine and cataleptinol + overdose(M, alien, removed, holder) + return + var/obj/item/organ/internal/brain = M.internal_organs_by_name[BP_BRAIN] + if((M.bodytemperature < 179) && (M.chem_effects[CE_CRYO])) //best use in cryogenics, experiment with Balanced or Prioritising Metabolisation settings, aiming for a gas cooler temperature target that minimises the cryostasis multiplier. remember the cryotube heats slowly when someone is inside. + if(brain) + if(brain.damage && brain.damage < brain.max_damage && !(M.chem_effects[CE_NEUROTOXIC])) //skips the oxygenation check under brain.dm + brain.damage = max(brain.damage - 16*removed, 0) //high number, as cryo slows metabolism. also needs to slightly outpace rough injuries to actually make it worthwhile to use. + else //without cryogenics. skips the oxygen check, however has large downsides if not pushed thorugh an IV to moderate volume in blood. + if(brain) + if(brain.damage && brain.damage < brain.max_damage && !(M.chem_effects[CE_NEUROTOXIC]) && prob(75)) + brain.damage = max(brain.damage - 8*removed, 0) //pretty slow, non-guaranteed brain healing - 75% chance of restoring 2.5% brain activity per tick. only really useful during apocalyptic scenarios. + M.dizziness = max(200, M.dizziness + 15) + M.hallucination = max(M.hallucination, 100) + M.add_chemical_effect(CE_BLOODTHIN, 40) //treat (arterial) bleeding first + if(prob(40)) + to_chat(M, SPAN_HIGHDANGER(pick("You have a painful headache!", "You feel a throbbing pain behind your eyes!", "You feel a painful pressure build up within your skull!", "An unbearable pain radiates throughout your head!"))) + M.adjustHalLoss(rand(30,60)) //painshock levels of pain, though still managable. + M.Weaken(2) + M.stuttering = 40 + M.emote(pick("flail", "twitch_v", "choke", "scream")) + else if(prob(25)) + if(prob(50)) + to_chat(M, SPAN_WARNING(pick("You feel a tingly sensation in your body.", "You can smell something unusual.", "You can taste something unusual."))) + else + M.emote(pick("twitch", "shiver")) + +/singleton/reagent/cataleptinol/affect_chem_effect(var/mob/living/carbon/M, var/alien, var/removed) //hallucinations done under here so antipsychotics can still work + . = ..() + if(.) + M.add_chemical_effect(CE_HALLUCINATE, 2) + if(prob(40)) + M.add_chemical_effect(CE_HEPATOTOXIC, 2) //major downside of using cataleptinol, this will create more problems if left unchecked. outside of cryogenic conditions, this translates to trading ~25% brain activity for total liver failure; in cryogenic conditions, you trade ~40% brain activity for total liver failure. /singleton/reagent/cataleptinol/overdose(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) - M.hallucination = max(M.hallucination, 15) - if(prob(5)) - to_chat(M, SPAN_WARNING(pick("You have a painful headache!", "You feel a throbbing pain behind your eyes!"))) - ..() - + M.add_chemical_effect(CE_NEUROTOXIC, 6*removed) //crashes both the brain & liver if you OD. Neurotoxic also stops it from healing, so you just fucked up a patient for no gain. + if(prob(40)) + M.add_chemical_effect(CE_HEPATOTOXIC, 2) //stacks on top of ambient liver damage from using cataleptinol + if(prob(30)) + M.seizure(rand(2,3)) /singleton/reagent/fluvectionem name = "Fluvectionem" @@ -1379,6 +1445,11 @@ . = ..() +/singleton/reagent/fluvectionem/affect_chem_effect(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) + . = ..() + if(.) + M.add_chemical_effect(CE_BLOODTHIN, 25) + /singleton/reagent/pulmodeiectionem name = "Pulmodeiectionem" description = "Pulmodeiectionem is a complex anti-toxin medication that is capable of purging the lungs of toxic reagents by damaging the mucous lining of the bronchi and trachea, allowing particulate to be coughed out of the lungs. Pulmodeiectionem works only when inhaled and can cause long-term damage to the lungs." @@ -1477,7 +1548,7 @@ /singleton/reagent/sanasomnum name = "Sanasomnum" - description = "Not strictly a drug, Sanasomnum is actually a cocktail of biomechanical stem cells, which induce a regenerative state of unconsciousness capable healing almost any injury in minutes - however, usage nearly guarantees long-term and irreversible complications, and it is banned from medical use throughout the spur." + description = "Not strictly a drug, Sanasomnum is a cocktail of biomechanical stem cells known to cause paralysis and cancerous growths in the few human studies it was trialled during. As a result, little further research has been done on it... nothing that's available to the public, at least." reagent_state = SOLID color = "#b2db5e" overdose = REAGENTS_OVERDOSE diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index 584276d4a3b..b0764f016b5 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -550,17 +550,31 @@ description = "A bright orange powder consisting of strange self-heating properties that reacts when exposed to sodium chloride." reagent_state = SOLID color = "#FFFF00" + scannable = TRUE + breathe_met = REM/2 + touch_met = REM/2 taste_description = "chalk" default_temperature = 600 //Kelvin -/singleton/reagent/cryosurfactant - name = "Cryosurfactant" +/singleton/reagent/pyrosilicate/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) + if(M.bodytemperature < M.species.heat_level_3) + M.bodytemperature = min(474, M.bodytemperature + (50 * TEMPERATURE_DAMAGE_COEFFICIENT)) +/singleton/reagent/cryosilicate + name = "Cryosilicate" description = "A bright cyan liquid consisting of strange self-cooling properties that reacts when exposed to water." reagent_state = LIQUID color = "#00FFFF" + scannable = TRUE + breathe_met = REM/2 + touch_met = REM/2 taste_description = "needles" default_temperature = 100 //Kelvin +/singleton/reagent/cryosilicate/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) + if(!(REAGENT_VOLUME(M.reagents, /singleton/reagent/leporazine) > 5)) + if(M.bodytemperature > M.species.cold_level_3) + M.bodytemperature = max(140, M.bodytemperature - (50 * TEMPERATURE_DAMAGE_COEFFICIENT)) + /singleton/reagent/venenum name = "Venenum" description = "A thick tar like liquid that seems to move around on it's own every now and then. Limited data shows it only works when injected into the bloodstream." diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 6909bf7106b..9debeb92908 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -805,6 +805,16 @@ if(prob(5)) M.emote(pick("twitch_v", "grunt")) + if((M.bodytemperature < 151)) //red nightshade in extracool cryogenic conditions will restore bonebreaks, at the cost of blood depletion + var/mob/living/carbon/human/H = M + H.vessel.remove_reagent(/singleton/reagent/blood, rand(15,30)) + for(var/obj/item/organ/external/E in H.organs) + if(E.status & ORGAN_BROKEN) + if(prob(10)) + H.vessel.remove_reagent(/singleton/reagent/blood, rand(30, 60)) + E.status &= ~ORGAN_BROKEN + M.visible_message("[M] spasms!", SPAN_DANGER("You feel a stabbing pain!")) + /singleton/reagent/toxin/berserk/overdose(var/mob/living/carbon/M, var/datum/reagents/holder) if(prob(25)) M.add_chemical_effect(CE_CARDIOTOXIC, 1) @@ -997,3 +1007,23 @@ var/obj/item/organ/external/affected = H.get_organ(BP_CHEST) var/obj/item/organ/internal/parasite/heartworm/infest = new() infest.replaced(H, affected) + +/singleton/reagent/toxin/malignant_tumour_cells + name = "Malignant Tumour Cells" + description = "Cells of a malignant tumour which have broken off and entered the circulatory and/or lymphatic system to spread to other regions of the body." + reagent_state = SOLID + color = "#460000" + metabolism = REM/2 //Slow metabolisation so medical can potentially screen it early, given it's danger. + ingest_mul = 0 + touch_mul = 0 + breathe_mul = 0 + taste_description = "blood" + taste_mult = 0.1 + strength = 0 + +/singleton/reagent/toxin/malignant_tumour_cells/affect_blood(mob/living/carbon/M, alien, removed, datum/reagents/holder) + ..() + var/mob/living/carbon/human/H = M + if(!(REAGENT_VOLUME(M.reagents, /singleton/reagent/cytophenolate)) && !H.internal_organs_by_name[BP_TUMOUR_SPREADING]) //only affects people with immunosuppressants or a pre-existing malignant tumour + return + H.infest_with_parasite(H, BP_TUMOUR_SPREADING, pick(H.organs), 10) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index e2f8efdb050..3ae859bbc35 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -733,7 +733,8 @@ name = "Cataleptinol" id = "cataleptinol" result = /singleton/reagent/cataleptinol - required_reagents = list(/singleton/reagent/toxin/phoron = 0.1, /singleton/reagent/alkysine = 1, /singleton/reagent/cryoxadone = 0.1) + required_reagents = list(/singleton/reagent/toxin/phoron = 0.5, /singleton/reagent/alkysine = 2, /singleton/reagent/clonexadone = 1) + catalysts = list(/singleton/reagent/cryosilicate = 5) result_amount = 1 /datum/chemical_reaction/coughsyrup @@ -3891,41 +3892,41 @@ result_amount = 4 required_reagents = list(/singleton/reagent/silicate = 1, /singleton/reagent/acid = 1, /singleton/reagent/hydrazine = 1, /singleton/reagent/iron = 1) -/datum/chemical_reaction/cryosurfactant - name = "Cryosurfactant" - id = "cryosurfactant" - result = /singleton/reagent/cryosurfactant +/datum/chemical_reaction/cryosilicate + name = "Cryosilicate" + id = "cryosilicate" + result = /singleton/reagent/cryosilicate result_amount = 3 - required_reagents = list(/singleton/reagent/surfactant = 1, /singleton/reagent/drink/ice = 1, /singleton/reagent/sodium = 1) + required_reagents = list(/singleton/reagent/silicate = 1, /singleton/reagent/drink/ice = 1, /singleton/reagent/sodium = 1) //WATER -/datum/chemical_reaction/cryosurfactant_cooling_water - name = "Cryosurfactant Cooling Water" - id = "cryosurfactant_cooling_water" +/datum/chemical_reaction/cryosilicate_cooling_water + name = "Cryosilicate Cooling Water" + id = "cryosilicate_cooling_water" result = null result_amount = 1 - required_reagents = list(/singleton/reagent/cryosurfactant = 1) + required_reagents = list(/singleton/reagent/cryosilicate = 1) inhibitors = list(/singleton/reagent/pyrosilicate = 1) catalysts = list(/singleton/reagent/water = 1) mix_message = "The solution begins to freeze." -/datum/chemical_reaction/cryosurfactant_cooling_water/on_reaction(var/datum/reagents/holder, var/created_volume, var/created_thermal_energy) - holder.del_reagent(/singleton/reagent/cryosurfactant) +/datum/chemical_reaction/cryosilicate_cooling_water/on_reaction(var/datum/reagents/holder, var/created_volume, var/created_thermal_energy) + holder.del_reagent(/singleton/reagent/cryosilicate) holder.add_thermal_energy(-created_volume*500) //ICE -/datum/chemical_reaction/cryosurfactant_cooling_ice - name = "Cryosurfactant Cooling Ice" - id = "cryosurfactant_cooling_ice" +/datum/chemical_reaction/cryosilicate_cooling_ice + name = "Cryosilicate Cooling Ice" + id = "cryosilicate_cooling_ice" result = null result_amount = 1 - required_reagents = list(/singleton/reagent/cryosurfactant = 1) + required_reagents = list(/singleton/reagent/cryosilicate = 1) inhibitors = list(/singleton/reagent/pyrosilicate = 1) catalysts = list(/singleton/reagent/drink/ice = 1) mix_message = "The solution begins to freeze." -/datum/chemical_reaction/cryosurfactant_cooling_ice/on_reaction(var/datum/reagents/holder, var/created_volume, var/created_thermal_energy) - holder.del_reagent(/singleton/reagent/cryosurfactant) +/datum/chemical_reaction/cryosilicate_cooling_ice/on_reaction(var/datum/reagents/holder, var/created_volume, var/created_thermal_energy) + holder.del_reagent(/singleton/reagent/cryosilicate) holder.add_thermal_energy(-created_volume*500) /datum/chemical_reaction/pyrosilicate_heating @@ -3934,22 +3935,22 @@ result = null result_amount = 1 required_reagents = list(/singleton/reagent/pyrosilicate = 1) - inhibitors = list(/singleton/reagent/cryosurfactant = 1) + inhibitors = list(/singleton/reagent/cryosilicate = 1) catalysts = list(/singleton/reagent/sodiumchloride = 1) /datum/chemical_reaction/pyrosilicate_heating/on_reaction(var/datum/reagents/holder, var/created_volume) holder.del_reagent(/singleton/reagent/pyrosilicate) holder.add_thermal_energy(created_volume*1000) -/datum/chemical_reaction/pyrosilicate_cryosurfactant - name = "Pyrosilicate Cryosurfactant Reaction" - id = "pyrosilicate_cryosurfactant" +/datum/chemical_reaction/pyrosilicate_cryosilicate + name = "Pyrosilicate Cryosilicate Reaction" + id = "pyrosilicate_cryosilicate" result = null - required_reagents = list(/singleton/reagent/pyrosilicate = 1, /singleton/reagent/cryosurfactant = 1) + required_reagents = list(/singleton/reagent/pyrosilicate = 1, /singleton/reagent/cryosilicate = 1) required_temperature_min = T0C //Does not react when below these temperatures. result_amount = 1 -/datum/chemical_reaction/pyrosilicate_cryosurfactant/on_reaction(var/datum/reagents/holder, var/created_volume, var/created_thermal_energy) +/datum/chemical_reaction/pyrosilicate_cryosilicate/on_reaction(var/datum/reagents/holder, var/created_volume, var/created_thermal_energy) if(created_volume) var/turf/simulated/floor/T = get_turf(holder.my_atom.loc) if(istype(T)) diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index 00e04ae43f7..acad3bd2600 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -1,6 +1,6 @@ /obj/item/storage/box/bloodpacks - name = "blood packs bags" - desc = "This box contains blood packs." + name = "\improper IV bags" + desc = "This box contains IV bags." illustration = "blood" /obj/item/storage/box/bloodpacks/fill() @@ -14,7 +14,7 @@ new /obj/item/reagent_containers/blood/empty(src) /obj/item/reagent_containers/blood - name = "blood pack" + name = "\improper IV bag" desc = "Contains fluids used for transfusions." icon = 'icons/obj/bloodpack.dmi' icon_state = "bloodpack" @@ -37,7 +37,7 @@ /obj/item/reagent_containers/blood/Initialize() . = ..() if(blood_type != null) - name = "blood pack [blood_type]" + name = "\improper IV bag - [blood_type] blood" reagents.add_reagent(/singleton/reagent/blood, volume, list("donor"=null,"blood_DNA"=null,"blood_type"=blood_type,"trace_chem"=null,"dose_chem"=null)) w_class = ITEMSIZE_NORMAL update_icon() @@ -163,10 +163,10 @@ /obj/item/reagent_containers/blood/attackby(obj/item/attacking_item, mob/user) ..() if (attacking_item.ispen()) - if (REAGENT_VOLUME(reagents, /singleton/reagent/blood) && name != "empty blood pack") //Stops people mucking with bloodpacks that are filled + if (REAGENT_VOLUME(reagents, /singleton/reagent/blood) && name != "empty IV bag") //Stops people mucking with bloodpacks that are filled to_chat(user, SPAN_NOTICE("You can't relabel [name] until it is empty!")) return - var/blood_name = tgui_input_list(user, "What blood type would you like to label it as?", "Blood Types", list("A+", "A-", "B+", "B-", "O+", "O-", "AB+", "AB-", "Saline Plus", "Clear", "Cancel")) + var/blood_name = tgui_input_list(user, "What would you like to label the IV bag?", "Label Selection", list("A+ blood", "A- blood", "B+ blood", "B- blood", "O+ blood", "O- blood", "AB+ blood", "AB- blood", "Saline Plus", "Cryonics mixture", "Other mixture", "Clear", "Cancel")) if(blood_name == "Cancel") return var/obj/item/i = user.get_active_hand() @@ -176,13 +176,13 @@ blood_type = null name = initial(name) desc = initial(desc) - to_chat(user, SPAN_NOTICE("You clear the blood pack label.")) + to_chat(user, SPAN_NOTICE("You clear the IV bag label.")) update_icon() return blood_type = blood_name - name = "blood pack [blood_type]" + name = "\improper IV bag - [blood_type]" desc = "Contains fluids used for transfusions." - to_chat(user, SPAN_NOTICE("You label the blood pack as [blood_type].")) + to_chat(user, SPAN_NOTICE("You label the IV bag as [blood_type].")) update_icon() return @@ -269,12 +269,12 @@ blood_type = "O-" /obj/item/reagent_containers/blood/empty - name = "empty blood pack" + name = "empty IV bag" desc = "Seems pretty useless... Maybe if there were a way to fill it?" icon_state = "bloodpack" /obj/item/reagent_containers/blood/ripped - name = "ripped blood pack" + name = "ripped IV bag" desc = "It's torn up and useless." icon = 'icons/obj/bloodpack.dmi' icon_state = "ripped" diff --git a/code/modules/reagents/reagent_containers/glass/bottle.dm b/code/modules/reagents/reagent_containers/glass/bottle.dm index 902fa38bfe4..59c5572a3e3 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle.dm @@ -145,15 +145,15 @@ /obj/item/reagent_containers/glass/bottle/pyrosilicate name = "pyrosilicate bottle" - desc = "A small bottle. Contains pyrosilicate - used to heat up reagents." + desc = "A small bottle. Contains pyrosilicate which is used to heat up reagents." icon_state = "bottle-4" reagents_to_add = list(/singleton/reagent/pyrosilicate = 60) -/obj/item/reagent_containers/glass/bottle/cryosurfactant - name = "cryosurfactant bottle" - desc = "A small bottle. Contains cryosurfactant - used to cool down reagents." +/obj/item/reagent_containers/glass/bottle/cryosilicate + name = "cryosilicate bottle" + desc = "A small bottle. Contains cryosilicate which is used to cool down reagents." icon_state = "bottle-4" - reagents_to_add = list(/singleton/reagent/cryosurfactant = 60) + reagents_to_add = list(/singleton/reagent/cryosilicate = 60) /obj/item/reagent_containers/glass/bottle/epinephrine name = "epinephrine bottle" @@ -229,7 +229,7 @@ /obj/item/reagent_containers/glass/bottle/trioxin name = "hylemnomil-zeta vial" - desc = "A small, unmarked lial with an ominous label. It contains a swirling, purple liquid." + desc = "A small, unmarked vial with an ominous label. It contains a swirling, purple liquid." icon_state = "bouteille" reagents_to_add = list(/singleton/reagent/toxin/hylemnomil = 60) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index f9d91e99f3e..e027eb73c25 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -321,7 +321,7 @@ /obj/item/reagent_containers/hypospray/autoinjector/sanasomnum name = "sanasomnum autoinjector" - desc = "A special autoinjector loaded with outlawed biomechanical stem cells, inducing a regenerative coma so intense it can heal almost any injury - even broken bones, organ and brain damage, severed tendons, and arterial damage. Upon use one will fall immediately into a state of unconsciousness lasting roughly three to five minutes, arising completely healed. The only thing it cannot fix are organs that have been destroyed outright, or so much cumulative damage that death is all but certain. The only downside is that Sanasomnum use guarantees extreme cancerous growth months or years down the line, which is invariably fatal in the long-term. However, in the short-term, it will save your life." + desc = "An autoinjector loaded with sanasomnum, an experimental and outlawed combination medicine known to cause paralysis and cancerous growths in the few human studies it was trialled during. As a result, little further research has been done on it... nothing that's available to the public, at least." //antag chemical. this is the non-antag facing description so no one reads the autoinjector desc and considers it fairgame to then use it. volume = 20 amount_per_transfer_from_this = 20 diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 3fe9403e073..bd2de09f860 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -370,3 +370,8 @@ icon_state = "cleanertablet" reagents_to_add = list(/singleton/reagent/spacecleaner = 15) +/obj/item/reagent_containers/pill/ryetalyn + name = "10u Ryetalyn Pill" + desc = "A medicine used to treat genetic conditions, including benign and malignant tumours." + icon_state = "pill11" + reagents_to_add = list(/singleton/reagent/ryetalyn = 10) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 14bc17e07af..45b5c7b7ece 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -419,11 +419,8 @@ if(src.loc) var/datum/gas_mixture/env = src.loc.return_air() - if(env) - if (reagents.total_volume > 750) - env.temperature = 0 - else if (reagents.total_volume > 500) - env.temperature -= 100 + if(env && reagents.total_volume) + env.temperature = max(173, env.temperature - (reagents.total_volume/10)) QDEL_IN(src, 10) diff --git a/html/changelogs/kermit-cryonicsadditions.yml b/html/changelogs/kermit-cryonicsadditions.yml new file mode 100644 index 00000000000..b76d874fbfe --- /dev/null +++ b/html/changelogs/kermit-cryonicsadditions.yml @@ -0,0 +1,21 @@ +author: kermit + +delete-after: True + +changes: + - qol: "Cryotubes apply less stasis at temperatures between 120K and 200K, meaning cryotube beaker mixes are more viable." + - rscadd: "Cataleptinol (new recipe: 0.5u phoron, 2u alkysine, 1u clonexadone and a 5u cryosilicate catalyst) has been reworked from the ground up to be more useful and versatile. Cataleptinol will heal brain activity regardless of oxygenation - at cryo temperatures, this is with no consequence; outside of cryogenics, the benefits come with large consequences which will exacerbate any medical conditions." + - rscadd: "Cryo/Clonexadone both overdose at 5u. This isn't anything to worry about when using Cryo/Clonexadone in a cryotube; using these two chemicals outside of cryotubes requires much greater care. Added ocular toxicity (eye damage) for use by Cryo/Clonexadone's overdose." + - balance: "Significantly nerfs Cryo/Clonexadone's organ healing. It's still there, but pharmacist's can improve upon the organ healing - it's also required due to metabolisation/stasis changes. Cryo/Clonexadone only heals brain damage above the 50% mark." + - rscadd: "Renames Cryosurfactant -> Cryosilicate. The recipe now also uses silicate instead of surfactant." + - rscadd: "Pyrosilicate and Cryosilicate respectively superheat or supercool the body, making them useful for inducing cryogenic conditions or chemically incinerating someone. Leporazine inhibits these functions." + - rscadd: "Adds a chemical effect for blood thinning - essentially an anti-coagzolug effect, it makes you bleed faster. Will prevent coagzolug from working. Currently used by Cataleptinol, Fluvectionem and Synaptizine." + - qol: "Bicaridine's AB fixing requires a minimum of 30u (you should still use more than this - every 0.1u above this is another roll of 'will it fix the AB?') instead of a minimum of 50u. Alternatively, you can used bicaridine in a cryotube." + - rscadd: "Kelotane can now be used in a cryotube to fix disfiguration. Red Nightshade in cryogenic conditions will restore bone breaks. Peridaxon+Thetamycin combo can de-necrose livers/kidneys in cryogenic conditions." + - rscadd: "Overdosing peridaxon results in the developing of benign tumours; benign tumours do not spread or cause collateral damage to organs, they simply cause pain. Ryetalyn will put a tumour into recession." + - rscadd: "Genetic damage now results in the developing of malignant tumours; malignant tumours will eventually spread and cause collateral damage to organs. Symptoms will be different depending on the tumour's location. Ryetalyn will put a tumour into recession - some ryetalyn pills can be found in the GTR's Medication Cabinet." + - balance: "Limb deformities resulting from genetic damage may occur more often." + - imageadd: "Renames Blood Pack -> IV Bag. Adds 'Cryonics Mixture' and 'Other Mixture' IV bag labels." + - rscadd: "Cryocells can be deconstructed or have their components upgraded. Upgrading the components increases the effectiveness of the Cryostasis Settings." + - bugfix: "Coolant tanks no longer anti-nuke an environment's atmosphere when destroyed." + - bugfix: "Cryotubes no longer render synthetics unconscious - IPCs can now bathe in cryotubes to cool off." diff --git a/icons/obj/bloodpack.dmi b/icons/obj/bloodpack.dmi index cbfc8828184b2cda6f52e784381f3e1a77e95e19..4c6f9952a47ce50e9db9b81b5eb4322d282e41d2 100644 GIT binary patch literal 1880 zcmb7_do&w%6vv|;K{bh`MUf_yl}#CKy-H{?a@Ml7T0+Uj#At(hB@#mEv=gm1)mo^9 zQjdBKJ(5aLk5<=uZA97<2^EiMkf4!9blKV2Iort>E3+3m1N|nq0INDmONEwbks7hR7U~sZ`R8nMOOhR%@d>jBkxO;oF1C;$4 z)h<|gcyIc@=C?M8CfH9*xn@*aHa5jYM;@4_qA0RSyGl=rbf!d)@1 zIqr3=(Nl?&Z--i?-ksuC>Y``Y?@xK&*-S0APHO5!8?j7v-huW))DQXT-DYYGjgVcg zM;5Ip@|AsaA8wg@m1Ufit{R(c&0!y%GcJ=B5H%Bc+K9@(gM6}8@kSCH*yTh!A$?bu za~`_e(~zxDDDaGf29%zBg!#a=l}igM2~&V$OyC*SF|k-I$ zcG+pA6hdG9eiHl{<)sd4biI7BO`NKjj7v$tWrKPvW8UA0q6yRD(06Dw^iT6mFS@>m z)<7rK>YDaa?h#rwj%&cLHl`x0iLh0DQ%|m19jpL!)#xkOND8aJ-}gn!+Z3J4d7`Xj z*3zMpLH{B)ee{9)4xFY~GoCRqFHDpZYlISsgeNXS9}KiaCAPCzt#psfsl&Wz$CA=i zRw)d0<*B0YwK&yL)sEcoB4{Rb@k?m0l3m?RS_ZL^3gy(tw@@Q_0yZx$8bv)EH*-8w z4lnPNeN5=$PheY{RT}JBR`Rq-odwDtMZJq{MT@2JU3c4_hl!V$8&lC8e29pYY5a8H zLPxlv>h3lrIsW7eJ4|Q(d(8-{MRo6V!sx?F@{fX2h+#{66ra4cd67sYit3lfE_%#X zS#I=dh%XniN?7N@c9>;5cEf)ai^W__7g<>s4(^+-wD7xTp2c7=Fr1|<=Nxd^#MVbW z-x#L@2B&gY7Z+<~?vZ^aTmIU)xZN;FuMfcNU+g&ohj7KzH8ULqJH;MO#UB^kcZEBg zJRRC_RxTmfRE@^0r~A1IJejRCLyI%@Oi{X@VW%`>5+{?%+JbF#`H&W<17d#2bxB&! zY+vPc80eLPQNZ=tp-m5b_}fQ{zC_+|_4afEGg*$`PJZI_W;0@FC;SBPZR}z1t4ZA= za{|1UTwDcSPT|W|`0#<(!&gjC03`ON1^p2YwAswmaJp(094Ykcp9AzSAnA0e8-o*j zo5js(Udv{yZ|XZ<8cAwWJ8)i7SHm6%8!^`W>m&^eCJPF!xJA&NAZp zAvlRPB71D`N_tw_58F%HQ~heJVz96Bn=z*)EV5EY>NczBZ#OFR$_UGF+Jkc~{i&nL z7uY$<#31Wxs0J&f$w2AAJvKY5h?xBOI zbk88S|g zSSm!qGf!u5-r&vZr{?N77d^R`A}EYAjr^jj=rl|LM$+C?OP*Mz`Q*j^hz8l3&~J^vF;Iy5mx zT+&c>L?^-vL+sa5Vq` literal 1682 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 literal 11293 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 a1@%kVm)4