From b0d922cf44617aa11e4b46777cbb548bbccc931d Mon Sep 17 00:00:00 2001 From: nikothedude <59709059+nikothedude@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:29:29 -0400 Subject: [PATCH] [SEMI-MODULAR] [TEST-MERGE FIRST] Adds synth wounds and resets synth limb damage to 1x, other synth changes (#23733) * [TEST-MERGE FIRST] Wound refactor number two: Full synthetic support * Wound refactor two compatability (#23618) * Delam emergency procedure moth (#23483) * safety moff * delta/whitespace/examine * icebox * moff poster * moff poster * Update DelamProcedure.tsx * Update scram.dm * sound plays during warning * remove nightshift, theres already a global proc * scrubber hint * missed that define * Apply suggestions from code review Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> * covered by ui_interact * Update modular_skyrat/modules/delam_emergency_stop/code/scram.dm Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> * Update modular_skyrat/modules/delam_emergency_stop/code/scram.dm --------- Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> * Automatic changelog for PR #23483 [ci skip] * Automatic changelog compile [ci skip] * [non modular] disables TG "hold up" for the foreseeable future (#23607) Update gun.dm * Automatic changelog for PR #23607 [ci skip] * [MIRROR] Desouls Hivelord [MDB IGNORE] (#23609) * Desouls Hivelord (#78213) ## About The Pull Request ![dreammaker_RJz4brjobM](https://github.com/tgstation/tgstation/assets/7483112/e5e4a3e9-ea6b-47f9-887c-3339d24d3fa8) Replaces the sprite of the hivelord with a new one, in my continuing quest to annihilate the old asteroid mob sprites. A (never completed) asteroid mob resprite was actually my first PR, this one is my 200th. I am also planning on fucking with basic mob versions of these mobs some time but the sprites can be atomised out. In addition to replacing the old-ass MSPaint sprites, this PR also adds a short death animation effect to the hivelord brood (from hivelords or legions) which looks nicer than them just vanishing instantly upon death. Look at this video for an example of the animation: https://www.youtube.com/watch?v=cKaskN5-y2A ## Why It's Good For The Game Looks nicer. ## Changelog :cl: image: Hivelords have a new sprite. image: Hivelord and Legion brood have a death animation. /:cl: * Desouls Hivelord --------- Co-authored-by: Jacquerel * Automatic changelog for PR #23609 [ci skip] * [MIRROR] Updates chem factory tank sprites [MDB IGNORE] (#23608) * Updates chem factory tank sprites (#78209) Updates chem factory tank sprites. * Updates chem factory tank sprites --------- Co-authored-by: Wallem <66052067+Wallemations@users.noreply.github.com> * [MIRROR] Rice Dough can be made in a beaker [MDB IGNORE] (#23611) * Rice Dough can be made in a beaker (#78062) ## About The Pull Request Rice dough can be made in a beaker using 20u of Rice Flour and 10u of Water. 10u of Rice Flour is made from 5u of Rice and 5u of Flour. Rice dough can still be crafted manually using the crafting menu and the original recipe. ## Why It's Good For The Game Cooks can sometimes get swamped with work, especially on a high-pop shift or when there are no botanists. By making rice dough more convenient to make, cooks don't need to spend as much time in the crafting menu. Rice Flour is made from mixing equal parts Rice and Flour. Since no recipe other than Rice dough uses both Rice and Flour in it's Recipe, it should be fine to turn those regents into the intermediate reagent "Rice Flour". Fixes #77966 ## Changelog :cl: qol: Rice Dough may be made in beaker instead of being crafted, but the rice and flour must be added first /:cl: * Rice Dough can be made in a beaker --------- Co-authored-by: blueDev2 <89804215+blueDev2@users.noreply.github.com> * Automatic changelog for PR #23608 [ci skip] * Automatic changelog for PR #23611 [ci skip] * f * awda * unused type!!! * Apply suggestions from code review Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> * oh hey unused defines! bye --------- Co-authored-by: lessthanthree <83487515+lessthnthree@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> Co-authored-by: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Co-authored-by: Changelogs Co-authored-by: RatFromTheJungle <62520989+RatFromTheJungle@users.noreply.github.com> Co-authored-by: Jacquerel Co-authored-by: Wallem <66052067+Wallemations@users.noreply.github.com> Co-authored-by: blueDev2 <89804215+blueDev2@users.noreply.github.com> * aa * fsegf * im confused * ASSwdadzxd * a * break to fix shuytyyhdg * aaaasdfggh * a * ack * a little more * AA * a readme * a lil colder * another touchup * ack * msucle * a * one * tada * ack * a * fuck! * some packs and medicine * a * more * it only makes sense * readme update * woo * and now, we map it in * me when * Apply suggestions from code review Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> * j * fix ci * Apply suggestions from code review Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com> * o;l * SPACE * AAAAAAAAAAAAAAAAAAAAAH * Apply suggestions from code review Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> * j * Apply suggestions from code review Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> * y * a * dwadwa * Just fixing this typo you missed * And found another instance of this same block of code * change the way burns work * thick clothing now blocks reagents * cock * uyjujy * a * yjhf * awdawdawd * remove stacking buffs + make electrical damage worse * whoops * FUCK * adwdad * AAAA * oh the misery * this'd be cool * warn * a * i think it needs a lil buff * Apply suggestions from code review Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> * asd * I LOVE COMPILING AND NOT HAVING ERROSR --------- Co-authored-by: lessthanthree <83487515+lessthnthree@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> Co-authored-by: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Co-authored-by: Changelogs Co-authored-by: RatFromTheJungle <62520989+RatFromTheJungle@users.noreply.github.com> Co-authored-by: Jacquerel Co-authored-by: Wallem <66052067+Wallemations@users.noreply.github.com> Co-authored-by: blueDev2 <89804215+blueDev2@users.noreply.github.com> Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com> --- ...avaland_surface_syndicate_base1_skyrat.dmm | 2 + .../SpaceRuins/skyrat/interdynefob.dmm | 2 + code/__DEFINES/text.dm | 4 + code/__DEFINES/wounds.dm | 24 +- .../subsystem/processing/quirks.dm | 2 +- .../mob/living/carbon/carbon_defense.dm | 6 +- .../reagents/cat2_medicine_reagents.dm | 13 +- .../code/modules/jobs/job_types/roboticist.dm | 16 + .../modules/medical/attributions.txt | 2 + .../modules/medical/code/cargo/packs.dm | 36 + modular_skyrat/modules/medical/code/medkit.dm | 177 +++++ modular_skyrat/modules/medical/code/sprays.dm | 12 + .../modules/medical/code/wounds/muscle.dm | 19 +- .../code/wounds/synth/blunt/robotic_blunt.dm | 398 +++++++++++ .../wounds/synth/blunt/robotic_blunt_T1.dm | 65 ++ .../wounds/synth/blunt/robotic_blunt_T2.dm | 52 ++ .../wounds/synth/blunt/robotic_blunt_T3.dm | 385 +++++++++++ .../wounds/synth/blunt/secures_internals.dm | 388 +++++++++++ .../code/wounds/synth/robotic_burns.dm | 441 ++++++++++++ .../code/wounds/synth/robotic_muscle.dm | 47 ++ .../code/wounds/synth/robotic_pierce.dm | 146 ++++ .../code/wounds/synth/robotic_slash.dm | 628 ++++++++++++++++++ .../medical/code/wounds/wound_effects.dm | 33 + modular_skyrat/modules/medical/readme.md | 51 ++ .../medical/sound/robotic_slash_T1.ogg | Bin 0 -> 34541 bytes .../medical/sound/robotic_slash_T2.ogg | Bin 0 -> 50347 bytes .../medical/sound/robotic_slash_T3.ogg | Bin 0 -> 63099 bytes .../modules/modular_vending/code/wardrobes.dm | 3 + .../modules/synths/code/bodyparts/limbs.dm | 4 +- .../modules/synths/code/reagents/pill.dm | 6 +- .../modules/synths/code/species/synthetic.dm | 4 +- strings/wounds/metal_scar_desc.json | 67 ++ tgstation.dme | 13 + 33 files changed, 3018 insertions(+), 28 deletions(-) create mode 100644 modular_skyrat/modules/medical/attributions.txt create mode 100644 modular_skyrat/modules/medical/code/cargo/packs.dm create mode 100644 modular_skyrat/modules/medical/code/medkit.dm create mode 100644 modular_skyrat/modules/medical/code/sprays.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T1.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T2.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T3.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/synth/robotic_muscle.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/synth/robotic_pierce.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm create mode 100644 modular_skyrat/modules/medical/code/wounds/wound_effects.dm create mode 100644 modular_skyrat/modules/medical/readme.md create mode 100644 modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg create mode 100644 modular_skyrat/modules/medical/sound/robotic_slash_T2.ogg create mode 100644 modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg create mode 100644 strings/wounds/metal_scar_desc.json diff --git a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm index 957a669e53c..b9f9c542350 100644 --- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm +++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm @@ -1741,6 +1741,8 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/structure/table/reinforced, +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced/unzipped, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) "rQ" = ( diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm index 464498600fd..0e37692de27 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm @@ -1891,6 +1891,8 @@ /obj/effect/turf_decal/trimline/dark_blue/filled/line, /obj/effect/turf_decal/siding/dark, /obj/structure/extinguisher_cabinet/directional/west, +/obj/structure/table/glass, +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced/unzipped, /turf/open/floor/iron/white/diagonal, /area/ruin/space/has_grav/skyrat/interdynefob/medbay) "hZ" = ( diff --git a/code/__DEFINES/text.dm b/code/__DEFINES/text.dm index 751fe7c2b58..a0df5e24eb7 100644 --- a/code/__DEFINES/text.dm +++ b/code/__DEFINES/text.dm @@ -84,6 +84,10 @@ #define FLESH_SCAR_FILE "wounds/flesh_scar_desc.json" /// File location for bone wound descriptions #define BONE_SCAR_FILE "wounds/bone_scar_desc.json" +// SKYRAT EDIT ADDITION BEGIN - SYNTH WOUNDS +/// File location for metalic wound descriptions +#define METAL_SCAR_FILE "wounds/metal_scar_desc.json" +// SKYRAT EDIT ADDITION END /// File location for scar wound descriptions #define SCAR_LOC_FILE "wounds/scar_loc.json" /// File location for exodrone descriptions diff --git a/code/__DEFINES/wounds.dm b/code/__DEFINES/wounds.dm index 19ccd843dd4..14067fbcd6a 100644 --- a/code/__DEFINES/wounds.dm +++ b/code/__DEFINES/wounds.dm @@ -124,10 +124,15 @@ GLOBAL_LIST_INIT(bio_state_anatomy, list( /// Generic loss wounds. See loss.dm #define WOUND_SERIES_LOSS_BASIC "wound_series_loss_basic" -// SKYRAT EDIT ADDITION BEGIN - MUSCLE WOUNDS +// SKYRAT EDIT ADDITION BEGIN - MUSCLE AND SYNTH WOUNDS // Have to put it here so I can use it in the global list of wound series -/// See muscle.dm -#define WOUND_SERIES_MUSCLE_DAMAGE "skyrat_wound_series_muscle_damage" // We use a super high number as realistically speaking TG will never increment to this amount of wound series +/// See muscle.dm and robotic_blunt.dm +#define WOUND_SERIES_MUSCLE_DAMAGE "skyrat_wound_series_muscle_damage" + +#define WOUND_SERIES_METAL_BLUNT_BASIC "wound_series_metal_blunt_basic" +#define WOUND_SERIES_METAL_BURN_OVERHEAT "wound_series_metal_burn_basic" +#define WOUND_SERIES_WIRE_SLASH_ELECTRICAL_DAMAGE "wound_series_metal_slash_electrical_damage_basic" +#define WOUND_SERIES_WIRE_PIERCE_ELECTRICAL_DAMAGE "wound_series_metal_pierce_electrical_damage_basic" // SKYRAT EDIT ADDITION END /// A assoc list of (wound typepath -> wound_pregen_data instance). Every wound should have a pregen data. @@ -203,17 +208,23 @@ GLOBAL_LIST_INIT(wounding_types_to_series, list( WOUND_BLUNT = list( WOUND_SERIES_BONE_BLUNT_BASIC, WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT -- MUSCLE WOUNDS + WOUND_SERIES_METAL_BLUNT_BASIC, // SKYRAT EDIT ADDITION - SYNTH WOUNDS + ), WOUND_SLASH = list( WOUND_SERIES_FLESH_SLASH_BLEED, - WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT -- MUSCLE WOUNDS + WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT ADDITION - MUSCLE WOUNDS + WOUND_SERIES_WIRE_SLASH_ELECTRICAL_DAMAGE, // SKYRAT EDIT ADDITION - SYNTH WOUNDS + ), WOUND_BURN = list( WOUND_SERIES_FLESH_BURN_BASIC, + WOUND_SERIES_METAL_BURN_OVERHEAT, // SKYRAT EDIT ADDITION - SYNTH WOUNDS ), WOUND_PUNCTURE = list( WOUND_SERIES_FLESH_PUNCTURE_BLEED, - WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT -- MUSCLE WOUNDS + WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT ADDITION - MUSCLE WOUNDS + WOUND_SERIES_WIRE_PIERCE_ELECTRICAL_DAMAGE, // SKYRAT EDIT ADDITION - SYNTH WOUNDS ), )) @@ -284,7 +295,8 @@ GLOBAL_LIST_INIT(wounding_types_to_series, list( /// Assoc list of biotype -> ideal scar file to be used and grab stuff from. GLOBAL_LIST_INIT(biotypes_to_scar_file, list( "[BIO_FLESH]" = FLESH_SCAR_FILE, - "[BIO_BONE]" = BONE_SCAR_FILE + "[BIO_BONE]" = BONE_SCAR_FILE, + "[BIO_METAL]" = METAL_SCAR_FILE // SKYRAT EDIT ADDITION - METAL SCARS (see robotic_blunt.dm) )) // ~burn wound infection defines diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index 6e6fc6547e2..c34d97b28f9 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -15,7 +15,7 @@ GLOBAL_LIST_INIT_TYPED(quirk_blacklist, /list/datum/quirk, list( list(/datum/quirk/prosthetic_limb, /datum/quirk/quadruple_amputee, /datum/quirk/body_purist), list(/datum/quirk/prosthetic_organ, /datum/quirk/tin_man, /datum/quirk/body_purist), list(/datum/quirk/quadruple_amputee, /datum/quirk/paraplegic, /datum/quirk/hemiplegic), - list(/datum/quirk/quadruple_amputee, /datum/quirk/frail), + //list(/datum/quirk/quadruple_amputee, /datum/quirk/frail), // SKYRAT EDIT REMOVAL- Since we have synth wounds now, frail has a large downside for prosthetics and such list(/datum/quirk/social_anxiety, /datum/quirk/mute), list(/datum/quirk/mute, /datum/quirk/softspoken), list(/datum/quirk/poor_aim, /datum/quirk/bighands), diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 8cb32613da8..a51e9c3430e 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -479,8 +479,7 @@ var/immediately_stun = should_stun && !(flags & SHOCK_DELAY_STUN) if (immediately_stun) if (paralyze) - //Paralyze(40) - SKYRAT EDIT REMOVAL - StaminaKnockdown(10, TRUE) // SKYRAT EDIT ADDITION + StaminaKnockdown(stun_duration / 4) // SKYRAT EDIT CHANGE - ORIGINAL: Paralyze(40) else Knockdown(stun_duration) //Jitter and other fluff. @@ -494,8 +493,7 @@ ///Called slightly after electrocute act to apply a secondary stun. /mob/living/carbon/proc/secondary_shock(paralyze, stun_duration) if (paralyze) - //Paralyze(60) - SKYRAT EDIT REMOVAL - StaminaKnockdown(10, TRUE) //SKYRAT EDIT ADDITION + StaminaKnockdown(stun_duration / 6) // SKYRAT EDIT CHANGE - ORIGINAL: Paralyze(60) else Knockdown(stun_duration) diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index 53558cbd820..7cad082583d 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -203,14 +203,19 @@ inverse_chem = /datum/reagent/inverse/hercuri inverse_chem_val = 0.3 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC // SKYRAT EDIT ADDITION - Lets hercuri process in synths /datum/reagent/medicine/c2/hercuri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() var/need_mob_update - if(affected_mob.getFireLoss() > 50) - need_mob_update = affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) - else - need_mob_update = affected_mob.adjustFireLoss(-1.25 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) + // SKYRAT EDIT CHANGE BEGIN -- Adds check for owner_flags; indented the getFireLoss check and everything under it, so synths can get cooled down + var/owner_flags = affected_mob.dna.species.reagent_flags + if (owner_flags & PROCESS_ORGANIC) + if(affected_mob.getFireLoss() > 50) + need_mob_update = affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) + else + need_mob_update = affected_mob.adjustFireLoss(-1.25 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) + // SKYRAT EDIT CHANGE END affected_mob.adjust_bodytemperature(rand(-25,-5) * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50) if(ishuman(affected_mob)) var/mob/living/carbon/human/humi = affected_mob diff --git a/modular_skyrat/master_files/code/modules/jobs/job_types/roboticist.dm b/modular_skyrat/master_files/code/modules/jobs/job_types/roboticist.dm index d90c994c6ad..8c62f0a30f1 100644 --- a/modular_skyrat/master_files/code/modules/jobs/job_types/roboticist.dm +++ b/modular_skyrat/master_files/code/modules/jobs/job_types/roboticist.dm @@ -3,3 +3,19 @@ satchel = /obj/item/storage/backpack/satchel/science/robo duffelbag = /obj/item/storage/backpack/duffelbag/science/robo messenger = /obj/item/storage/backpack/messenger/science/robo + +/datum/job/roboticist + description = "Build cyborgs, mechs, AIs, and maintain them all. Create MODsuits for those that wish. Try to remind medical that you're \ + actually a lot better at treating synthetic crew members than them." + +/datum/job/roboticist/New() + . = ..() + + mail_goodies += list( + /obj/item/healthanalyzer/advanced = 15, + // if we decide later to let sci have access to the hand drill, let robos get it from here + /obj/item/storage/pill_bottle/liquid_solder = 6, + /obj/item/storage/pill_bottle/system_cleaner = 6, + /obj/item/storage/pill_bottle/nanite_slurry = 6, + /obj/item/reagent_containers/spray/hercuri/chilled = 8, + ) diff --git a/modular_skyrat/modules/medical/attributions.txt b/modular_skyrat/modules/medical/attributions.txt new file mode 100644 index 00000000000..f57c3fa0db5 --- /dev/null +++ b/modular_skyrat/modules/medical/attributions.txt @@ -0,0 +1,2 @@ +robotic_slash_T1.ogg, robotic_slash_T2.ogg, and robotic_slash_T3.ogg adapated from CGEffex's Bug Zapper2.wav (CC Attribution 4.0) +https://freesound.org/people/CGEffex/sounds/107004/ diff --git a/modular_skyrat/modules/medical/code/cargo/packs.dm b/modular_skyrat/modules/medical/code/cargo/packs.dm new file mode 100644 index 00000000000..0de1f24eb16 --- /dev/null +++ b/modular_skyrat/modules/medical/code/cargo/packs.dm @@ -0,0 +1,36 @@ +/datum/supply_pack/science/chilled_hercuri + name = "Chilled Hercuri Pack" + desc = "Contains 2 pre-chilled bottles of hercuri, 100u each. Useful for dealing with severely burnt synthetics!" + cost = CARGO_CRATE_VALUE * 2.5 + contains = list(/obj/item/reagent_containers/spray/hercuri/chilled = 2) + crate_name = "chilled hercuri crate" + + access_view = FALSE + access = FALSE + access_any = FALSE + +/datum/supply_pack/science/synth_treatment_kits + name = "Synthetic Treatment Kits" + desc = "Contains 2 treatment kits for synthetic lifeforms, filled with everything you need to treat an inorganic wound!" + cost = CARGO_CRATE_VALUE * 4.5 + contains = list(/obj/item/storage/backpack/duffelbag/synth_treatment_kit = 2) + crate_name = "synthetic treatment kits crate" + + access_view = FALSE + access = FALSE + access_any = FALSE + +/datum/supply_pack/science/synth_healing_chems + name = "Synthetic Medicine Pack" + desc = "Contains a variety of synthetic-exclusive medicine. 2 pill bottles of liquid solder, 2 of nanite slurry, 2 of system cleaner." + cost = CARGO_CRATE_VALUE * 7 // rarely made, so it should be expensive(?) + contains = list( + /obj/item/storage/pill_bottle/liquid_solder = 2, + /obj/item/storage/pill_bottle/nanite_slurry = 2, + /obj/item/storage/pill_bottle/system_cleaner = 2 + ) + crate_name = "synthetic medicine crate" + + access_view = FALSE + access = FALSE + access_any = FALSE diff --git a/modular_skyrat/modules/medical/code/medkit.dm b/modular_skyrat/modules/medical/code/medkit.dm new file mode 100644 index 00000000000..8ea40ae54bd --- /dev/null +++ b/modular_skyrat/modules/medical/code/medkit.dm @@ -0,0 +1,177 @@ +/obj/item/storage/backpack/duffelbag/synth_treatment_kit + name = "synthetic treatment kit" + desc = "A \"surgical\" duffel bag containing everything you need to treat the worst and best of inorganic wounds." + icon = 'modular_skyrat/master_files/icons/obj/clothing/backpacks.dmi' + worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/back.dmi' + lefthand_file = 'modular_skyrat/master_files/icons/mob/inhands/clothing/backpack_lefthand.dmi' + righthand_file = 'modular_skyrat/master_files/icons/mob/inhands/clothing/backpack_righthand.dmi' + icon_state = "duffel_robo" + inhand_icon_state = "duffel_robo" + +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/PopulateContents() // yes, this is all within the storage capacity + // Slash/Pierce wound tools - can reduce intensity of electrical damage (wires can fix generic burn damage) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/wirecutters(src) + // Blunt/Brute tools + new /obj/item/weldingtool/largetank(src) // Used for repairing blunt damage or heating metal at T3 blunt + new /obj/item/screwdriver(src) // Used for fixing T1 blunt or securing internals of T2/3 blunt + new /obj/item/bonesetter(src) + // Clothing items + new /obj/item/clothing/head/utility/welding(src) + new /obj/item/clothing/gloves/color/black(src) // Protects from T3 mold metal step + new /obj/item/clothing/glasses/hud/diagnostic(src) // When worn, generally improves wound treatment quality + // Reagent containers + new /obj/item/reagent_containers/spray/hercuri/chilled(src) // Highly effective (specifically coded to be) against burn wounds + // Generic medical items + new /obj/item/stack/medical/gauze/twelve(src) + new /obj/item/healthanalyzer(src) + new /obj/item/healthanalyzer/simple(src) // Buffs wound treatment and gives details of wounds it scans + // "Ghetto" tools, things you shouldnt ideally use but you might have to + new /obj/item/stack/medical/bone_gel(src) // Ghetto T2/3 option for securing internals + new /obj/item/plunger(src) // Can be used to mold heated metal at T3 + +// a treatment kit with extra space and more tools/upgraded tools, like a crowbar, insuls, a reinforced plunger, a crowbar and wrench +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma + name = "synthetic trauma kit" + desc = "A \"surgical\" duffel bag containing everything you need to treat the worst and best of inorganic wounds. This one has extra tools and space \ + for treatment of the WORST of the worst! However, it's highly specialized interior means it can ONLY hold synthetic repair tools." + storage_type = /datum/storage/duffel/synth_trauma_kit + +/datum/storage/duffel/synth_trauma_kit + exception_max = 6 + max_slots = 27 + max_total_storage = 35 + +/datum/storage/duffel/synth_trauma_kit/New(atom/parent, max_slots, max_specific_storage, max_total_storage, numerical_stacking, allow_quick_gather, allow_quick_empty, collection_mode, attack_hand_interact) + . = ..() + + var/static/list/exception_cache = typecacheof(list( + // Mainly just stacks, with the exception of pill bottles and sprays + /obj/item/stack/cable_coil, + /obj/item/stack/medical/gauze, + /obj/item/reagent_containers/spray, + /obj/item/stack/medical/bone_gel, + /obj/item/rcd_ammo, + /obj/item/storage/pill_bottle, + )) + + var/static/list/can_hold_list = list( + // Stacks + /obj/item/stack/cable_coil, + /obj/item/stack/medical/gauze, + /obj/item/stack/medical/bone_gel, + // Reagent containers, for synth medicine + /obj/item/reagent_containers/spray, + /obj/item/storage/pill_bottle, + /obj/item/reagent_containers/pill, + /obj/item/reagent_containers/cup, + /obj/item/reagent_containers/syringe, + // Tools, including tools you might not want to use but might have to (hemostat/retractor/etc) + /obj/item/screwdriver, + /obj/item/wrench, + /obj/item/crowbar, + /obj/item/weldingtool, + /obj/item/bonesetter, + /obj/item/wirecutters, + /obj/item/hemostat, + /obj/item/retractor, + /obj/item/cautery, + /obj/item/plunger, + // RCD stuff - RCDs can easily treat the 1st step of T3 blunt + /obj/item/construction/rcd, + /obj/item/rcd_ammo, + // Clothing items + /obj/item/clothing/gloves, + /obj/item/clothing/glasses/hud/health, + /obj/item/clothing/glasses/hud/diagnostic, + /obj/item/clothing/glasses/welding, + /obj/item/clothing/glasses/sunglasses, // still provides some welding protection + /obj/item/clothing/head/utility/welding, + /obj/item/clothing/mask/gas/welding, + // Generic health items + /obj/item/healthanalyzer, + ) + exception_hold = exception_cache + + // We keep the type list and the typecache list separate... + var/static/list/can_hold_cache = typecacheof(can_hold_list) + can_hold = can_hold_cache + + //...So we can run this without it generating a line for every subtype. + can_hold_description = generate_hold_desc(can_hold_list) + +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/PopulateContents() // yes, this is all within the storage capacity + // Slash/Pierce wound tools - can reduce intensity of electrical damage (wires can fix generic burn damage) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/wirecutters(src) + // Blunt/Brute tools + new /obj/item/weldingtool/hugetank(src) // Used for repairing blunt damage or heating metal at T3 blunt + new /obj/item/screwdriver(src) // Used for fixing T1 blunt or securing internals of T2/3 blunt + new /obj/item/wrench(src) // Same as screwdriver for T2/3 + new /obj/item/crowbar(src) // Ghetto fixing option for T2/3 blunt + new /obj/item/bonesetter(src) + // Clothing items + new /obj/item/clothing/head/utility/welding(src) + new /obj/item/clothing/gloves/color/black(src) // Protects from T3 mold metal step + new /obj/item/clothing/gloves/color/yellow(src) // Protects from electrical damage and crowbarring a blunt wound + new /obj/item/clothing/glasses/hud/diagnostic(src) // When worn, generally improves wound treatment quality + // Reagent containers + new /obj/item/reagent_containers/spray/hercuri/chilled(src) // Highly effective (specifically coded to be) against burn wounds + // Generic medical items + new /obj/item/stack/medical/gauze/twelve(src) + new /obj/item/healthanalyzer(src) + new /obj/item/healthanalyzer/simple(src) // Buffs wound treatment and gives details of wounds it scans + // "Ghetto" tools, things you shouldnt ideally use but you might have to + new /obj/item/stack/medical/bone_gel(src) // Ghetto T2/3 option for securing internals + new /obj/item/plunger/reinforced(src) // Can be used to mold heated metal at T3 + +// advanced tools, an RCD, chems, etc etc. dont give this one to the crew early in the round +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced + name = "advanced synth trauma kit" + desc = "An \"advanced\" \"surgical\" duffel bag containing absolutely everything you need to treat the worst and best of inorganic wounds. \ + This one has extra tools and space for treatment of the ones even worse than the WORST of the worst! However, its highly specialized interior \ + means it can ONLY hold synthetic repair tools." + + storage_type = /datum/storage/duffel/synth_trauma_kit/advanced + +/datum/storage/duffel/synth_trauma_kit/advanced + exception_max = 10 + max_slots = 31 + max_total_storage = 48 + +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced/PopulateContents() // yes, this is all within the storage capacity + // Slash/Pierce wound tools - can reduce intensity of electrical damage (wires can fix generic burn damage) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/crowbar/power(src) // jaws of life - wirecutters and crowbar + // Blunt/Brute tools + new /obj/item/weldingtool/experimental(src) // Used for repairing blunt damage or heating metal at T3 blunt + new /obj/item/screwdriver/power(src) // drill - screwdriver and wrench + new /obj/item/construction/rcd/loaded(src) // lets you instantly heal T3 blunt step 1 + new /obj/item/bonesetter(src) + // Clothing items + new /obj/item/clothing/head/utility/welding(src) + new /obj/item/clothing/gloves/combat(src) // insulated AND heat-resistant + new /obj/item/clothing/glasses/hud/diagnostic(src) // When worn, generally improves wound treatment quality + // Reagent containers + new /obj/item/reagent_containers/spray/hercuri/chilled(src) // Highly effective (specifically coded to be) against burn wounds + new /obj/item/reagent_containers/spray/hercuri/chilled(src) // 2 of them + new /obj/item/storage/pill_bottle/nanite_slurry(src) // Heals blunt/burn + new /obj/item/storage/pill_bottle/liquid_solder(src) // Heals brain damage + new /obj/item/storage/pill_bottle/system_cleaner(src) // Heals toxin damage and purges chems + // Generic medical items + new /obj/item/stack/medical/gauze/twelve(src) + new /obj/item/healthanalyzer/advanced(src) // advanced, not a normal analyzer + new /obj/item/healthanalyzer/simple(src) // Buffs wound treatment and gives details of wounds it scans + // "Ghetto" tools, things you shouldn't ideally use but you might have to + new /obj/item/stack/medical/bone_gel(src) // Ghetto T2/3 option for securing internals + new /obj/item/plunger/reinforced(src) // Can be used to mold heated metal at T3 blunt + +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced/unzipped + zipped_up = FALSE diff --git a/modular_skyrat/modules/medical/code/sprays.dm b/modular_skyrat/modules/medical/code/sprays.dm new file mode 100644 index 00000000000..8e2371e3f28 --- /dev/null +++ b/modular_skyrat/modules/medical/code/sprays.dm @@ -0,0 +1,12 @@ +/obj/item/reagent_containers/spray/hercuri/chilled + name = "chilled hercuri spray" // effective at cooling low-temperature burns but also is more efficienct at cooling high-temperature + desc = "A medical spray bottle. This one contains hercuri, a medicine used to negate the effects of dangerous high-temperature environments. \ + This one comes pre-chilled, making it especially good at cooling synthetic burns! \n\ + It has a bold warning label near the nozzle: ONLY USE IN EMERGENCIES! WILL CAUSE FREEZING! SECONDARY EFFECT ONLY USEFUL ON LIVING SYNTHS! INEFFECTIVE ON DECEASED! \n\ + There's a smaller warning label on the body of the spray: IN EVENT OF RUNAWAY ENDOTHERMY, APPLY SYSTEM CLEANER!" + var/starting_temperature = 100 + +/obj/item/reagent_containers/spray/hercuri/chilled/add_initial_reagents() + . = ..() + + reagents.chem_temp = starting_temperature diff --git a/modular_skyrat/modules/medical/code/wounds/muscle.dm b/modular_skyrat/modules/medical/code/wounds/muscle.dm index c1f9c3fc4c3..35cc54c7099 100644 --- a/modular_skyrat/modules/medical/code/wounds/muscle.dm +++ b/modular_skyrat/modules/medical/code/wounds/muscle.dm @@ -33,13 +33,14 @@ Overwriting of base procs */ /datum/wound/muscle/wound_injury(datum/wound/old_wound = null, attack_direction) - if(limb.held_index && victim.get_item_for_held_index(limb.held_index) && (disabling || prob(30 * severity))) - var/obj/item/I = victim.get_item_for_held_index(limb.held_index) - if(istype(I, /obj/item/offhand)) - I = victim.get_inactive_held_item() + var/obj/item/held_item = victim.get_item_for_held_index(limb.held_index || 0) + if(held_item && (disabling || prob(30 * severity))) + if(istype(held_item, /obj/item/offhand)) + held_item = victim.get_inactive_held_item() - if(I && victim.dropItemToGround(I)) - victim.visible_message(span_danger("[victim] drops [I] in shock!"), span_warning("The force on your [parse_zone(limb.body_zone)] causes you to drop [I]!"), vision_distance=COMBAT_MESSAGE_RANGE) + if(held_item && victim.dropItemToGround(held_item)) + victim.visible_message(span_danger("[victim] drops [held_item] in shock!"), \ + span_warning("The force on your [parse_zone(limb.body_zone)] causes you to drop [held_item]!"), vision_distance=COMBAT_MESSAGE_RANGE) return ..() @@ -173,3 +174,9 @@ id = "torn muscle" /datum/status_effect/wound/muscle/severe id = "ruptured tendon" + +/datum/status_effect/wound/muscle/robotic/moderate + id = "worn servo" + +/datum/status_effect/wound/muscle/robotic/severe + id = "severed hydraulic" diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm new file mode 100644 index 00000000000..52995365b01 --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm @@ -0,0 +1,398 @@ +/// The multiplier put against our movement effects if our victim has the determined reagent +#define ROBOTIC_WOUND_DETERMINATION_MOVEMENT_EFFECT_MOD 0.7 +/// The multiplier of stagger intensity on hit if our victim has the determined reagent +#define ROBOTIC_WOUND_DETERMINATION_STAGGER_MOVEMENT_MULT 0.7 + +/// The multiplier put against our movement effects if our limb is grasped +#define ROBOTIC_BLUNT_GRASPED_MOVEMENT_MULT 0.7 + +/datum/wound/blunt/robotic + name = "Robotic Blunt (Screws and bolts) Wound" + wound_flags = (ACCEPTS_GAUZE|SPLINT_OVERLAY|CAN_BE_GRASPED) + + default_scar_file = METAL_SCAR_FILE + + /// If we suffer severe head booboos, we can get brain traumas tied to them + var/datum/brain_trauma/active_trauma + /// What brain trauma group, if any, we can draw from for head wounds + var/brain_trauma_group + /// If we deal brain traumas, when is the next one due? + var/next_trauma_cycle + /// How long do we wait +/- 20% for the next trauma? + var/trauma_cycle_cooldown + + /// The ratio stagger score will be multiplied against for determining the final chance of moving away from the attacker. + var/stagger_movement_chance_ratio = 1 + /// The ratio stagger score will be multiplied against for determining the amount of pixelshifting we will do when we are hit. + var/stagger_shake_shift_ratio = 0.05 + + /// The ratio of stagger score to shake duration during a stagger() call + var/stagger_score_to_shake_duration_ratio = 0.1 + + /// In the stagger aftershock, the stagger score will be multiplied against for determining the chance of dropping held items. + var/stagger_drop_chance_ratio = 1.25 + /// In the stagger aftershock, the stagger score will be multiplied against for determining the chance of falling over. + var/stagger_fall_chance_ratio = 1 + + /// In the stagger aftershock, the stagger score will be multiplied against for determining how long we are knocked down for. + var/stagger_aftershock_knockdown_ratio = 0.5 + /// In the stagger after shock, the stagger score will be multiplied against this (if caused by movement) for determining how long we are knocked down for. + var/stagger_aftershock_knockdown_movement_ratio = 0.1 + + /// If the victim stops moving before the aftershock, aftershock effects will be multiplied against this. + var/aftershock_stopped_moving_score_mult = 0.1 + + /// The ratio damage applied will be multiplied against for determining our stagger score. + var/chest_attacked_stagger_mult = 2.5 + /// The minimum score an attack must do to trigger a stagger. + var/chest_attacked_stagger_minimum_score = 5 + /// The ratio of damage to stagger chance on hit. + var/chest_attacked_stagger_chance_ratio = 2 + + /// The base score given to stagger() when we successfully stagger on a move. + var/base_movement_stagger_score = 30 + /// The base chance of moving to trigger stagger(). + var/chest_movement_stagger_chance = 1 + + /// The base duration of a stagger()'s sprite shaking. + var/base_stagger_shake_duration = 1.5 SECONDS + /// The base duration of a stagger()'s sprite shaking if caused by movement. + var/base_stagger_movement_shake_duration = 1.5 SECONDS + + /// The ratio of stagger score to camera shake chance. + var/stagger_camera_shake_chance_ratio = 0.75 + /// The base duration of a stagger's aftershock's camerashake. + var/base_aftershock_camera_shake_duration = 1.5 SECONDS + /// The base strength of a stagger's aftershock's camerashake. + var/base_aftershock_camera_shake_strength = 0.5 + + /// The amount of x and y pixels we will be shaken around by during a movement stagger. + var/movement_stagger_shift = 1 + + /// If we are currently oscillating. If true, we cannot stagger(). + var/oscillating = FALSE + + /// % chance for hitting our limb to fix something. + var/percussive_maintenance_repair_chance = 10 + /// Damage must be under this to proc percussive maintenance. + var/percussive_maintenance_damage_max = 7 + /// Damage must be over this to proc percussive maintenance. + var/percussive_maintenance_damage_min = 0 + + /// The time, in world time, that we will be allowed to do another movement shake. Useful because it lets us prioritize attacked shakes over movement shakes. + var/time_til_next_movement_shake_allowed = 0 + + /// The percent our limb must get to max possible damage by burn damage alone to count as malleable if it has no T2 burn wound. + var/limb_burn_percent_to_max_threshold_for_malleable = 0.8 // must be 75% to max damage by burn damage alone + + /// The last time our victim has moved. Used for determining if we should increase or decrease the chance of having stagger aftershock. + var/last_time_victim_moved = 0 + + processes = TRUE + +/datum/wound_pregen_data/blunt_metal + abstract = TRUE + required_limb_biostate = BIO_METAL + wound_series = WOUND_SERIES_METAL_BLUNT_BASIC + required_wounding_types = list(WOUND_BLUNT) + +/datum/wound_pregen_data/blunt_metal/generate_scar_priorities() + return list("[BIO_METAL]") + +/datum/wound/blunt/robotic/set_victim(new_victim) + if(victim) + UnregisterSignal(victim, COMSIG_MOVABLE_MOVED) + UnregisterSignal(victim, COMSIG_MOB_AFTER_APPLY_DAMAGE) + if(new_victim) + RegisterSignal(new_victim, COMSIG_MOVABLE_MOVED, PROC_REF(victim_moved)) + RegisterSignal(new_victim, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(victim_attacked)) + + return ..() + +/datum/wound/blunt/robotic/get_limb_examine_description() + return span_warning("This limb looks loosely held together.") + +// this wound is unaffected by cryoxadone and pyroxadone +/datum/wound/blunt/robotic/on_xadone(power) + return + +/datum/wound/blunt/robotic/wound_injury(datum/wound/old_wound, attack_direction) + . = ..() + + // hook into gaining/losing gauze so crit bone wounds can re-enable/disable depending if they're slung or not + if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group) + processes = TRUE + active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND) + next_trauma_cycle = world.time + (rand(100-WOUND_BONE_HEAD_TIME_VARIANCE, 100+WOUND_BONE_HEAD_TIME_VARIANCE) * 0.01 * trauma_cycle_cooldown) + + var/obj/item/held_item = victim.get_item_for_held_index(limb.held_index || 0) + if(held_item && (disabling || prob(30 * severity))) + if(istype(held_item, /obj/item/offhand)) + held_item = victim.get_inactive_held_item() + if(held_item && victim.dropItemToGround(held_item)) + victim.visible_message(span_danger("[victim] drops [held_item] in shock!"), span_warning("The force on your [limb.plaintext_zone] causes you to drop [held_item]!"), vision_distance=COMBAT_MESSAGE_RANGE) + +/datum/wound/blunt/robotic/remove_wound(ignore_limb, replaced) + . = ..() + + QDEL_NULL(active_trauma) + +/datum/wound/blunt/robotic/handle_process(seconds_per_tick, times_fired) + . = ..() + + if (!victim || IS_IN_STASIS(victim)) + return + + if (limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle) + if (active_trauma) + QDEL_NULL(active_trauma) + else + active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND) + next_trauma_cycle = world.time + (rand(100-WOUND_BONE_HEAD_TIME_VARIANCE, 100+WOUND_BONE_HEAD_TIME_VARIANCE) * 0.01 * trauma_cycle_cooldown) + +/// If true, allows our superstructure to be modified if we are T3. RCDs can always fix our superstructure. +/datum/wound/blunt/robotic/proc/limb_malleable() + if (!isnull(get_overheat_wound())) + return TRUE + var/burn_damage_to_max = (limb.burn_dam / limb.max_damage) // only exists for the weird case where it cant get a overheat wound + if (burn_damage_to_max >= limb_burn_percent_to_max_threshold_for_malleable) + return TRUE + return FALSE + +/// If we have one, returns a robotic overheat wound of severe severity or higher. Null otherwise. +/datum/wound/blunt/robotic/proc/get_overheat_wound() + RETURN_TYPE(/datum/wound/burn/robotic/overheat) + for (var/datum/wound/found_wound as anything in limb.wounds) + var/datum/wound_pregen_data/pregen_data = found_wound.get_pregen_data() + if (pregen_data.wound_series == WOUND_SERIES_METAL_BURN_OVERHEAT && found_wound.severity >= WOUND_SEVERITY_SEVERE) // meh solution but whateva + return found_wound + return null + +/// If our victim is lying down and is attacked in the chest, effective oscillation damage is multiplied against this. +#define OSCILLATION_ATTACKED_LYING_DOWN_EFFECT_MULT 0.5 + +/// If the attacker is wearing a diag hud, chance of percussive maintenance succeeding is multiplied against this. +#define PERCUSSIVE_MAINTENANCE_DIAG_HUD_CHANCE_MULT 1.5 +/// If our wound has been scanned by a wound analyzer, chance of percussive maintenance succeeding is multiplied against this. +#define PERCUSSIVE_MAINTENANCE_WOUND_SCANNED_CHANCE_MULT 1.5 +/// If the attacker is NOT our victim, chance of percussive maintenance succeeding is multiplied against this. +#define PERCUSSIVE_MAINTENANCE_ATTACKER_NOT_VICTIM_CHANCE_MULT 2.5 + +/// Signal handler proc to when our victim has damage applied via apply_damage(), which is a external attack. +/datum/wound/blunt/robotic/proc/victim_attacked(datum/source, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item) + SIGNAL_HANDLER + + if (def_zone != limb.body_zone) // use this proc since receive damage can also be called for like, chems and shit + return + if(!victim) + return + + var/effective_damage = (damage - blocked) + + var/obj/item/stack/gauze = limb.current_gauze + if(gauze) + effective_damage *= gauze.splint_factor + + switch (limb.body_zone) + + if(BODY_ZONE_CHEST) + var/oscillation_mult = 1 + if (victim.body_position == LYING_DOWN) + oscillation_mult *= OSCILLATION_ATTACKED_LYING_DOWN_EFFECT_MULT + var/oscillation_damage = effective_damage + var/stagger_damage = oscillation_damage * chest_attacked_stagger_mult + if (victim.has_status_effect(/datum/status_effect/determined)) + oscillation_damage *= ROBOTIC_WOUND_DETERMINATION_STAGGER_MOVEMENT_MULT + if ((stagger_damage >= chest_attacked_stagger_minimum_score) && prob(oscillation_damage * chest_attacked_stagger_chance_ratio)) + stagger(stagger_damage * oscillation_mult, attack_direction, attacking_item, shift = stagger_damage * stagger_shake_shift_ratio) + + if(!uses_percussive_maintenance() || damage < percussive_maintenance_damage_min || damage > percussive_maintenance_damage_max || damagetype != BRUTE || sharpness) + return + var/success_chance_mult = 1 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + success_chance_mult *= PERCUSSIVE_MAINTENANCE_WOUND_SCANNED_CHANCE_MULT + var/mob/living/user + if (isatom(attacking_item)) + var/atom/attacking_atom = attacking_item + user = attacking_atom.loc // nullable + + if (istype(user)) + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + success_chance_mult *= PERCUSSIVE_MAINTENANCE_DIAG_HUD_CHANCE_MULT + + if (user != victim) + success_chance_mult *= PERCUSSIVE_MAINTENANCE_ATTACKER_NOT_VICTIM_CHANCE_MULT // encourages people to get other people to beat the shit out of their limbs + if (prob(percussive_maintenance_repair_chance * success_chance_mult)) + handle_percussive_maintenance_success(attacking_item, user) + else + handle_percussive_maintenance_failure(attacking_item, user) + +#undef OSCILLATION_ATTACKED_LYING_DOWN_EFFECT_MULT +#undef PERCUSSIVE_MAINTENANCE_DIAG_HUD_CHANCE_MULT +#undef PERCUSSIVE_MAINTENANCE_WOUND_SCANNED_CHANCE_MULT +#undef PERCUSSIVE_MAINTENANCE_ATTACKER_NOT_VICTIM_CHANCE_MULT + +/// The percent, in decimal, of a stagger's shake() duration, that will be used in a addtimer() to queue aftershock(). +#define STAGGER_PERCENT_OF_SHAKE_DURATION_TO_AFTERSHOCK_DELAY 0.65 // 1 = happens at the end, .5 = happens halfway through + +/// Causes an oscillation, which 1. has a chance to move our victim away from the attacker, and 2. after a delay, calls aftershock(). +/datum/wound/blunt/robotic/proc/stagger(stagger_score, attack_direction, obj/item/attacking_item, from_movement, shake_duration = base_stagger_shake_duration, shift, knockdown_ratio = stagger_aftershock_knockdown_ratio) + if (oscillating) + return + + var/self_message = "Your [limb.plaintext_zone] oscillates" + var/message = "[victim]'s [limb.plaintext_zone] oscillates" + if (attacking_item) + message += " from the impact" + else if (from_movement) + message += " from the movement" + message += "!" + self_message += "! You might be able to avoid an aftershock by stopping and waiting..." + + if (isnull(attack_direction)) + attack_direction = get_dir(victim, attacking_item) + + if (!isnull(attack_direction) && prob(stagger_score * stagger_movement_chance_ratio)) + to_chat(victim, span_warning("The force of the blow sends you reeling!")) + var/turf/target_loc = get_step(victim, attack_direction) + victim.Move(target_loc) + + victim.visible_message(span_warning(message), ignored_mobs = victim) + to_chat(victim, span_warning(self_message)) + victim.balloon_alert(victim, "oscillation! stop moving") + + victim.Shake(pixelshiftx = shift, pixelshifty = shift, duration = shake_duration) + var/aftershock_delay = (shake_duration * STAGGER_PERCENT_OF_SHAKE_DURATION_TO_AFTERSHOCK_DELAY) + var/knockdown_time = stagger_score * knockdown_ratio + addtimer(CALLBACK(src, PROC_REF(aftershock), stagger_score, attack_direction, attacking_item, world.time, knockdown_time), aftershock_delay) + oscillating = TRUE + +#undef STAGGER_PERCENT_OF_SHAKE_DURATION_TO_AFTERSHOCK_DELAY + +#define AFTERSHOCK_GRACE_THRESHOLD_PERCENT 0.33 // lower mult = later grace period = more forgiving + +/** + * Timer proc from stagger(). + * + * Based on chance, causes items to be dropped, knockdown to be applied, and/or screenshake to occur. + * Chance is massively reduced if the victim isn't moving. + */ +/datum/wound/blunt/robotic/proc/aftershock(stagger_score, attack_direction, obj/item/attacking_item, stagger_starting_time, knockdown_time) + if (!still_exists()) + return FALSE + + var/message = "The oscillations from your [limb.plaintext_zone] spread, " + var/limb_message = "causing " + var/limb_affected + + var/stopped_moving_grace_threshold = (world.time - ((world.time - stagger_starting_time) * AFTERSHOCK_GRACE_THRESHOLD_PERCENT)) + var/victim_stopped_moving = (last_time_victim_moved <= stopped_moving_grace_threshold) + if (victim_stopped_moving) + stagger_score *= aftershock_stopped_moving_score_mult + + if (prob(stagger_score * stagger_drop_chance_ratio)) + limb_message += "your hands" + victim.drop_all_held_items() + limb_affected = TRUE + + if (prob(stagger_score * stagger_fall_chance_ratio)) + if (limb_affected) + limb_message += " and " + limb_message += "your legs" + victim.Knockdown(knockdown_time) + limb_affected = TRUE + + if (prob(stagger_score * stagger_camera_shake_chance_ratio)) + if (limb_affected) + limb_message += " and " + limb_message += "your head" + shake_camera(victim, base_aftershock_camera_shake_duration, base_aftershock_camera_shake_strength) + limb_affected = TRUE + + if (limb_affected) + message += "[limb_message] to shake uncontrollably!" + else + message += "but pass harmlessly" + if (victim_stopped_moving) + message += " thanks to your stillness" + message += "." + + to_chat(victim, span_danger(message)) + victim.balloon_alert(victim, "oscillation over") + + oscillating = FALSE + +#undef AFTERSHOCK_GRACE_THRESHOLD_PERCENT + +/// Called when percussive maintenance succeeds at its random roll. +/datum/wound/blunt/robotic/proc/handle_percussive_maintenance_success(attacking_item, mob/living/user) + victim.visible_message(span_green("[victim]'s [limb.plaintext_zone] rattles from the impact, but looks a lot more secure!"), \ + span_green("Your [limb.plaintext_zone] rattles into place!")) + remove_wound() + +/// Called when percussive maintenance fails at its random roll. +/datum/wound/blunt/robotic/proc/handle_percussive_maintenance_failure(attacking_item, mob/living/user) + to_chat(victim, span_warning("Your [limb.plaintext_zone] rattles around, but you don't sense any sign of improvement.")) + +/// If our victim has no gravity, the effects of movement are multiplied by this. +#define VICTIM_MOVED_NO_GRAVITY_EFFECT_MULT 0.5 +/// If our victim is resting, or is walking and isnt forced to move, the effects of movement are multiplied by this. +#define VICTIM_MOVED_CAREFULLY_EFFECT_MULT 0.25 + +/// Signal handler proc that applies movements affect to our victim if they were moved. +/datum/wound/blunt/robotic/proc/victim_moved(datum/source, atom/old_loc, dir, forced, list/old_locs) + SIGNAL_HANDLER + + var/overall_mult = 1 + + var/obj/item/stack/gauze = limb.current_gauze + if (gauze) + overall_mult *= gauze.splint_factor + if (!victim.has_gravity(get_turf(victim))) + overall_mult *= VICTIM_MOVED_NO_GRAVITY_EFFECT_MULT + else if (victim.body_position == LYING_DOWN || (!forced && victim.move_intent == MOVE_INTENT_WALK)) + overall_mult *= VICTIM_MOVED_CAREFULLY_EFFECT_MULT + if (victim.has_status_effect(/datum/status_effect/determined)) + overall_mult *= ROBOTIC_WOUND_DETERMINATION_MOVEMENT_EFFECT_MOD + if (limb.grasped_by) + overall_mult *= ROBOTIC_BLUNT_GRASPED_MOVEMENT_MULT + + overall_mult *= get_buckled_movement_consequence_mult(victim.buckled) + + if (limb.body_zone == BODY_ZONE_CHEST) + var/stagger_chance = chest_movement_stagger_chance * overall_mult + if (prob(stagger_chance)) + stagger(base_movement_stagger_score, shake_duration = base_stagger_movement_shake_duration, from_movement = TRUE, shift = movement_stagger_shift, knockdown_ratio = stagger_aftershock_knockdown_movement_ratio) + + last_time_victim_moved = world.time + +#undef VICTIM_MOVED_NO_GRAVITY_EFFECT_MULT +#undef VICTIM_MOVED_CAREFULLY_EFFECT_MULT + +/// If our victim is buckled to a generic object, movement effects will be multiplied against this. +#define VICTIM_BUCKLED_BASE_MOVEMENT_EFFECT_MULT 0.5 +/// If our victim is buckled to a medical bed (e.g. rollerbed), movement effects will be multiplied against this. +#define VICTIM_BUCKLED_ROLLER_BED_MOVEMENT_EFFECT_MULT 0.05 + +/// Returns a multiplier to our movement effects based on what our victim is buckled to. +/datum/wound/blunt/robotic/proc/get_buckled_movement_consequence_mult(atom/movable/buckled_to) + if (!buckled_to) + return 1 + + if (istype(buckled_to, /obj/structure/bed/medical)) + return VICTIM_BUCKLED_ROLLER_BED_MOVEMENT_EFFECT_MULT + else + return VICTIM_BUCKLED_BASE_MOVEMENT_EFFECT_MULT + +#undef VICTIM_BUCKLED_BASE_MOVEMENT_EFFECT_MULT +#undef VICTIM_BUCKLED_ROLLER_BED_MOVEMENT_EFFECT_MULT + +/// If this wound can be treated in its current state by just hitting it with a low force object. Exists for conditional logic, e.g. "Should we respond +/// to percussive maintenance right now?". Critical blunt uses this to only react when the limb is malleable and superstructure is broken. +/datum/wound/blunt/robotic/proc/uses_percussive_maintenance() + return FALSE + +#undef ROBOTIC_WOUND_DETERMINATION_MOVEMENT_EFFECT_MOD +#undef ROBOTIC_WOUND_DETERMINATION_STAGGER_MOVEMENT_MULT + +#undef ROBOTIC_BLUNT_GRASPED_MOVEMENT_MULT diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T1.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T1.dm new file mode 100644 index 00000000000..9cd2ae0adbb --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T1.dm @@ -0,0 +1,65 @@ +/datum/wound/blunt/robotic/moderate + name = "Loosened Screws" + desc = "Various semi-external fastening instruments have loosened, causing components to jostle, inhibiting limb control." + treat_text = "Recommend topical re-fastening of instruments with a screwdriver, though percussive maintenance via low-force bludgeoning may suffice - \ + albeit at risk of worsening the injury." + examine_desc = "appears to be loosely secured" + occur_text = "jostles awkwardly and seems to slightly unfasten" + severity = WOUND_SEVERITY_MODERATE + simple_treat_text = "Bandaging the wound will reduce the impact until it's screws are secured - which is faster if done by \ + someone else, a roboticist, an engineer, or with a diagnostic HUD." + homemade_treat_text = "In a pinch, percussive maintenance can reset the screws - the chance of which is increased if done by someone else or \ + with a diagnostic HUD!" + status_effect_type = /datum/status_effect/wound/blunt/robotic/moderate + treatable_tools = list(TOOL_SCREWDRIVER) + interaction_efficiency_penalty = 1.2 + limp_slowdown = 2.5 + limp_chance = 30 + threshold_penalty = 20 + can_scar = FALSE + a_or_from = "from" + +/datum/wound_pregen_data/blunt_metal/loose_screws + abstract = FALSE + wound_path_to_generate = /datum/wound/blunt/robotic/moderate + viable_zones = list(BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + threshold_minimum = 30 + +/datum/wound/blunt/robotic/moderate/uses_percussive_maintenance() + return TRUE + +/datum/wound/blunt/robotic/moderate/treat(obj/item/potential_treater, mob/user) + if (potential_treater.tool_behaviour == TOOL_SCREWDRIVER) + fasten_screws(potential_treater, user) + return TRUE + + return ..() + +/// The main treatment for T1 blunt. Uses a screwdriver, guaranteed to always work, better with a diag hud. Removes the wound. +/datum/wound/blunt/robotic/moderate/proc/fasten_screws(obj/item/screwdriver_tool, mob/user) + if (!screwdriver_tool.tool_start_check()) + return + + var/delay_mult = 1 + + if (user == victim) + delay_mult *= 3 + + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + delay_mult *= 0.5 + + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.5 + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + victim.visible_message(span_notice("[user] begins fastening the screws of [their_or_other] [limb.plaintext_zone]..."), \ + span_notice("You begin fastening the screws of [your_or_other] [limb.plaintext_zone]...")) + + if (!screwdriver_tool.use_tool(target = victim, user = user, delay = (10 SECONDS * delay_mult), volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return + + victim.visible_message(span_green("[user] finishes fastening [their_or_other] [limb.plaintext_zone]!"), \ + span_green("You finish fastening [your_or_other] [limb.plaintext_zone]!")) + + remove_wound() diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T2.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T2.dm new file mode 100644 index 00000000000..68bac1fe12b --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T2.dm @@ -0,0 +1,52 @@ +/datum/wound/blunt/robotic/secures_internals/severe + name = "Detached Fastenings" + desc = "Various fastening devices are extremely loose and solder has disconnected at multiple points, causing significant jostling of internal components and \ + noticable limb dysfunction." + treat_text = "Fastening of bolts and screws by a qualified technician (though bone gel may suffice in the absence of one) followed by re-soldering." + examine_desc = "jostles with every move, solder visibly broken" + occur_text = "visibly cracks open, solder flying everywhere" + severity = WOUND_SEVERITY_SEVERE + + simple_treat_text = "If on the chest, walk, grasp it, splint, rest or buckle yourself to something to reduce movement effects. \ + Afterwards, get someone else, ideally a robo/engi to screwdriver/wrench it, and then re-solder it!" + homemade_treat_text = "If unable to screw/wrench, bone gel can, over time, secure inner components at risk of corrossion. \ + Alternatively, crowbar the limb open to expose the internals - this will make it easier to re-secure them, but has a high risk of shocking you, \ + so use insulated gloves. This will cripple the limb, so use it only as a last resort!" + + wound_flags = (ACCEPTS_GAUZE|MANGLES_EXTERIOR|SPLINT_OVERLAY|CAN_BE_GRASPED) + treatable_by = list(/obj/item/stack/medical/bone_gel) + status_effect_type = /datum/status_effect/wound/blunt/robotic/severe + treatable_tools = list(TOOL_WELDER, TOOL_CROWBAR) + + interaction_efficiency_penalty = 2 + limp_slowdown = 6 + limp_chance = 60 + + brain_trauma_group = BRAIN_TRAUMA_MILD + trauma_cycle_cooldown = 1.5 MINUTES + + threshold_penalty = 40 + + base_movement_stagger_score = 40 + + chest_attacked_stagger_chance_ratio = 5 + chest_attacked_stagger_mult = 3 + + chest_movement_stagger_chance = 3 + + stagger_aftershock_knockdown_ratio = 0.3 + stagger_aftershock_knockdown_movement_ratio = 0.2 + + a_or_from = "from" + + ready_to_secure_internals = TRUE + ready_to_resolder = FALSE + + scar_keyword = "bluntsevere" + +/datum/wound_pregen_data/blunt_metal/fastenings + abstract = FALSE + + wound_path_to_generate = /datum/wound/blunt/robotic/secures_internals/severe + + threshold_minimum = 65 diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T3.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T3.dm new file mode 100644 index 00000000000..aa85498108a --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T3.dm @@ -0,0 +1,385 @@ +/datum/wound/blunt/robotic/secures_internals/critical + name = "Collapsed Superstructure" + desc = "The superstructure has totally collapsed in one or more locations, causing extreme internal oscillation with every move and massive limb dysfunction" + treat_text = "Reforming of superstructure via either RCD or manual molding, followed by typical treatment of loosened internals. \ + To manually mold, the limb must be aggressively grabbed and welded held to it to make it malleable (though attacking it til thermal overload may be adequate) \ + followed by firmly grasping and molding the limb with heat-resistant gloves." + occur_text = "caves in on itself, damaged solder and shrapnel flying out in a miniature explosion" + examine_desc = "has caved in, with internal components visible through gaps in the metal" + severity = WOUND_SEVERITY_CRITICAL + + disabling = TRUE + + simple_treat_text = "If on the chest, walk, grasp it, splint, rest or buckle yourself to something to reduce movement effects. \ + Afterwards, get someone, ideally a robo/engi to firmly grasp the limb and hold a welder to it. Then, have them use their hands to mold the metal - \ + careful though, it's hot! An RCD can skip all this, but is hard to come by. Afterwards, have them screw/wrench and then re-solder the limb!" + + homemade_treat_text = "The metal can be made malleable by repeated application of a welder, to a severe burn. Afterwards, a plunger can reset the metal, \ + as can percussive maintenance. After the metal is reset, if unable to screw/wrench, bone gel can, over time, secure inner components at risk of corrossion. \ + Alternatively, crowbar the limb open to expose the internals - this will make it easier to re-secure them, but has a high risk of shocking you, \ + so use insulated gloves. This will cripple the limb, so use it only as a last resort!" + + interaction_efficiency_penalty = 2.8 + limp_slowdown = 8 + limp_chance = 80 + threshold_penalty = 60 + + brain_trauma_group = BRAIN_TRAUMA_SEVERE + trauma_cycle_cooldown = 2.5 MINUTES + + scar_keyword = "bluntcritical" + + status_effect_type = /datum/status_effect/wound/blunt/robotic/critical + + sound_effect = 'sound/effects/wounds/crack2.ogg' + + wound_flags = (ACCEPTS_GAUZE|MANGLES_EXTERIOR|SPLINT_OVERLAY|CAN_BE_GRASPED) + treatable_by = list(/obj/item/stack/medical/bone_gel) + status_effect_type = /datum/status_effect/wound/blunt/robotic/critical + treatable_tools = list(TOOL_WELDER, TOOL_CROWBAR) + + base_movement_stagger_score = 55 + + base_aftershock_camera_shake_duration = 1.75 SECONDS + base_aftershock_camera_shake_strength = 1 + + chest_attacked_stagger_chance_ratio = 6.5 + chest_attacked_stagger_mult = 4 + + chest_movement_stagger_chance = 14 + + aftershock_stopped_moving_score_mult = 0.3 + + stagger_aftershock_knockdown_ratio = 0.5 + stagger_aftershock_knockdown_movement_ratio = 0.3 + + percussive_maintenance_repair_chance = 3 + percussive_maintenance_damage_max = 6 + + regen_time_needed = 60 SECONDS + gel_damage = 20 + + ready_to_secure_internals = FALSE + ready_to_resolder = FALSE + + a_or_from = "a" + + /// Has the first stage of our treatment been completed? E.g. RCDed, manually molded... + var/superstructure_remedied = FALSE + +/datum/wound_pregen_data/blunt_metal/superstructure + abstract = FALSE + wound_path_to_generate = /datum/wound/blunt/robotic/secures_internals/critical + threshold_minimum = 125 + +/datum/wound/blunt/robotic/secures_internals/critical/item_can_treat(obj/item/potential_treater) + if(!superstructure_remedied) + if(istype(potential_treater, /obj/item/construction/rcd)) + return TRUE + if(limb_malleable() && istype(potential_treater, /obj/item/plunger)) + return TRUE + return ..() + +/datum/wound/blunt/robotic/secures_internals/critical/check_grab_treatments(obj/item/potential_treater, mob/user) + if(potential_treater.tool_behaviour == TOOL_WELDER && (!superstructure_remedied && !limb_malleable())) + return TRUE + return ..() + +/datum/wound/blunt/robotic/secures_internals/critical/treat(obj/item/item, mob/user) + if(!superstructure_remedied) + if(istype(item, /obj/item/construction/rcd)) + return rcd_superstructure(item, user) + if(uses_percussive_maintenance() && istype(item, /obj/item/plunger)) + return plunge(item, user) + if(item.tool_behaviour == TOOL_WELDER && !limb_malleable() && isliving(victim.pulledby)) + var/mob/living/living_puller = victim.pulledby + if (living_puller.grab_state >= GRAB_AGGRESSIVE) // only let other people do this + return heat_metal(item, user) + return ..() + +/datum/wound/blunt/robotic/secures_internals/critical/try_handling(mob/living/carbon/human/user) + if(user.pulling != victim || user.zone_selected != limb.body_zone) + return FALSE + + if(superstructure_remedied || !limb_malleable()) + return FALSE + + if(user.grab_state < GRAB_AGGRESSIVE) + to_chat(user, span_warning("You must have [victim] in an aggressive grab to manipulate [victim.p_their()] [lowertext(name)]!")) + return TRUE + + user.visible_message(span_danger("[user] begins softly pressing against [victim]'s collapsed [limb.plaintext_zone]..."), \ + span_notice("You begin softly pressing against [victim]'s collapsed [limb.plaintext_zone]..."), \ + ignored_mobs = victim) + to_chat(victim, span_userdanger("[user] begins pressing against your collapsed [limb.plaintext_zone]!")) + + var/delay_mult = 1 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + if(!do_after(user, 8 SECONDS, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return + mold_metal(user) + return TRUE + +/// If the user turns combat mode on after they start to mold metal, our limb takes this much brute damage. +#define MOLD_METAL_SABOTAGE_BRUTE_DAMAGE 30 // really punishing +/// Our limb takes this much brute damage on a failed mold metal attempt. +#define MOLD_METAL_FAILURE_BRUTE_DAMAGE 5 +/// If the user's hand is unprotected from heat when they mold metal, we do this much burn damage to it. +#define MOLD_METAL_HAND_BURNT_BURN_DAMAGE 5 +/// Gloves must be above or at this threshold to cause the user to not be burnt apon trying to mold metal. +#define MOLD_METAL_HEAT_RESISTANCE_THRESHOLD 1000 // less than the black gloves max resist +/** + * Standard treatment for 1st step of T3, after the limb has been made malleable. Done via aggrograb. + * High chance to work, very high with robo/engi wires and diag hud. + * Can be sabotaged by switching to combat mode. + * Deals brute to the limb on failure. + * Burns the hand of the user if its not insulated. + */ +/datum/wound/blunt/robotic/secures_internals/critical/proc/mold_metal(mob/living/carbon/human/user) + var/chance = 60 + + var/knows_wires = FALSE + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + chance *= 2 + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + chance *= 1.25 + knows_wires = TRUE + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + chance *= 2 + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + chance *= 1.25 + else + chance *= 2 + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + + if ((user != victim && user.combat_mode)) + user.visible_message(span_bolddanger("[user] molds [their_or_other] [limb.plaintext_zone] into a really silly shape! What a goofball!"), \ + span_danger("You maliciously mold [victim]'s [limb.plaintext_zone] into a weird shape, damaging it in the process!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[user] molds your [limb.plaintext_zone] into a weird shape, damaging it in the process!")) + + limb.receive_damage(brute = MOLD_METAL_SABOTAGE_BRUTE_DAMAGE, wound_bonus = CANT_WOUND, damage_source = user) + else if (prob(chance)) + user.visible_message(span_green("[user] carefully molds [their_or_other] [limb.plaintext_zone] into the proper shape!"), \ + span_green("You carefully mold [victim]'s [limb.plaintext_zone] into the proper shape!"), ignored_mobs = victim) + to_chat(victim, span_green("[user] carefully molds your [limb.plaintext_zone] into the proper shape!")) + to_chat(user, span_green("[capitalize(your_or_other)] [limb.plaintext_zone] has been molded into the proper shape! Your next step is to use a screwdriver/wrench to secure your internals.")) + set_superstructure_status(TRUE) + else + user.visible_message(span_danger("[user] accidentally molds [their_or_other] [limb.plaintext_zone] into the wrong shape!"), \ + span_danger("You accidentally mold [your_or_other] [limb.plaintext_zone] into the wrong shape!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[user] accidentally molds your [limb.plaintext_zone] into the wrong shape!")) + + limb.receive_damage(brute = MOLD_METAL_FAILURE_BRUTE_DAMAGE, damage_source = user, wound_bonus = CANT_WOUND) + + var/sufficiently_insulated_gloves = FALSE + var/obj/item/clothing/gloves/worn_gloves = user.gloves + if ((worn_gloves?.heat_protection & HANDS) && worn_gloves?.max_heat_protection_temperature && worn_gloves.max_heat_protection_temperature >= MOLD_METAL_HEAT_RESISTANCE_THRESHOLD) + sufficiently_insulated_gloves = TRUE + + if (sufficiently_insulated_gloves || HAS_TRAIT(user, TRAIT_RESISTHEAT) || HAS_TRAIT(user, TRAIT_RESISTHEATHANDS)) + return + + to_chat(user, span_danger("You burn your hand on [victim]'s [limb.plaintext_zone]!")) + var/obj/item/bodypart/affecting = user.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") + affecting?.receive_damage(burn = MOLD_METAL_HAND_BURNT_BURN_DAMAGE, damage_source = limb) + +#undef MOLD_METAL_SABOTAGE_BRUTE_DAMAGE +#undef MOLD_METAL_FAILURE_BRUTE_DAMAGE +#undef MOLD_METAL_HAND_BURNT_BURN_DAMAGE +#undef MOLD_METAL_HEAT_RESISTANCE_THRESHOLD + +/** + * A "safe" way to give our victim a T2 burn wound. Requires an aggrograb, and a welder. This is required to mold metal, the 1st step of treatment. + * Guaranteed to work. After a delay, causes a T2 burn wound with no damage. + * Can be sabotaged by enabling combat mode to cause a T3. + */ +/datum/wound/blunt/robotic/secures_internals/critical/proc/heat_metal(obj/item/welder, mob/living/user) + if (!welder.tool_use_check()) + return TRUE + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + + user?.visible_message(span_danger("[user] carefully holds [welder] to [their_or_other] [limb.plaintext_zone], slowly heating it..."), \ + span_warning("You carefully hold [welder] to [your_or_other] [limb.plaintext_zone], slowly heating it..."), ignored_mobs = victim) + + var/delay_mult = 1 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + if (!welder.use_tool(target = victim, user = user, delay = 10 SECONDS * delay_mult, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + var/wound_path = /datum/wound/burn/robotic/overheat/severe + if (user != victim && user.combat_mode) + wound_path = /datum/wound/burn/robotic/overheat/critical // it really isnt that bad, overheat wounds are a bit funky + user.visible_message(span_danger("[user] heats [victim]'s [limb.plaintext_zone] aggressively, overheating it far beyond the necessary point!"), \ + span_danger("You heat [victim]'s [limb.plaintext_zone] aggressively, overheating it far beyond the necessary point!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[user] heats your [limb.plaintext_zone] aggressively, overheating it far beyond the necessary point!")) + + var/datum/wound/burn/robotic/overheat/overheat_wound = new wound_path + overheat_wound.apply_wound(limb, wound_source = welder) + + to_chat(user, span_green("[capitalize(your_or_other)] [limb.plaintext_zone] is now heated, allowing it to be molded! Your next step is to have someone physically reset the superstructure with their hands.")) + return TRUE + +/// Cost of an RCD to quickly fix our broken in raw matter +#define ROBOTIC_T3_BLUNT_WOUND_RCD_COST 25 +/// Cost of an RCD to quickly fix our broken in silo material +#define ROBOTIC_T3_BLUNT_WOUND_RCD_SILO_COST ROBOTIC_T3_BLUNT_WOUND_RCD_COST / 4 + +/// The "premium" treatment for 1st step of T3. Requires an RCD. Guaranteed to work, but can cause damage if delay is high. +/datum/wound/blunt/robotic/secures_internals/critical/proc/rcd_superstructure(obj/item/construction/rcd/treating_rcd, mob/user) + if (!treating_rcd.tool_use_check()) + return TRUE + + var/has_enough_matter = (treating_rcd.get_matter(user) > ROBOTIC_T3_BLUNT_WOUND_RCD_COST) + var/silo_has_enough_materials = (treating_rcd.get_silo_iron() > ROBOTIC_T3_BLUNT_WOUND_RCD_SILO_COST) + + if (!silo_has_enough_materials && has_enough_matter) + return TRUE + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + + var/base_time = 10 SECONDS + var/delay_mult = 1 + var/knows_wires = FALSE + if (victim == user) + delay_mult *= 3 // real slow + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + delay_mult *= 0.5 + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + delay_mult *= 0.5 // engis are accustomed to using RCDs + knows_wires = TRUE + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + delay_mult *= 0.85 + else + delay_mult *= 0.5 + + var/final_time = (base_time * delay_mult) + var/misused = (final_time > base_time) // if we damage the limb when we're done + + if (user) + var/misused_text = (misused ? "unsteadily " : "") + + var/message = "[user]'s RCD whirs to life as it begins [misused_text]replacing the damaged superstructure of [their_or_other] [limb.plaintext_zone]..." + var/self_message = "Your RCD whirs to life as it begins [misused_text]replacing the damaged superstructure of [your_or_other] [limb.plaintext_zone]..." + + if (misused) // warning span if misused, notice span otherwise + message = span_danger(message) + self_message = span_danger(self_message) + else + message = span_notice(message) + self_message = span_notice(self_message) + + user.visible_message(message, self_message) + + if (!treating_rcd.use_tool(target = victim, user = user, delay = final_time, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + playsound(get_turf(treating_rcd), 'sound/machines/ping.ogg', 75) // celebration! we did it + set_superstructure_status(TRUE) + + var/use_amount = (silo_has_enough_materials ? ROBOTIC_T3_BLUNT_WOUND_RCD_SILO_COST : ROBOTIC_T3_BLUNT_WOUND_RCD_COST) + treating_rcd.useResource(use_amount, user) + + if (user) + var/misused_text = (misused ? ", though it replaced a bit more than it should've..." : "!") + var/message = "[user]'s RCD lets out a small ping as it finishes replacing the superstructure of [their_or_other] [limb.plaintext_zone][misused_text]" + var/self_message = "Your RCD lets out a small ping as it finishes replacing the superstructure of [your_or_other] [limb.plaintext_zone][misused_text]" + if (misused) + message = span_danger(message) + self_message = span_danger(self_message) + else + message = span_green(message) + self_message = span_green(self_message) + + user.visible_message(message, self_message) + if (misused) + limb.receive_damage(brute = 10, damage_source = treating_rcd, wound_bonus = CANT_WOUND) + // the double message is fine here, since the first message also tells you if you fucked up and did some damage + to_chat(user, span_green("The superstructure has been reformed! Your next step is to secure the internals via a screwdriver/wrench.")) + return TRUE + +#undef ROBOTIC_T3_BLUNT_WOUND_RCD_COST +#undef ROBOTIC_T3_BLUNT_WOUND_RCD_SILO_COST + +/** + * Goofy but practical, this is the superior ghetto self-tend of T3's first step compared to percussive maintenance. + * Still requires the limb to be malleable, but has a high chance of success and doesn't burn your hand, but gives worse bonuses for wires/HUD. + */ +/datum/wound/blunt/robotic/secures_internals/critical/proc/plunge(obj/item/plunger/treating_plunger, mob/user) + if (!treating_plunger.tool_use_check()) + return TRUE + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + user?.visible_message(span_notice("[user] begins plunging at the dents on [their_or_other] [limb.plaintext_zone] with [treating_plunger]..."), \ + span_green("You begin plunging at the dents on [your_or_other] [limb.plaintext_zone] with [treating_plunger]...")) + + var/delay_mult = 1 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + delay_mult /= treating_plunger.plunge_mod + + if (!treating_plunger.use_tool(target = victim, user = user, delay = 8 SECONDS * delay_mult, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + var/success_chance = 80 + if (victim == user) + success_chance *= 0.6 + + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + success_chance *= 1.25 + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + success_chance *= 1.1 + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + success_chance *= 1.25 // its kinda alien to do this, so even people with the wires get the full bonus of diag huds + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + success_chance *= 1.5 + + if (prob(success_chance)) + user?.visible_message(span_green("[victim]'s [limb.plaintext_zone] lets out a sharp POP as [treating_plunger] forces it into its normal position!"), \ + span_green("[victim]'s [limb.plaintext_zone] lets out a sharp POP as your [treating_plunger] forces it into its normal position!")) + to_chat(user, span_green("[capitalize(your_or_other)] [limb.plaintext_zone]'s structure has been reset to it's proper position! Your next step is to secure it with a screwdriver/wrench, though bone gel would also work.")) + set_superstructure_status(TRUE) + else + user?.visible_message(span_danger("[victim]'s [limb.plaintext_zone] splinters from [treating_plunger]'s plunging!"), \ + span_danger("[capitalize(your_or_other)] [limb.plaintext_zone] splinters from your [treating_plunger]'s plunging!")) + limb.receive_damage(brute = 5, damage_source = treating_plunger) + + return TRUE + +/datum/wound/blunt/robotic/secures_internals/critical/handle_percussive_maintenance_success(attacking_item, mob/living/user) + var/your_or_other = (user == victim ? "your" : "[victim]'s") + victim.visible_message(span_green("[victim]'s [limb.plaintext_zone] gets smashed into a proper shape!"), \ + span_green("Your [limb.plaintext_zone] gets smashed into a proper shape!")) + + var/user_message = "[capitalize(your_or_other)] [limb.plaintext_zone]'s superstructure has been reset! Your next step is to screwdriver/wrench the internals, \ + though if you're desperate enough to use percussive maintenance, you might want to either use a crowbar or bone gel..." + to_chat(user, span_green(user_message)) + + set_superstructure_status(TRUE) + +/datum/wound/blunt/robotic/secures_internals/critical/handle_percussive_maintenance_failure(attacking_item, mob/living/user) + to_chat(victim, span_danger("Your [limb.plaintext_zone] only deforms more from the impact...")) + limb.receive_damage(brute = 1, damage_source = attacking_item, wound_bonus = CANT_WOUND) + +/datum/wound/blunt/robotic/secures_internals/critical/uses_percussive_maintenance() + return (!superstructure_remedied && limb_malleable()) + +/// Transitions our steps by setting both superstructure and secure internals readiness. +/datum/wound/blunt/robotic/secures_internals/critical/proc/set_superstructure_status(remedied) + superstructure_remedied = remedied + ready_to_secure_internals = remedied diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm new file mode 100644 index 00000000000..9dd515813ef --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm @@ -0,0 +1,388 @@ +/// A subtype of blunt wounds that has a "secure internals" step +/datum/wound/blunt/robotic/secures_internals + /// Our current counter for gel + gauze regeneration + var/regen_time_elapsed = 0 SECONDS + /// Time needed for gel to secure internals. + var/regen_time_needed = 30 SECONDS + + /// If we have used bone gel to secure internals. + var/gelled = FALSE + /// Total brute damage taken over the span of [regen_time_needed] deciseconds when we gel our limb. + var/gel_damage = 10 // brute in total + + /// If we are ready to begin screwdrivering or gelling our limb. + var/ready_to_secure_internals = FALSE + /// If our external plating has been torn open and we can access our internals without a tool + var/crowbarred_open = FALSE + /// If internals are secured, and we are ready to weld our limb closed and end the wound + var/ready_to_resolder = TRUE + +/datum/wound/blunt/robotic/secures_internals/handle_process(seconds_per_tick, times_fired) + . = ..() + + if (!victim || IS_IN_STASIS(victim)) + return + + if (gelled) + regen_time_elapsed += ((seconds_per_tick SECONDS) / 2) + if(victim.body_position == LYING_DOWN) + if(SPT_PROB(30, seconds_per_tick)) + regen_time_elapsed += 1 SECONDS + if(victim.IsSleeping() && SPT_PROB(30, seconds_per_tick)) + regen_time_elapsed += 1 SECONDS + + var/effective_damage = ((gel_damage / (regen_time_needed / 10)) * seconds_per_tick) + var/obj/item/stack/gauze = limb.current_gauze + if (gauze) + effective_damage *= gauze.splint_factor + limb.receive_damage(effective_damage, wound_bonus = CANT_WOUND, damage_source = src) + if(effective_damage && prob(33)) + var/gauze_text = (gauze?.splint_factor ? ", although the [gauze] helps to prevent some of the leakage" : "") + to_chat(victim, span_danger("Your [limb.plaintext_zone] sizzles as some gel leaks and warps the exterior metal[gauze_text]...")) + + if(regen_time_elapsed > regen_time_needed) + if(!victim || !limb) + qdel(src) + return + to_chat(victim, span_green("The gel within your [limb.plaintext_zone] has fully hardened, allowing you to re-solder it!")) + gelled = FALSE + ready_to_resolder = TRUE + ready_to_secure_internals = FALSE + set_disabling(FALSE) + +/datum/wound/blunt/robotic/secures_internals/modify_desc_before_span(desc) + . = ..() + + var/use_exclamation = FALSE + + if (!limb.current_gauze) // gauze covers it up + if (crowbarred_open) + . += ", [span_notice("and is violently torn open, internals visible to the outside")]" + use_exclamation = TRUE + if (gelled) + . += ", [span_notice("with fizzling blue surgical gel leaking out of the cracks")]" + use_exclamation = TRUE + if (use_exclamation) + . += "!" + +/datum/wound/blunt/robotic/secures_internals/get_scanner_description(mob/user) + . = ..() + + var/to_add = get_wound_status() + if (!isnull(to_add)) + . += "\nWound status: [to_add]" + +/datum/wound/blunt/robotic/secures_internals/get_simple_scanner_description(mob/user) + . = ..() + + var/to_add = get_wound_status() + if (!isnull(to_add)) + . += "\nWound status: [to_add]" + +/// Returns info specific to the dynamic state of the wound. +/datum/wound/blunt/robotic/secures_internals/proc/get_wound_status(mob/user) + if (crowbarred_open) + . += "The limb has been torn open, allowing ease of access to internal components, but also disabling it. " + if (gelled) + . += "Bone gel has been applied, causing progressive corrosion of the metal, but eventually securing the internals. " + +/datum/wound/blunt/robotic/secures_internals/item_can_treat(obj/item/potential_treater, mob/user) + if (potential_treater.tool_behaviour == TOOL_WELDER || potential_treater.tool_behaviour == TOOL_CAUTERY) + if (ready_to_resolder) + return TRUE + + if (ready_to_secure_internals) + if (item_can_secure_internals(potential_treater)) + return TRUE + + return ..() + +/datum/wound/blunt/robotic/secures_internals/treat(obj/item/potential_treater, mob/user) + if (ready_to_secure_internals) + if (istype(potential_treater, /obj/item/stack/medical/bone_gel)) + return apply_gel(potential_treater, user) + else if (!crowbarred_open && potential_treater.tool_behaviour == TOOL_CROWBAR) + return crowbar_open(potential_treater, user) + else if (item_can_secure_internals(potential_treater)) + return secure_internals_normally(potential_treater, user) + else if (ready_to_resolder && (potential_treater.tool_behaviour == TOOL_WELDER) || (potential_treater.tool_behaviour == TOOL_CAUTERY)) + return resolder(potential_treater, user) + + return ..() + +/// Returns TRUE if the item can be used in our 1st step (2nd if T3) of repairs. +/datum/wound/blunt/robotic/secures_internals/proc/item_can_secure_internals(obj/item/potential_treater) + return (potential_treater.tool_behaviour == TOOL_SCREWDRIVER || potential_treater.tool_behaviour == TOOL_WRENCH || istype(potential_treater, /obj/item/stack/medical/bone_gel)) + +#define CROWBAR_OPEN_SELF_TEND_DELAY_MULT 2 +#define CROWBAR_OPEN_KNOWS_ROBO_WIRES_DELAY_MULT 0.5 +#define CROWBAR_OPEN_KNOWS_ENGI_WIRES_DELAY_MULT 0.5 +#define CROWBAR_OPEN_HAS_DIAG_HUD_DELAY_MULT 0.5 +#define CROWBAR_OPEN_WOUND_SCANNED_DELAY_MULT 0.5 +/// If our limb is essential, damage dealt to it by tearing it open will be multiplied against this. +#define CROWBAR_OPEN_ESSENTIAL_LIMB_DAMAGE_MULT 1.5 + +/// The "power" put into electrocute_act whenever someone gets shocked when they crowbar open our limb +#define CROWBAR_OPEN_SHOCK_POWER 20 +/// The brute damage done to this limb (doubled on essential limbs) when it is crowbarred open +#define CROWBAR_OPEN_BRUTE_DAMAGE 20 + +/** + * Available during the "secure internals" step of T2 and T3. Requires a crowbar. Low-quality ghetto option. + * + * Tears open the limb, exposing internals. This massively increases the chance of secure internals succeeding, and removes the self-tend malice. + * + * Deals significant damage to the limb, and shocks the user (causing failure) if victim is alive, this limb is wired, and user is not insulated. + */ +/datum/wound/blunt/robotic/secures_internals/proc/crowbar_open(obj/item/crowbarring_item, mob/living/user) + if (!crowbarring_item.tool_start_check()) + return TRUE + + var/delay_mult = 1 + if (user == victim) + delay_mult *= CROWBAR_OPEN_SELF_TEND_DELAY_MULT + + var/knows_wires = FALSE + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + delay_mult *= CROWBAR_OPEN_KNOWS_ROBO_WIRES_DELAY_MULT + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + delay_mult *= CROWBAR_OPEN_KNOWS_ENGI_WIRES_DELAY_MULT + knows_wires = TRUE + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + delay_mult *= (CROWBAR_OPEN_HAS_DIAG_HUD_DELAY_MULT * 1.5) + else + delay_mult *= CROWBAR_OPEN_HAS_DIAG_HUD_DELAY_MULT + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= CROWBAR_OPEN_WOUND_SCANNED_DELAY_MULT + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + + var/self_message = span_warning("You start prying open [your_or_other] [limb.plaintext_zone] with [crowbarring_item]...") + + user?.visible_message(span_bolddanger("[user] starts prying open [their_or_other] [limb.plaintext_zone] with [crowbarring_item]!"), self_message, ignored_mobs = list(victim)) + + var/victim_message + if (user != victim) // this exists so we can do a userdanger + victim_message = span_userdanger("[user] starts prying open your [limb.plaintext_zone] with [crowbarring_item]!") + else + victim_message = self_message + to_chat(victim, victim_message) + + playsound(get_turf(crowbarring_item), 'sound/machines/airlock_alien_prying.ogg', 30, TRUE) + if (!crowbarring_item.use_tool(target = victim, user = user, delay = (7 SECONDS * delay_mult), volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + var/limb_can_shock = (victim.stat != DEAD && limb.biological_state & BIO_WIRED) + var/stunned = FALSE + + var/message + + if (user && limb_can_shock) + var/electrocute_flags = (SHOCK_KNOCKDOWN|SHOCK_NO_HUMAN_ANIM|SHOCK_SUPPRESS_MESSAGE) + var/stun_chance = 100 + + if (HAS_TRAIT(user, TRAIT_SHOCKIMMUNE)) + stun_chance = 0 + + else if (iscarbon(user)) // doesn't matter if we're shock immune, it's set to 0 anyway + var/mob/living/carbon/carbon_user = user + if (carbon_user.gloves) + stun_chance *= carbon_user.gloves.siemens_coefficient + + if (ishuman(user)) + var/mob/living/carbon/human/human_user = user + stun_chance *= human_user.physiology.siemens_coeff + stun_chance *= carbon_user.dna.species.siemens_coeff + + if (stun_chance && prob(stun_chance)) + electrocute_flags &= ~SHOCK_KNOCKDOWN + electrocute_flags &= ~SHOCK_NO_HUMAN_ANIM + stunned = TRUE + + message = span_boldwarning("[user] is shocked by [their_or_other] [limb.plaintext_zone], [user.p_their()] crowbar slipping as [user.p_they()] briefly convulse!") + self_message = span_userdanger("You are shocked by [your_or_other] [limb.plaintext_zone], causing your crowbar to slip out!") + if (user != victim) + victim_message = span_userdanger("[user] is shocked by your [limb.plaintext_zone] in [user.p_their()] efforts to tear it open!") + + var/shock_damage = CROWBAR_OPEN_SHOCK_POWER + if (limb.current_gauze) + shock_damage *= limb.current_gauze.splint_factor // always good to let gauze do something + user.electrocute_act(shock_damage, limb, flags = electrocute_flags) + + if (!stunned) + var/other_shock_text = "" + var/self_shock_text = "" + if (!limb_can_shock) + other_shock_text = ", and is striken by golden bolts of electricity" + self_shock_text = ", but are immediately shocked by the electricity contained within" + message = span_boldwarning("[user] tears open [their_or_other] [limb.plaintext_zone] with [user.p_their()] crowbar[other_shock_text]!") + self_message = span_warning("You tear open [your_or_other] [limb.plaintext_zone] with your crowbar[self_shock_text]!") + if (user != victim) + victim_message = span_userdanger("Your [limb.plaintext_zone] fragments and splinters as [user] tears it open with [user.p_their()] crowbar!") + + playsound(get_turf(crowbarring_item), 'sound/effects/bang.ogg', 35, TRUE) // we did it! + to_chat(user, span_green("You've torn [your_or_other] [limb.plaintext_zone] open, heavily damaging it but making it a lot easier to screwdriver the internals!")) + var/damage = CROWBAR_OPEN_BRUTE_DAMAGE + if (limb_essential()) // can't be disabled + damage *= CROWBAR_OPEN_ESSENTIAL_LIMB_DAMAGE_MULT + limb.receive_damage(brute = CROWBAR_OPEN_BRUTE_DAMAGE, wound_bonus = CANT_WOUND, damage_source = crowbarring_item) + set_torn_open(TRUE) + + if (user == victim) + victim_message = self_message + + user.visible_message(message, self_message, ignored_mobs = list(victim)) + to_chat(victim, victim_message) + return TRUE + +#undef CROWBAR_OPEN_SELF_TEND_DELAY_MULT +#undef CROWBAR_OPEN_KNOWS_ROBO_WIRES_DELAY_MULT +#undef CROWBAR_OPEN_KNOWS_ENGI_WIRES_DELAY_MULT +#undef CROWBAR_OPEN_HAS_DIAG_HUD_DELAY_MULT +#undef CROWBAR_OPEN_WOUND_SCANNED_DELAY_MULT +#undef CROWBAR_OPEN_ESSENTIAL_LIMB_DAMAGE_MULT + +#undef CROWBAR_OPEN_BRUTE_DAMAGE +#undef CROWBAR_OPEN_SHOCK_POWER + +/// Sets [crowbarred_open] to the new value. If we werent originally disabling, or if we arent currently and we're torn open, we set disabling to true. +/datum/wound/blunt/robotic/secures_internals/proc/set_torn_open(torn_open_state) + // if we aren't disabling but we were torn open, OR if we aren't disabling by default + var/should_update_disabling = ((!disabling && torn_open_state) || !initial(disabling)) + + crowbarred_open = torn_open_state + if(should_update_disabling) + set_disabling(torn_open_state) + +/// If, on a secure internals attempt, we have less than this chance to succeed, we warn the user. +#define SECURE_INTERNALS_CONFUSED_CHANCE_THRESHOLD 25 +#define SECURE_INTERNALS_FAILURE_BRUTE_DAMAGE 5 + +/** + * The primary way of performing the secure internals step for T2/T3. Uses a screwdriver/wrench. Very hard to do by yourself, or without a diag hud/wire knowledge. + * Roboticists/engineers have a very high chance of succeeding. + * Deals some brute damage on failure, but moves to the final step of treatment (re-soldering) on success. + * + * If [crowbarred_open], made far more likely and remove the self-tend malice. + */ +/datum/wound/blunt/robotic/secures_internals/proc/secure_internals_normally(obj/item/securing_item, mob/user) + if (!securing_item.tool_start_check()) + return TRUE + + var/chance = 10 + var/delay_mult = 1 + + if (user == victim) + if (!crowbarred_open) + chance *= 0.2 + delay_mult *= 2 + + var/knows_wires = FALSE + if (crowbarred_open) + chance *= 4 // even self-tends get a high chance of success if torn open! + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + chance *= 8 // almost guaranteed if its not self surgery - guaranteed with diag hud + delay_mult *= 0.75 + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + chance *= 5.5 + delay_mult *= 0.85 + knows_wires = TRUE + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + chance *= 1.25 // ((10 * 8) * 1.25) = 100% + else + chance *= 4 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + chance *= 1.5 // youre not intended to fix this by yourself this way + delay_mult *= 0.8 + + var/confused = (chance < SECURE_INTERNALS_CONFUSED_CHANCE_THRESHOLD) // generate chance beforehand, so we can use this var + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + user?.visible_message(span_notice("[user] begins the delicate operation of securing the internals of [their_or_other] [limb.plaintext_zone]..."), \ + span_notice("You begin the delicate operation of securing the internals of [your_or_other] [limb.plaintext_zone]...")) + if (confused) + to_chat(user, span_warning("You are confused by the layout of [your_or_other] [limb.plaintext_zone]! A diagnostic hud would help, as would knowing robo/engi wires! You could also tear the limb open with a crowbar, or get someone else to help.")) + + if (!securing_item.use_tool(target = victim, user = user, delay = (10 SECONDS * delay_mult), volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + if (prob(chance)) + user?.visible_message(span_green("[user] finishes securing the internals of [their_or_other] [limb.plaintext_zone]!"), \ + span_green("You finish securing the internals of [your_or_other] [limb.plaintext_zone]!")) + to_chat(user, span_green("[capitalize(your_or_other)] [limb.plaintext_zone]'s internals are now secure! Your next step is to weld/cauterize it.")) + ready_to_secure_internals = FALSE + ready_to_resolder = TRUE + else + user?.visible_message(span_danger("[user] screws up and accidentally damages [their_or_other] [limb.plaintext_zone]!")) + limb.receive_damage(brute = SECURE_INTERNALS_FAILURE_BRUTE_DAMAGE, damage_source = securing_item, wound_bonus = CANT_WOUND) + + return TRUE + +#undef SECURE_INTERNALS_CONFUSED_CHANCE_THRESHOLD +#undef SECURE_INTERNALS_FAILURE_BRUTE_DAMAGE + +/** + * "Premium" ghetto option of the secure internals step for T2/T3. Requires bone gel. Guaranteed to work. + * Deals damage over time and disables the limb, but finishes the step afterwards. + */ +/datum/wound/blunt/robotic/secures_internals/proc/apply_gel(obj/item/stack/medical/bone_gel/gel, mob/user) + if (gelled) + to_chat(user, span_warning("[user == victim ? "Your" : "[victim]'s"] [limb.plaintext_zone] is already filled with bone gel!")) + return TRUE + + var/delay_mult = 1 + if (victim == user) + delay_mult *= 0.5 + + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + user.visible_message(span_danger("[user] begins hastily applying [gel] to [victim]'s [limb.plaintext_zone]..."), span_warning("You begin hastily applying [gel] to [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone], disregarding the acidic effect it seems to have on the metal...")) + + if (!do_after(user, (8 SECONDS * delay_mult), target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + gel.use(1) + if(user != victim) + user.visible_message(span_notice("[user] finishes applying [gel] to [victim]'s [limb.plaintext_zone], emitting a fizzing noise!"), span_notice("You finish applying [gel] to [victim]'s [limb.plaintext_zone]!"), ignored_mobs=victim) + to_chat(victim, span_userdanger("[user] finishes applying [gel] to your [limb.plaintext_zone], and you can hear the sizzling of the metal...")) + else + victim.visible_message(span_notice("[victim] finishes applying [gel] to [victim.p_their()] [limb.plaintext_zone], emitting a funny fizzing sound!"), span_notice("You finish applying [gel] to your [limb.plaintext_zone], and you can hear the sizzling of the metal...")) + + gelled = TRUE + set_disabling(TRUE) + processes = TRUE + return TRUE + +/** + * The final step of T2/T3, requires a welder/cautery. Guaranteed to work. Cautery is slower. + * Once complete, removes the wound entirely. + */ +/datum/wound/blunt/robotic/secures_internals/proc/resolder(obj/item/welding_item, mob/user) + if (!welding_item.tool_start_check()) + return TRUE + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + victim.visible_message(span_notice("[user] begins re-soldering [their_or_other] [limb.plaintext_zone]..."), \ + span_notice("You begin re-soldering [your_or_other] [limb.plaintext_zone]...")) + + var/delay_mult = 1 + if (welding_item.tool_behaviour == TOOL_CAUTERY) + delay_mult *= 3 // less efficient + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + if (!welding_item.use_tool(target = victim, user = user, delay = 7 SECONDS * delay_mult, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + victim.visible_message(span_green("[user] finishes re-soldering [their_or_other] [limb.plaintext_zone]!"), \ + span_notice("You finish re-soldering [your_or_other] [limb.plaintext_zone]!")) + remove_wound() + return TRUE diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm new file mode 100644 index 00000000000..24ac18eeab6 --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm @@ -0,0 +1,441 @@ +#define OVERHEAT_ON_STASIS_HEAT_MULT 0.25 +/// At 100% hercuri composition, a spray of reagents will have its effective chem temp reduced by this. 50%, reduced by half this, etc. +#define ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_MAX_HEAT_DECREMENT 60 +/// At 100% hercuri composition, a spray of reagents will have its heat shock damage reduced by this. 50%, reduced by half this, etc. +#define ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_HEAT_SHOCK_MULT_DECREMENT 0.3 + +/datum/wound_pregen_data/burnt_metal + abstract = TRUE + required_limb_biostate = BIO_METAL + required_wounding_types = list(WOUND_BURN) + wound_series = WOUND_SERIES_METAL_BURN_OVERHEAT + +/datum/wound_pregen_data/burnt_metal/generate_scar_priorities() + return list("[BIO_METAL]") + +/datum/wound/burn/robotic/overheat + treat_text = "Introduction of a cold environment or lowering of body temperature." + + simple_desc = "Metals are overheated, increasing damage taken significantly and raising body temperature!" + simple_treat_text = "Ideally cryogenics, but any source of low body temperature can work. Spraying with spray bottles/extinguishers/showers \ + will quickly cool the limb, but cause damage. Hercuri is especially effective in quick cooling. \ + Clothing reduces the water/hercuri that makes it to the metal, and gauze binds it and reduces the damage taken." + homemade_treat_text = "You can also splash any liquid on it for a rather inefficient and damaging coolant!" + + default_scar_file = METAL_SCAR_FILE + + wound_flags = (ACCEPTS_GAUZE|SPLINT_OVERLAY|CAN_BE_GRASPED) // gauze binds the metal and makes it resistant to thermal shock + + processes = TRUE + + /// The virtual temperature of the chassis. Crucial for many things, like our severity, the temp we transfer, our cooling damage, etc. + var/chassis_temperature + + /// The lower bound of the chassis_temperature we can start with. + var/starting_temperature_min = (BODYTEMP_NORMAL + 200) + /// The upper bound of the chassis_temperature we can start with. + var/starting_temperature_max = (BODYTEMP_NORMAL + 250) + + /// If [chassis_temperature] goes below this, we reduce in severity. + var/cooling_threshold = (BODYTEMP_NORMAL + 3) + /// If [chassis_temperature] goes above this, we increase in severity. + var/heating_threshold = (BODYTEMP_NORMAL + 300) + + /// The buffer in kelvin we will subtract from the chassis_temperature of a wound we demote to. + var/cooling_demote_buffer = 60 + /// The buffer in kelvin we will add to the chassis_temperature of a wound we promote to. + var/heating_promote_buffer = 60 + + /// The coefficient of heat transfer we will use when shifting our temp to the victim's. + var/bodytemp_coeff = 0.04 + /// For every degree below normal bodytemp, we will multiply our incoming temperature by 1 + degrees * this. Allows incentivization of freezing yourself instead of just waiting. + var/bodytemp_difference_expose_bonus_ratio = 0.035 + /// The coefficient of heat transfer we will use when shifting our victim's temp to ours. + var/outgoing_bodytemp_coeff = 0 + /// The mult applied to heat output when we are on a important limb, e.g. head/torso. + var/important_outgoing_mult = 1.2 + /// The coefficient of heat transfer we will use when shifting our temp to a turf. + var/turf_coeff = 0.02 + + /// The maximum temperature we can cause by heating our victim. + var/max_outgoing_temperature = BODYTEMP_HEAT_WOUND_LIMIT - 1 + + /// If we are hit with burn damage, the damage will be multiplied against this to determine the effective heat we get. + var/incoming_damage_heat_coeff = 3 + + /// The coefficient of heat transfer we will use when receiving heat from reagent contact. + var/base_reagent_temp_coefficient = 0.02 + + /// The ratio of temp shift -> brute damage. Careful with this value, it can make stuff really really nasty. + var/heat_shock_delta_to_damage_ratio = 0.12 + /// The minimum heat difference we must have on reagent contact to cause heat shock damage. + var/heat_shock_minimum_delta = 5 + + /// If we are sprayed with a extinguisher/shower with obscuring clothing on (think clothing that prevents surgery), the effect is multiplied against this. + var/sprayed_with_reagent_clothed_mult = 0.15 + + /// The wound we demote to when we go below cooling threshold. If null, removes us. + var/datum/wound/burn/robotic/demotes_to + /// The wound we promote to when we go above heating threshold. + var/datum/wound/burn/robotic/promotes_to + + /// The color of the light we will generate. + var/light_color + /// The power of the light we will generate. + var/light_power + /// The range of the light we will generate. + var/light_range + + /// The glow we have attached to our victim, to simulate our limb glowing. + var/obj/effect/dummy/lighting_obj/moblight/mob_glow + +/datum/wound/burn/robotic/overheat/New(temperature) + chassis_temperature = (isnull(temperature) ? get_random_starting_temperature() : temperature) + + return ..() + +/datum/wound/burn/robotic/overheat/Destroy() + QDEL_NULL(mob_glow) + return ..() + +/datum/wound/burn/robotic/overheat/set_victim(mob/living/new_victim) + if (victim) + QDEL_NULL(mob_glow) + UnregisterSignal(victim, COMSIG_MOB_AFTER_APPLY_DAMAGE) + UnregisterSignal(victim, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS) + if (new_victim) + mob_glow = new_victim.mob_light(light_range, light_power, light_color) + mob_glow.set_light_on(TRUE) + RegisterSignal(new_victim, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(victim_attacked)) + RegisterSignal(new_victim, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, PROC_REF(victim_exposed_to_reagents)) + + return ..() + +/datum/wound/burn/robotic/overheat/proc/get_random_starting_temperature() + return LERP(starting_temperature_min, starting_temperature_max, rand()) // LERP since we deal with decimals + +/datum/wound/burn/robotic/get_limb_examine_description() + return span_warning("The metal on this limb is glowing radiantly.") + +/datum/wound/burn/robotic/overheat/handle_process(seconds_per_tick, times_fired) + if (isnull(victim)) + var/turf/our_turf = get_turf(limb) + if (!isnull(our_turf)) + expose_temperature(our_turf.GetTemperature(), (turf_coeff * seconds_per_tick)) + return + if (outgoing_bodytemp_coeff <= 0) + return + var/statis_mult = 1 + if (IS_IN_STASIS(victim)) // stasis heavily reduces the ingoing and outgoing transfer of heat + statis_mult *= OVERHEAT_ON_STASIS_HEAT_MULT + + var/difference_from_average = max((BODYTEMP_NORMAL - victim.bodytemperature), 0) + var/difference_mult = 1 + (difference_from_average * bodytemp_difference_expose_bonus_ratio) + if (expose_temperature(victim.bodytemperature, (bodytemp_coeff * seconds_per_tick * statis_mult * difference_mult))) + return + var/mult = outgoing_bodytemp_coeff + if (limb_essential()) + mult *= important_outgoing_mult + var/adjustment_allowed = max((max_outgoing_temperature - victim.bodytemperature), 0) + var/amount_to_adjust = min((((chassis_temperature - victim.bodytemperature) * mult) * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick * statis_mult), adjustment_allowed) + victim.adjust_bodytemperature(amount_to_adjust) + +/// Signal proc for when our victim is externally attacked. Increases chassis temp based on burn damage received. +/datum/wound/burn/robotic/overheat/proc/victim_attacked(datum/source, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item) + SIGNAL_HANDLER + + if (def_zone != limb.body_zone) // use this proc since receive damage can also be called for like, chems and shit + return + + if (!victim) + return + + if (damagetype != BURN) + return + + if (wound_bonus == CANT_WOUND) + return + + var/effective_damage = (damage - blocked) + if (effective_damage <= 0) + return + + expose_temperature((chassis_temperature + effective_damage), incoming_damage_heat_coeff) + +/** + * Signal proc for when our victim is exposed to reagents, obviously. + * + * Equalizes temp to the reagent temp, but also causes thermal shock. Basically, does damage based on the temp differential. + * Clothes reduce the effects massively. Hercuri reduces the thermal shock and gets a special temp buff. + */ +/datum/wound/burn/robotic/overheat/proc/victim_exposed_to_reagents(datum/signal_source, list/reagents, datum/reagents/source, methods, volume_modifier, show_message) + SIGNAL_HANDLER + + var/reagent_coeff = base_reagent_temp_coefficient + if (!get_location_accessible(victim, limb.body_zone)) + if (ishuman(victim)) + // hi! its niko! small rant + // this proc has no goddamn reason to be on human, it could so easily just have used a proc on carbon that would get the required bodyparts to check + // but no. it had to hardcode the list in the proc itself so its impossible to modularly fix this + // so instead we just say fuck it and hope to god only human subtypes get this wound + // tldr; ryll why + var/mob/living/carbon/human/human_victim = victim + for (var/obj/item/clothing/iter_clothing as anything in human_victim.get_clothing_on_part(limb)) + if (iter_clothing.clothing_flags & THICKMATERIAL) + return + + reagent_coeff *= sprayed_with_reagent_clothed_mult + + if (istype(source.my_atom, /obj/effect/particle_effect/water/extinguisher)) // this used to be a lot, lot more modular, but sadly reagent temps/volumes and shit are horribly inconsistant + expose_temperature(source.chem_temp, (2.55 * reagent_coeff), TRUE) + return + + if (istype(source.my_atom, /obj/machinery/shower)) + expose_temperature(source.chem_temp, (15 * volume_modifier * reagent_coeff), TRUE) + return + + var/total_reagent_amount = 0 + var/hercuri_amount = 0 + for (var/datum/reagent/iterated_reagent as anything in reagents) + total_reagent_amount += reagents[iterated_reagent] + if (iterated_reagent.type == /datum/reagent/medicine/c2/hercuri) + hercuri_amount = reagents[iterated_reagent] + + var/hercuri_percent = (hercuri_amount / total_reagent_amount) + + var/hercuri_chem_temp_increment = (ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_MAX_HEAT_DECREMENT * hercuri_percent) + var/local_chem_temp = max(source.chem_temp - hercuri_chem_temp_increment, 0) + + var/heat_shock_damage_mult = 1 - (ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_HEAT_SHOCK_MULT_DECREMENT * hercuri_percent) + + expose_temperature(local_chem_temp, (reagent_coeff * volume_modifier * total_reagent_amount), TRUE, heat_shock_damage_mult = heat_shock_damage_mult) + +/// Adjusts chassis_temperature by the delta between temperature and itself, multiplied by coeff. +/// If heat_shock is TRUE, limb will receive brute damage based on the delta. +/datum/wound/burn/robotic/overheat/proc/expose_temperature(temperature, coeff = 0.02, heat_shock = FALSE, heat_shock_damage_mult = 1) + var/temp_delta = (temperature - chassis_temperature) * coeff + + var/unclamped_new_temperature = (chassis_temperature + temp_delta) + var/clamped_new_temperature + var/heat_adjustment_used + + if(temp_delta > 0) + clamped_new_temperature = min(min(chassis_temperature + max(temp_delta, 1), temperature), heating_threshold) + heat_adjustment_used = (clamped_new_temperature / unclamped_new_temperature) + else + clamped_new_temperature = max(max(chassis_temperature + min(temp_delta, -1), temperature), cooling_threshold) + heat_adjustment_used = (unclamped_new_temperature / clamped_new_temperature) + + if (heat_shock && abs(temp_delta) > heat_shock_minimum_delta) + var/gauze_mult = 1 + var/obj/item/stack/gauze = limb.current_gauze + if (gauze) + gauze_mult *= (gauze.splint_factor) * 0.4 // very very effective + + if (limb.grasped_by) + gauze_mult *= 0.7 // hold it down yourself + + if (victim) + var/gauze_or_not = (!isnull(gauze) ? ", but [gauze] helps to keep it together" : "") + var/clothing_text = (!get_location_accessible(victim, limb.body_zone) ? ", [victim.p_their()] clothing absorbing some of the liquid" : "") + victim.visible_message(span_warning("[victim]'s [limb.plaintext_zone] strains from the thermal shock[clothing_text][gauze_or_not]!")) + playsound(victim, 'sound/items/welder.ogg', 25) + + var/damage = (((abs(temp_delta) * heat_shock_delta_to_damage_ratio) * gauze_mult) * heat_shock_damage_mult) * heat_adjustment_used + limb.receive_damage(brute = damage, wound_bonus = CANT_WOUND) + + chassis_temperature = clamped_new_temperature // can only be decimal or 1, so it can only reduce the intensity of the adjustment + + return check_temperature() + +/// Removes, demotes, or promotes ourselves to a new wound type if our temperature is past a heating/cooling threshold. +/datum/wound/burn/robotic/overheat/proc/check_temperature() + if (chassis_temperature <= cooling_threshold) + if (demotes_to) + victim.visible_message(span_green("[victim]'s [limb.plaintext_zone] turns a more pleasant thermal color as it cools down a little..."), span_green("Your [limb.plaintext_zone] seems to cool down a little!")) + replace_wound(new demotes_to(cooling_threshold - cooling_demote_buffer)) + return TRUE + else + victim.visible_message(span_green("[victim]'s [limb.plaintext_zone] simmers gently as it returns to its usual colors!"), span_green("Your [limb.plaintext_zone] simmers gently as it returns to its usual colors!")) + remove_wound() + return TRUE + else if (promotes_to && chassis_temperature >= heating_threshold) + victim.visible_message(span_danger("[victim]'s [limb.plaintext_zone] brightens as it overheats further!"), span_userdanger("Your [limb.plaintext_zone] sizzles and brightens as it overheats further!")) + replace_wound(new promotes_to(heating_threshold + heating_promote_buffer)) + return TRUE + +/// Returns a string with our temperature and heating/cooling thresholds, for use in health analyzers. +/datum/wound/burn/robotic/overheat/proc/get_wound_status_info() + var/current_temp_celcius = round(chassis_temperature - T0C, 0.1) + var/current_temp_fahrenheit = round(chassis_temperature * 1.8-459.67, 0.1) + + var/cool_celcius = round(cooling_threshold - T0C, 0.1) + var/cool_fahrenheit = round(cooling_threshold * 1.8-459.67, 0.1) + + var/heat_celcius = round(heating_threshold - T0C, 0.1) + var/heat_fahrenheit = round(heating_threshold * 1.8-459.67, 0.1) + + return "Its current temperature is [span_blue("[current_temp_celcius ] °C ([current_temp_fahrenheit] °F)")], \ + and needs to cool to [span_nicegreen("[cool_celcius] °C ([cool_fahrenheit] °F)")], but \ + will worsen if heated to [span_purple("[heat_celcius] °C ([heat_fahrenheit] °F)")]." + +/datum/wound/burn/robotic/overheat/get_scanner_description(mob/user) + . = ..() + + . += "\nWound status: [get_wound_status_info()]" + +/datum/wound/burn/robotic/overheat/get_simple_scanner_description(mob/user) + . = ..() + + . += "\nWound status: [get_wound_status_info()]" + +// this wound is unaffected by cryoxadone and pyroxadone +/datum/wound/burn/robotic/overheat/on_xadone(power) + return + +/datum/wound/burn/robotic/overheat/moderate + name = "Transient Overheating" + desc = "External metals have exceeded lower-bound thermal limits and have lost some structural integrity, increasing damage taken as well as the chance to \ + sustain additional wounds." + occur_text = "lets out a slight groan as it turns a dull shade of thermal red" + examine_desc = "is glowing a dull thermal red and giving off heat" + treat_text = "Reduction of body temperature to expedite the passive heat dissipation - or, if thermal shock is to be risked, application of a fire extinguisher/shower." + severity = WOUND_SEVERITY_MODERATE + + damage_multiplier_penalty = 1.15 //1.15x damage taken + + starting_temperature_min = (BODYTEMP_NORMAL + 350) + starting_temperature_max = (BODYTEMP_NORMAL + 400) + + cooling_threshold = (BODYTEMP_NORMAL + 100) + heating_threshold = (BODYTEMP_NORMAL + 500) + + cooling_demote_buffer = 60 + heating_promote_buffer = 100 + + a_or_from = "from" + + // easy to get + threshold_penalty = 30 + + status_effect_type = /datum/status_effect/wound/burn/robotic/moderate + + sound_volume = 20 + + outgoing_bodytemp_coeff = 0.0056 + bodytemp_coeff = 0.006 + + base_reagent_temp_coefficient = 0.03 + heat_shock_delta_to_damage_ratio = 0.2 + + promotes_to = /datum/wound/burn/robotic/overheat/severe + + light_color = COLOR_RED + light_power = 0.1 + light_range = 0.5 + + can_scar = FALSE + +/datum/wound_pregen_data/burnt_metal/transient_overheat + abstract = FALSE + + wound_path_to_generate = /datum/wound/burn/robotic/overheat/moderate + + threshold_minimum = 30 + +/datum/wound/burn/robotic/overheat/severe + name = "Thermal Overload" + desc = "Exterior plating has surpassed critical thermal levels, causing significant failure in structural integrity and overheating of internal systems." + occur_text = "sizzles, the externals turning a dull shade of orange" + examine_desc = "appears discolored and polychromatic, parts of it glowing a dull orange" + treat_text = "Isolation from physical hazards, and accommodation of passive heat dissipation - active cooling may be used, but temperature differentials significantly \ + raise the risk of thermal shock." + severity = WOUND_SEVERITY_SEVERE + + a_or_from = "from" + + threshold_penalty = 65 + + status_effect_type = /datum/status_effect/wound/burn/robotic/severe + damage_multiplier_penalty = 1.25 // 1.25x damage taken + + starting_temperature_min = (BODYTEMP_NORMAL + 550) + starting_temperature_max = (BODYTEMP_NORMAL + 600) + + heating_promote_buffer = 150 + + cooling_threshold = (BODYTEMP_NORMAL + 375) + heating_threshold = (BODYTEMP_NORMAL + 800) + + outgoing_bodytemp_coeff = 0.0053 + bodytemp_coeff = 0.004 + + base_reagent_temp_coefficient = 0.03 + heat_shock_delta_to_damage_ratio = 0.2 + + demotes_to = /datum/wound/burn/robotic/overheat/moderate + promotes_to = /datum/wound/burn/robotic/overheat/critical + + light_color = COLOR_BRIGHT_ORANGE + light_power = 0.8 + light_range = 0.5 + + scar_keyword = "burnsevere" + +/datum/wound_pregen_data/burnt_metal/severe + abstract = FALSE + wound_path_to_generate = /datum/wound/burn/robotic/overheat/severe + threshold_minimum = 80 + +/datum/wound/burn/robotic/overheat/critical + name = "Runaway Exothermy" + desc = "Carapace is beyond melting point, causing catastrophic structural integrity failure as well as massively heating up the subject." + occur_text = "turns a bright shade of radiant white as it sizzles and melts" + examine_desc = "is a blinding shade of white, almost melting from the heat" + treat_text = "Immediate confinement to cryogenics, as rapid overheating and physical vulnerability may occur. Active cooling is not advised, \ + since the thermal shock may be lethal with such a temperature differential." + severity = WOUND_SEVERITY_CRITICAL + + a_or_from = "from" + + sound_effect = 'sound/effects/wounds/sizzle2.ogg' + + threshold_penalty = 100 + + status_effect_type = /datum/status_effect/wound/burn/robotic/critical + + damage_multiplier_penalty = 1.5 //1.5x damage taken + + starting_temperature_min = (BODYTEMP_NORMAL + 1050) + starting_temperature_max = (BODYTEMP_NORMAL + 1100) + + cooling_demote_buffer = 100 + + cooling_threshold = (BODYTEMP_NORMAL + 775) + heating_threshold = INFINITY + + outgoing_bodytemp_coeff = 0.0055 // burn... BURN... + bodytemp_coeff = 0.0025 + + base_reagent_temp_coefficient = 0.03 + heat_shock_delta_to_damage_ratio = 0.2 + + max_outgoing_temperature = BODYTEMP_HEAT_WOUND_LIMIT // critical CAN cause wounds, but only barely + + demotes_to = /datum/wound/burn/robotic/overheat/severe + + wound_flags = (MANGLES_EXTERIOR|ACCEPTS_GAUZE|SPLINT_OVERLAY|CAN_BE_GRASPED) + + light_color = COLOR_VERY_SOFT_YELLOW + light_power = 1.3 + light_range = 1.5 + + scar_keyword = "burncritical" + +/datum/wound_pregen_data/burnt_metal/critical + abstract = FALSE + wound_path_to_generate = /datum/wound/burn/robotic/overheat/critical + threshold_minimum = 140 + +#undef OVERHEAT_ON_STASIS_HEAT_MULT +#undef ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_MAX_HEAT_DECREMENT diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_muscle.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_muscle.dm new file mode 100644 index 00000000000..4e91c58f7f6 --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_muscle.dm @@ -0,0 +1,47 @@ +/datum/wound/muscle/robotic + sound_effect = 'sound/effects/wounds/blood1.ogg' + +/datum/wound_pregen_data/muscle/robotic + required_limb_biostate = (BIO_METAL) + +/datum/wound/muscle/robotic/moderate + name = "Overworked Servo" + desc = "A servo has been overworked, and will operate with reduced efficiency until rested." + treat_text = "A tight splint on the affected limb, as well as plenty of rest and sleep." + examine_desc = "appears to be moving sluggishly" + occur_text = "jitters for a moment before moving sluggishly" + severity = WOUND_SEVERITY_MODERATE + interaction_efficiency_penalty = 1.5 + limp_slowdown = 2 + limp_chance = 30 + threshold_penalty = 15 + status_effect_type = /datum/status_effect/wound/muscle/robotic/moderate + regen_ticks_needed = 90 + +/datum/wound_pregen_data/muscle/robotic/servo + abstract = FALSE + wound_path_to_generate = /datum/wound/muscle/robotic/moderate + threshold_minimum = 35 + +/datum/wound/muscle/robotic/severe + name = "Exhausted Piston" + sound_effect = 'sound/effects/wounds/blood2.ogg' + desc = "An important hydraulic piston has been critically overused, resulting in total dysfunction until it recovers." + treat_text = "A tight splint on the affected limb, as well as plenty of rest and sleep." + examine_desc = "is stiffly limp, the extremities splayed out widely" + occur_text = "goes completely stiff, seeming to lock into position" + severity = WOUND_SEVERITY_SEVERE + interaction_efficiency_penalty = 2 + limp_slowdown = 5 + limp_chance = 40 + threshold_penalty = 35 + disabling = TRUE + status_effect_type = /datum/status_effect/wound/muscle/robotic/severe + regen_ticks_needed = 150 + +/datum/wound_pregen_data/muscle/robotic/hydraulic + abstract = FALSE + + wound_path_to_generate = /datum/wound/muscle/robotic/severe + threshold_minimum = 80 + diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_pierce.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_pierce.dm new file mode 100644 index 00000000000..b7e4f259e5d --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_pierce.dm @@ -0,0 +1,146 @@ +// Pierce +// Slow to rise but high damage overall +// Hard-ish to fix +/datum/wound/electrical_damage/pierce + heat_differential_healing_mult = 0.01 + simple_desc = "Electrical conduits have been pierced open, resulting in a fault that slowly intensifies, but with extreme maximum voltage!" + +/datum/wound_pregen_data/electrical_damage/pierce + abstract = TRUE + wound_series = WOUND_SERIES_WIRE_PIERCE_ELECTRICAL_DAMAGE + required_wounding_types = list(WOUND_PIERCE) + +/datum/wound/burn/electrical_damage/pierce/get_limb_examine_description() + return span_warning("The metal on this limb is pierced open.") + +/datum/wound/electrical_damage/pierce/moderate + name = "Punctured Capacitor" + desc = "A major capacitor has been broken open, causing slow but noticable electrical damage." + occur_text = "shoots out a short stream of sparks" + examine_desc = "is shuddering gently, movements a little weak" + treat_text = "Replacing of damaged wiring, though repairs via wirecutting instruments or sutures may suffice, albeit at limited efficiency. In case of emergency, \ + subject may be subjected to high temperatures to allow solder to reset." + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg' + + severity = WOUND_SEVERITY_MODERATE + + sound_volume = 30 + + threshold_penalty = 30 + + intensity = 10 SECONDS + processing_full_shock_threshold = 7 MINUTES + + processing_shock_power_per_second_max = 1.2 + processing_shock_power_per_second_min = 1.1 + + processing_shock_stun_chance = 0.5 + processing_shock_spark_chance = 35 + + process_shock_spark_count_max = 1 + process_shock_spark_count_min = 1 + + wirecut_repair_percent = 0.065 // not even faster at this point + wire_repair_percent = 0.026 + + initial_sparks_amount = 1 + + status_effect_type = /datum/status_effect/wound/electrical_damage/pierce/moderate + + a_or_from = "a" + + scar_keyword = "piercemoderate" + +/datum/wound_pregen_data/electrical_damage/pierce/moderate + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/pierce/moderate + threshold_minimum = 40 + +/datum/wound/electrical_damage/pierce/severe + name = "Penetrated Transformer" + desc = "A major transformer has been pierced, causing slow-to-progess but eventually intense electrical damage." + occur_text = "sputters and goes limp for a moment as it ejects a stream of sparks" + examine_desc = "is shuddering significantly, its servos briefly giving way in a rythmic pattern" + treat_text = "Containment of damaged wiring via gauze, then application of fresh wiring/sutures, or resetting of displaced wiring via wirecutter/retractor." + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T2.ogg' + + severity = WOUND_SEVERITY_SEVERE + + sound_volume = 15 + + threshold_penalty = 40 + + intensity = 20 SECONDS + processing_full_shock_threshold = 6.5 MINUTES + + processing_shock_power_per_second_max = 1.6 + processing_shock_power_per_second_min = 1.5 + + processing_shock_stun_chance = 2.5 + processing_shock_spark_chance = 60 + + process_shock_spark_count_max = 2 + process_shock_spark_count_min = 1 + + wirecut_repair_percent = 0.068 + wire_repair_percent = 0.02 + + initial_sparks_amount = 3 + + status_effect_type = /datum/status_effect/wound/electrical_damage/pierce/moderate + + a_or_from = "a" + + scar_keyword = "piercemoderate" + +/datum/wound_pregen_data/electrical_damage/pierce/severe + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/pierce/severe + threshold_minimum = 60 + +/datum/wound/electrical_damage/pierce/critical + name = "Ruptured PSU" + desc = "The local PSU of this limb has suffered a core rupture, causing a progressive power failure that will slowly intensify into massive electrical damage." + occur_text = "flashes with radiant blue, emitting a noise not unlike a Jacob's Ladder" + examine_desc = "'s PSU is visible, with a sizable hole in the center" + treat_text = "Immediate securing via gauze, followed by emergency cable replacement and securing via wirecutters or hemostat. \ + If the fault has become uncontrollable, extreme heat therapy is recommended." + + severity = WOUND_SEVERITY_CRITICAL + wound_flags = (ACCEPTS_GAUZE|MANGLES_EXTERIOR|CAN_BE_GRASPED|SPLINT_OVERLAY) + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg' + + sound_volume = 30 + + threshold_penalty = 60 + + intensity = 30 SECONDS + processing_full_shock_threshold = 5.5 MINUTES + + processing_shock_power_per_second_max = 2.2 + processing_shock_power_per_second_min = 2.1 + + processing_shock_stun_chance = 1 + processing_shock_spark_chance = 90 + + process_shock_spark_count_max = 3 + process_shock_spark_count_min = 2 + + wirecut_repair_percent = 0.067 + wire_repair_percent = 0.018 + + initial_sparks_amount = 8 + + status_effect_type = /datum/status_effect/wound/electrical_damage/pierce/moderate + + a_or_from = "a" + + scar_keyword = "piercecritical" + +/datum/wound_pregen_data/electrical_damage/pierce/critical + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/pierce/critical + threshold_minimum = 110 diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm new file mode 100644 index 00000000000..a28737520b5 --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm @@ -0,0 +1,628 @@ +/// How much damage and progress is reduced when on stasis. +#define ELECTRICAL_DAMAGE_ON_STASIS_MULT 0.15 +/// How much damage and progress is reduced when limb is grasped. +#define ELECTRICAL_DAMAGE_GRASPED_MULT 0.7 +/// How much damage and progress is reduced when our victim lies down. +#define ELECTRICAL_DAMAGE_LYING_DOWN_MULT 0.7 +/// How much progress is reduced when our victim is dead. +#define ELECTRICAL_DAMAGE_DEAD_PROGRESS_MULT 0.2 // they'll be resting to, so this is more like 0.1 + +/// Base time for a wirecutter being used. +#define ELECTRICAL_DAMAGE_WIRECUTTER_BASE_DELAY 8 SECONDS +/// Base time for a cable coil being used. +#define ELECTRICAL_DAMAGE_SUTURE_WIRE_BASE_DELAY 0.8 SECONDS +/// Global damage multiplier for the power a given electrical damage wound will add per tick. +#define ELECTRICAL_DAMAGE_POWER_PER_TICK_MULT 1 +/// Global damage multiplier for how much repairing wiring will reduce intensity. Higher is more. +#define ELECTRICAL_DAMAGE_SUTURE_WIRE_HEALING_AMOUNT_MULT 1 + +/// The minimum shock power we must have available to zap our victim. Must be at least one, since electrocute_act fails if its lower. +#define ELECTRICAL_DAMAGE_MINIMUM_SHOCK_POWER_PER_ZAP 1 +/// The maximum burn damage our limb can have before we refuse to let people who havent aggrograbbed the limb repair it with wires. This is so people can opt to just fix the burn damage. +#define ELECTRICAL_DAMAGE_MAX_BURN_DAMAGE_TO_LET_WIRES_REPAIR 5 + +/datum/wound/electrical_damage + name = "Electrical (Wires) Wound" + + simple_treat_text = "Replacing of broken wiring, or repairing via a wirecutter. Bandaging binds the wiring and reduces intensity buildup, \ + as does firmly grasping the limb - both the victim and someone else can do this. Roboticists/Engineers get a bonus to treatment, as do diagnostic HUDs." + homemade_treat_text = "Sutures can repair the wiring at reduced efficiency, as can retractors. In a pinch, high temperatures can repair the wiring!" + + wound_flags = (ACCEPTS_GAUZE|CAN_BE_GRASPED|SPLINT_OVERLAY) + + treatable_tools = list(TOOL_WIRECUTTER, TOOL_RETRACTOR) + treatable_by = list(/obj/item/stack/medical/suture) + treatable_by_grabbed = list(/obj/item/stack/cable_coil) + + default_scar_file = METAL_SCAR_FILE + + processes = TRUE + + /// How many sparks do we spawn when we're gained? + var/initial_sparks_amount = 1 + + /// How much of our damage is reduced if the target is shock immune. Percent. + var/shock_immunity_self_damage_reduction = 75 + + /// Mult for our damage if we are unimportant. + var/limb_unimportant_damage_mult = 0.8 + /// Mult for our progress if we are unimportant. + var/limb_unimportant_progress_mult = 0.8 + + /// The overall "intensity" of this wound. Goes up to [processing_full_shock_threshold], and is used for determining our effect scaling. Measured in deciseconds. + var/intensity + /// The time, in deciseconds, it takes to reach 100% power. + var/processing_full_shock_threshold = 3 MINUTES + /// If [intensity] is at or below this, we remove ourselves. + var/minimum_intensity = 0 + + /// How much shock power we add to [processing_shock_power_this_tick] per tick. Lower bound + var/processing_shock_power_per_second_min = 0.1 + /// How much shock power we add to [processing_shock_power_this_tick] per tick. Upper bound + var/processing_shock_power_per_second_max = 0.2 + + /// In the case we get below 1 power, we add the power to this buffer and use it next tick. + var/processing_shock_power_this_tick = 0 + /// The chance for each processed shock to stun the user. + var/processing_shock_stun_chance = 0 + /// The chance for each processed shock to spark. + var/processing_shock_spark_chance = 30 + /// The chance for each processed shock to message the user. + var/process_shock_message_chance = 80 + + /// Simple mult for how much of real time is added to [intensity]. + var/seconds_per_intensity_mult = 1 + + /// How many sparks we spawn if a shock sparks. Lower bound + var/process_shock_spark_count_min = 1 + /// How many sparks we spawn if a shock sparks. Upper bound + var/process_shock_spark_count_max = 1 + + // Generally should be less fast than wire, but its effectiveness should increase with severity + /// The percent, in decimal, a successful wirecut use will reduce intensity by. + var/wirecut_repair_percent + // Generally should be lower than wirecut + /// The percent, in decimal, a successful wire use will reduce intensity by. + var/wire_repair_percent + + /// The basic multiplier to all our effects. Damage, progress, etc. + var/overall_effect_mult = 1 + + /// The bodyheat our victim must be at or above to start getting passive healing. + var/heat_thresh_to_heal = (BODYTEMP_HEAT_DAMAGE_LIMIT + 30) + /// The mult that heat differences between normal and bodytemp threshold is multiplied against. Controls passive heat healing. + var/heat_differential_healing_mult = 0.08 + + /// Percent chance for a heat repair to give the victim a message. + var/heat_heal_message_chance = 20 + + /// If [get_intensity_mult()] is at or above this, the limb gets disabled. If null, it will never occur. + var/disable_at_intensity_mult + +/datum/wound_pregen_data/electrical_damage + abstract = TRUE + required_limb_biostate = (BIO_WIRED) + required_wounding_types = list(WOUND_SLASH) + wound_series = WOUND_SERIES_WIRE_SLASH_ELECTRICAL_DAMAGE + +/datum/wound_pregen_data/electrical_damage/generate_scar_priorities() + return list("[BIO_METAL]") // wire scars dont exist so we can just use metal + +/datum/wound/burn/electrical_damage/slash/get_limb_examine_description() + return span_warning("The wiring on this limb is slashed open.") + +/datum/wound/electrical_damage/handle_process(seconds_per_tick, times_fired) + . = ..() + + var/base_mult = get_base_mult() + + var/seconds_per_tick_for_intensity = seconds_per_tick * get_progress_mult() + seconds_per_tick_for_intensity = modify_progress_after_progress_mult(seconds_per_tick_for_intensity, seconds_per_tick) + + adjust_intensity(seconds_per_tick_for_intensity SECONDS) + + if (!victim || victim.stat == DEAD) + return + + var/damage_mult = get_damage_mult(victim) + var/intensity_mult = get_intensity_mult() + + damage_mult *= seconds_per_tick + damage_mult *= intensity_mult + + var/picked_damage = LERP(processing_shock_power_per_second_min, processing_shock_power_per_second_max, rand()) + processing_shock_power_this_tick += (picked_damage * damage_mult) + if (processing_shock_power_this_tick <= ELECTRICAL_DAMAGE_MINIMUM_SHOCK_POWER_PER_ZAP) + return + + var/stun_chance = (processing_shock_stun_chance * intensity_mult) * base_mult + var/spark_chance = (processing_shock_spark_chance * intensity_mult) * base_mult + + var/should_stun = SPT_PROB(stun_chance, seconds_per_tick) + var/should_message = SPT_PROB(process_shock_message_chance, seconds_per_tick) + + zap(victim, + processing_shock_power_this_tick, + stun = should_stun, + spark = SPT_PROB(spark_chance, seconds_per_tick), + animation = should_stun, message = FALSE, + message = should_stun, + tell_victim_if_no_message = should_message, + ignore_immunity = TRUE, + jitter_time = seconds_per_tick, + stutter_time = 0, + delay_stun = TRUE, + knockdown = TRUE, + ignore_gloves = TRUE + ) + processing_shock_power_this_tick = 0 + +/// If someone is aggrograbbing us and targetting our limb, intensity progress is multiplied against this. +#define LIMB_AGGROGRABBED_PROGRESS_MULT 0.5 + +/// Returns the multiplier used by our intensity progress. Intensity increment is multiplied against this. +/datum/wound/electrical_damage/proc/get_progress_mult() + var/progress_mult = get_base_mult() * seconds_per_intensity_mult + + if (!limb_essential()) + progress_mult *= limb_unimportant_progress_mult + + if (isliving(victim.pulledby)) + var/mob/living/living_puller = victim.pulledby + if (living_puller.grab_state >= GRAB_AGGRESSIVE && living_puller.zone_selected == limb.body_zone) + progress_mult *= LIMB_AGGROGRABBED_PROGRESS_MULT // they're holding it down + + if (victim.stat == DEAD) + progress_mult *= ELECTRICAL_DAMAGE_DEAD_PROGRESS_MULT // doesnt totally stop it but slows it down a lot + + return progress_mult +#undef LIMB_AGGROGRABBED_PROGRESS_MULT + +/// Returns the multiplier used by the damage we deal. +/datum/wound/electrical_damage/proc/get_damage_mult(mob/living/target) + SHOULD_BE_PURE(TRUE) + + var/damage_mult = get_base_mult() + + if (!limb_essential()) + damage_mult *= limb_unimportant_damage_mult + + return damage_mult * ELECTRICAL_DAMAGE_POWER_PER_TICK_MULT + +/// Returns the global multiplier used by both progress and damage. +/datum/wound/electrical_damage/proc/get_base_mult() + var/base_mult = 1 + + if (victim) + if (IS_IN_STASIS(victim)) + base_mult *= ELECTRICAL_DAMAGE_ON_STASIS_MULT + if (victim.body_position == LYING_DOWN) + base_mult *= ELECTRICAL_DAMAGE_LYING_DOWN_MULT + if (limb.grasped_by) + base_mult *= ELECTRICAL_DAMAGE_GRASPED_MULT + + if (victim.has_status_effect(/datum/status_effect/determined)) + base_mult *= WOUND_DETERMINATION_BLEED_MOD + + if (HAS_TRAIT(victim, TRAIT_SHOCKIMMUNE)) // it'd be a bit cheesy to just become immune to this, so it only makes it a lot lot better + base_mult *= shock_immunity_self_damage_reduction + + var/splint_mult = (limb.current_gauze ? limb.current_gauze.splint_factor : 1) + base_mult *= splint_mult + + return overall_effect_mult * base_mult + +/// Is called after seconds_for_intensity is modified by get_progress_mult(). +/datum/wound/electrical_damage/proc/modify_progress_after_progress_mult(seconds_for_intensity, seconds_per_tick) + if (!victim) + return seconds_for_intensity + + return seconds_for_intensity - (get_heat_healing() * seconds_per_tick) + +/// Returns how many deciseconds progress should be reduced by, based on the current heat of our victim's body. +/datum/wound/electrical_damage/proc/get_heat_healing(do_message = prob(heat_heal_message_chance)) + var/healing_amount = max((victim.bodytemperature - heat_thresh_to_heal), 0) * heat_differential_healing_mult + if (do_message && healing_amount) + to_chat(victim, span_notice("You feel the solder within your [limb.plaintext_zone] reform and repair your [name]...")) + + return healing_amount + +/// Changes intensity by the given amount, and then updates our status, removing ourselves if fixed. +/datum/wound/electrical_damage/proc/adjust_intensity(to_adjust) + intensity = clamp((intensity + to_adjust), 0, processing_full_shock_threshold) + + if (disable_at_intensity_mult) + set_disabling(get_intensity_mult() >= disable_at_intensity_mult) + + remove_if_fixed() + +/datum/wound/electrical_damage/wound_injury(datum/wound/electrical_damage/old_wound, attack_direction) + . = ..() + + if (old_wound) + intensity = max(intensity, old_wound.intensity) + processing_shock_power_this_tick = old_wound.processing_shock_power_this_tick + + do_sparks(initial_sparks_amount, FALSE, victim) + +/datum/wound/electrical_damage/modify_desc_before_span(desc, mob/user) + . = ..() + + if (limb.current_gauze) + return + + var/intensity_mult = get_intensity_mult() + if (intensity_mult < 0.2 || (victim.stat == DEAD)) + return + + . += ", and " + + var/extra + switch (intensity_mult) + if (0.2 to 0.4) + extra += "[span_deadsay("is letting out some sparks")]" + if (0.4 to 0.6) + extra += "[span_deadsay("is sparking quite a bit")]" + if (0.6 to 0.8) + extra += "[span_deadsay("is practically hemorrhaging sparks")]" + if (0.8 to 1) + extra += "[span_deadsay("has golden bolts of electricity constantly striking the surface")]" + + . += extra + +/datum/wound/electrical_damage/get_scanner_description(mob/user) + . = ..() + + . += "\nWound status: [get_wound_status_info()]" + +/datum/wound/electrical_damage/get_simple_scanner_description(mob/user) + . = ..() + + . += "\nWound status: [get_wound_status_info()]" + +/// Returns a string with our fault intensity and threshold to removal for use in health analyzers. +/datum/wound/electrical_damage/proc/get_wound_status_info() + return "Fault intensity is currently at [span_bold("[get_intensity_mult() * 100]")]%. It must be reduced to [span_blue("[minimum_intensity]")]% to remove the wound." + +// this wound is unaffected by cryoxadone and pyroxadone +/datum/wound/electrical_damage/on_xadone(power) + return + +/datum/wound/electrical_damage/item_can_treat(obj/item/potential_treater, mob/user) + if (istype(potential_treater, /obj/item/stack/cable_coil) && ((user.pulling == victim && user.grab_state >= GRAB_AGGRESSIVE) || (limb.burn_dam <= ELECTRICAL_DAMAGE_MAX_BURN_DAMAGE_TO_LET_WIRES_REPAIR))) + return TRUE // if we're aggrograbbed, or relatively undamaged, go ahead. else, we dont want to impede normal treatment + + return ..() + +/datum/wound/electrical_damage/treat(obj/item/treating_item, mob/user) + if (treating_item.tool_behaviour == TOOL_WIRECUTTER || treating_item.tool_behaviour == TOOL_RETRACTOR) + return wirecut(treating_item, user) + + if (istype(treating_item, /obj/item/stack/medical/suture) || istype(treating_item, /obj/item/stack/cable_coil)) + return suture_wires(treating_item, user) + + return ..() + +/** + * The "trauma" treatment, done with cables/sutures. Sutures get a debuff. + * Low self-tend penalty. + * Very fast, but low value. Eats up wires for breakfast. + * Has limited wire/HUD bonuses. If you're a robo, use a wirecutter instead. + */ +/datum/wound/electrical_damage/proc/suture_wires(obj/item/stack/suturing_item, mob/living/carbon/human/user) + if (!suturing_item.tool_start_check()) + return TRUE + + var/is_suture = (istype(suturing_item, /obj/item/stack/medical/suture)) + + var/change = (processing_full_shock_threshold * wire_repair_percent) * ELECTRICAL_DAMAGE_SUTURE_WIRE_HEALING_AMOUNT_MULT + var/delay_mult = 1 + if (user == victim) + delay_mult *= 1.5 + if (is_suture) + delay_mult *= 2 + var/obj/item/stack/medical/suture/suture_item = suturing_item + var/obj/item/stack/medical/suture/base_suture = /obj/item/stack/medical/suture + change += (suture_item.heal_brute - initial(base_suture.heal_brute)) + + // as this is the trauma treatment, there are less bonuses + // if youre doing this, youre probably doing this on-the-spot + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + delay_mult *= 0.8 + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + delay_mult *= 0.9 + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + delay_mult *= 0.8 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + change *= 1.2 + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + var/replacing_or_suturing = (is_suture ? "repairing some" : "replacing") + while (suturing_item.tool_start_check()) + user?.visible_message(span_danger("[user] begins [replacing_or_suturing] wiring within [their_or_other] [limb.plaintext_zone] with [suturing_item]..."), \ + span_notice("You begin [replacing_or_suturing] wiring within [your_or_other] [limb.plaintext_zone] with [suturing_item]...")) + if (!suturing_item.use_tool(target = victim, user = user, delay = ELECTRICAL_DAMAGE_SUTURE_WIRE_BASE_DELAY * delay_mult, amount = 1, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + if (user != victim && user.combat_mode) + user?.visible_message(span_danger("[user] mangles some of [their_or_other] [limb.plaintext_zone]'s wiring!"), \ + span_danger("You mangle some of [your_or_other] [limb.plaintext_zone]'s wiring!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[capitalize(your_or_other)] mangles some of your [limb.plaintext_zone]'s wiring!")) + adjust_intensity(change * 2) + else + var/repairs_or_replaces = (is_suture ? "repairs" : "replaces") + var/repair_or_replace = (is_suture ? "repair" : "replace") + user?.visible_message(span_notice("[user] [repairs_or_replaces] some of [their_or_other] [limb.plaintext_zone]'s wiring!"), \ + span_notice("You [repair_or_replace] some of [your_or_other] [limb.plaintext_zone]'s wiring!")) + adjust_intensity(-change) + victim.balloon_alert(user, "intensity reduced to [get_intensity_mult() * 100]%") + + if (fixed()) + return TRUE + return TRUE + +/** + * The "proper" treatment, done with wirecutters/retractors. Retractors get a debuff. + * High self-tend penalty. + * Slow, but high value. + * Has high wire/HUD bonuses. The ideal treatment for a robo. + */ +/datum/wound/electrical_damage/proc/wirecut(obj/item/wirecutting_tool, mob/living/carbon/human/user) + if (!wirecutting_tool.tool_start_check()) + return TRUE + + var/is_retractor = (wirecutting_tool.tool_behaviour == TOOL_RETRACTOR) + + var/change = (processing_full_shock_threshold * wirecut_repair_percent) + var/delay_mult = 1 + if (user == victim) + delay_mult *= 2.5 + if (is_retractor) + delay_mult *= 2 + change *= 0.8 + var/knows_wires = FALSE + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + delay_mult *= 0.9 + change *= 1.7 + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + change *= 1.35 + knows_wires = TRUE + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + delay_mult *= 0.9 + else + delay_mult *= 0.75 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.8 + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + while (wirecutting_tool.tool_start_check()) + user?.visible_message(span_danger("[user] begins resetting misplaced wiring within [their_or_other] [limb.plaintext_zone]..."), \ + span_notice("You begin resetting misplaced wiring within [your_or_other] [limb.plaintext_zone]...")) + if (!wirecutting_tool.use_tool(target = victim, user = user, delay = ELECTRICAL_DAMAGE_WIRECUTTER_BASE_DELAY * delay_mult, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + if (user != victim && user.combat_mode) + user?.visible_message(span_danger("[user] mangles some of [their_or_other] [limb.plaintext_zone]'s wiring!"), \ + span_danger("You mangle some of [your_or_other] [limb.plaintext_zone]'s wiring!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[capitalize(your_or_other)] mangles some of your [limb.plaintext_zone]'s wiring!")) + adjust_intensity(change * 2) + else + user?.visible_message(span_notice("[user] resets some of [their_or_other] [limb.plaintext_zone]'s wiring!"), \ + span_notice("You reset some of [your_or_other] [limb.plaintext_zone]'s wiring!")) + adjust_intensity(-change) + victim.balloon_alert(user, "intensity reduced to [get_intensity_mult() * 100]%") + + if (fixed()) + return TRUE + return TRUE + +/// If fixed() is true, we remove ourselves and return TRUE. FALSE otherwise. +/datum/wound/electrical_damage/proc/remove_if_fixed() + if (fixed()) + to_chat(victim, span_green("Your [limb.plaintext_zone] has recovered from its [name]!")) + remove_wound() + return TRUE + return FALSE + +/// Should we remove ourselves? +/datum/wound/electrical_damage/proc/fixed() + return (intensity <= minimum_intensity || isnull(limb)) + +/// Returns the multiplier we apply to our outgoing damage based off our current intensity. Is always between 0-1. +/datum/wound/electrical_damage/proc/get_intensity_mult() + return (min((intensity / processing_full_shock_threshold), 1)) + +/// Wrapper for electrocute_act +/datum/wound/electrical_damage/proc/zap( + mob/living/target, + damage, + coeff = 1, + stun, + spark = TRUE, + animation = TRUE, + message = TRUE, + ignore_immunity = FALSE, + delay_stun = FALSE, + knockdown = FALSE, + ignore_gloves = FALSE, + tell_victim_if_no_message = TRUE, + jitter_time = 20 SECONDS, + stutter_time = 4 SECONDS, +) + + var/flags = NONE + if (!stun) + flags |= SHOCK_NOSTUN + if (!animation) + flags |= SHOCK_NO_HUMAN_ANIM + if (!message) + flags |= SHOCK_SUPPRESS_MESSAGE + if (tell_victim_if_no_message && target == victim) + to_chat(target, span_warning("Your [limb.plaintext_zone] short-circuits and zaps you!")) + if (ignore_immunity) + flags |= SHOCK_IGNORE_IMMUNITY + if (delay_stun) + flags |= SHOCK_DELAY_STUN + if (knockdown) + flags |= SHOCK_KNOCKDOWN + if (ignore_gloves) + flags |= SHOCK_NOGLOVES + + target.electrocute_act(damage, limb, coeff, flags, jitter_time, stutter_time) + if (spark) + do_sparks(rand(process_shock_spark_count_min, process_shock_spark_count_max), FALSE, victim) + +// Slash +// Fast to rise, but lower damage overall +// Also a bit easy to treat +/datum/wound/electrical_damage/slash + simple_desc = "Wiring has been slashed open, resulting in a fault that quickly intensifies!" + +/datum/wound/electrical_damage/slash/moderate + name = "Frayed Wiring" + desc = "Internal wiring has suffered a slight abrasion, causing a slow electrical fault that will intensify over time." + occur_text = "lets out a few sparks, as a few frayed wires stick out" + examine_desc = "has a few frayed wires sticking out" + treat_text = "Replacing of damaged wiring, though repairs via wirecutting instruments or sutures may suffice, albeit at limited efficiency. In case of emergency, \ + subject may be subjected to high temperatures to allow solder to reset." + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg' + + severity = WOUND_SEVERITY_MODERATE + + sound_volume = 30 + + threshold_penalty = 20 + + intensity = 10 SECONDS + processing_full_shock_threshold = 3 MINUTES + + processing_shock_power_per_second_max = 0.5 + processing_shock_power_per_second_min = 0.4 + + processing_shock_stun_chance = 0 + processing_shock_spark_chance = 30 + + process_shock_spark_count_max = 1 + process_shock_spark_count_min = 1 + + wirecut_repair_percent = 0.085 // not even faster at this point + wire_repair_percent = 0.035 + + initial_sparks_amount = 1 + + status_effect_type = /datum/status_effect/wound/electrical_damage/slash/moderate + + a_or_from = "from" + + scar_keyword = "slashmoderate" + +/datum/wound_pregen_data/electrical_damage/slash/moderate + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/slash/moderate + threshold_minimum = 35 + +/datum/wound/electrical_damage/slash/severe + name = "Severed Conduits" + desc = "A number of wires have been completely cut, resulting in electrical faults that will intensify at a worrying rate." + occur_text = "sends some electrical fiber in the direction of the blow, beginning to profusely spark" + examine_desc = "has multiple severed wires visible to the outside" + treat_text = "Containment of damaged wiring via gauze, then application of fresh wiring/sutures, or resetting of displaced wiring via wirecutter/retractor." + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T2.ogg' + + severity = WOUND_SEVERITY_SEVERE + + sound_volume = 15 + + threshold_penalty = 30 + + intensity = 10 SECONDS + processing_full_shock_threshold = 2 MINUTES + + processing_shock_power_per_second_max = 0.7 + processing_shock_power_per_second_min = 0.6 + + processing_shock_stun_chance = 0 + processing_shock_spark_chance = 60 + + process_shock_spark_count_max = 2 + process_shock_spark_count_min = 1 + + wirecut_repair_percent = 0.1 + wire_repair_percent = 0.032 + + initial_sparks_amount = 3 + + status_effect_type = /datum/status_effect/wound/electrical_damage/slash/severe + + a_or_from = "from" + + scar_keyword = "slashsevere" + +/datum/wound_pregen_data/electrical_damage/slash/severe + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/slash/severe + threshold_minimum = 60 + +/datum/wound/electrical_damage/slash/critical + name = "Systemic Fault" + desc = "A significant portion of the power distribution network has been cut open, resulting in massive power loss and runaway electrocution." + occur_text = "lets out a violent \"zhwarp\" sound as angry electric arcs attack the surrounding air" + examine_desc = "has lots of wires mauled wires sticking out" + treat_text = "Immediate securing via gauze, followed by emergency cable replacement and securing via wirecutters or retractor. \ + If the fault has become uncontrollable, extreme heat therapy is recommended." + + severity = WOUND_SEVERITY_CRITICAL + wound_flags = (ACCEPTS_GAUZE|MANGLES_INTERIOR|CAN_BE_GRASPED|SPLINT_OVERLAY) + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg' + + sound_volume = 30 + + threshold_penalty = 50 + + intensity = 10 SECONDS + processing_full_shock_threshold = 1.25 MINUTES + + processing_shock_power_per_second_max = 1.3 + processing_shock_power_per_second_min = 1.1 + + processing_shock_stun_chance = 5 + processing_shock_spark_chance = 90 + + process_shock_spark_count_max = 3 + process_shock_spark_count_min = 2 + + wirecut_repair_percent = 0.12 + wire_repair_percent = 0.03 + + initial_sparks_amount = 8 + + status_effect_type = /datum/status_effect/wound/electrical_damage/slash/critical + + a_or_from = "a" + + scar_keyword = "slashcritical" + +/datum/wound_pregen_data/electrical_damage/slash/critical + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/slash/critical + threshold_minimum = 100 + +#undef ELECTRICAL_DAMAGE_ON_STASIS_MULT +#undef ELECTRICAL_DAMAGE_GRASPED_MULT +#undef ELECTRICAL_DAMAGE_LYING_DOWN_MULT +#undef ELECTRICAL_DAMAGE_DEAD_PROGRESS_MULT + +#undef ELECTRICAL_DAMAGE_WIRECUTTER_BASE_DELAY +#undef ELECTRICAL_DAMAGE_SUTURE_WIRE_BASE_DELAY + +#undef ELECTRICAL_DAMAGE_MINIMUM_SHOCK_POWER_PER_ZAP +#undef ELECTRICAL_DAMAGE_MAX_BURN_DAMAGE_TO_LET_WIRES_REPAIR +#undef ELECTRICAL_DAMAGE_POWER_PER_TICK_MULT +#undef ELECTRICAL_DAMAGE_SUTURE_WIRE_HEALING_AMOUNT_MULT diff --git a/modular_skyrat/modules/medical/code/wounds/wound_effects.dm b/modular_skyrat/modules/medical/code/wounds/wound_effects.dm new file mode 100644 index 00000000000..8f9aef16210 --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/wound_effects.dm @@ -0,0 +1,33 @@ +/datum/status_effect/wound/blunt/robotic/moderate + id = "unsecure_moderate" + +/datum/status_effect/wound/blunt/robotic/severe + id = "unsecure_severe" + +/datum/status_effect/wound/blunt/robotic/critical + id = "unsecure_critical" + +/datum/status_effect/wound/electrical_damage/slash/moderate + id = "electric_slash_moderate" + +/datum/status_effect/wound/electrical_damage/slash/severe + id = "electric_slash_severe" + +/datum/status_effect/wound/electrical_damage/slash/critical + id = "electric_slash_critical" + +/datum/status_effect/wound/electrical_damage/pierce/moderate + id = "electric_pierce_moderate" + +/datum/status_effect/wound/electrical_damage/pierce/severe + id = "electric_pierce_severe" + +/datum/status_effect/wound/electrical_damage/pierce/critical + id = "electric_pierce_critical" + +/datum/status_effect/wound/burn/robotic/moderate + id = "overheated" +/datum/status_effect/wound/burn/robotic/severe + id = "warpedmetal" +/datum/status_effect/wound/burn/robotic/critical + id = "demagnetizedmetal" diff --git a/modular_skyrat/modules/medical/readme.md b/modular_skyrat/modules/medical/readme.md new file mode 100644 index 00000000000..6ab0af32ddf --- /dev/null +++ b/modular_skyrat/modules/medical/readme.md @@ -0,0 +1,51 @@ + + +https://github.com/Skyrat-SS13/Skyrat-tg/pull/2336 +https://github.com/Skyrat-SS13/Skyrat-tg/pull/23733 + +## Skyrat Medical Update + +Module ID: SKYRAT_MEDICAL_UPDATE + +### Description: + +Various changes to the medical system, from adding bandage overlays, to new wounds, to modularized procs. + + + +### TG Proc/File Changes: + +- code/_DEFINES/wounds.dm: Added muscle/synth wound series, added them to the global list of wound series +- cat2_medicine_reagents.dm: /datum/reagent/medicine/c2/hercuri/on_mob_life, Allowed hercuri to affect synthetics, also changed hercuri process flags for this purpose +- quirks.dm: Commented out the quadruple_amputee/frail blacklist as frail can now apply to prosthetics + + +### Modular Overrides: + +- N/A + + +### Defines: + +- Many local synthetic wound defines + + +### Included files that are not contained in this module: + +- strings/wounds/metal_scar_desc.json -- Required to be here for _string_lists.dm usage + + +### Credits: + +Azarak - Original medical update, muscle wounds, bandage overlays +Niko - Synthetic wounds +TG coding/Skyrat coding channels and community - Support, ideas, reviews + + diff --git a/modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg b/modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cb7b3d0a79f49992a1d59f686b5b91c7176f9ae2 GIT binary patch literal 34541 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�>@N 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 x{;Oy6Z0f2#Sm73|UL_hgTVo};BNTRM3?@C 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 literal 0 HcmV?d00001 diff --git a/modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg b/modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f0ea8e2217027a04c58ce38f27925175106b34c7 GIT binary patch literal 63099 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