From 0f6496a55ceefa0f1bf1668fcef49b5182471695 Mon Sep 17 00:00:00 2001 From: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com> Date: Fri, 12 Jun 2020 07:47:33 -0400 Subject: [PATCH] [READY] Adds Medical Wounds: Bamboo Bones and the Skin of Your Teeth (#50558) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit About The Pull Request This PR adds medical wounds, new forms of injuries that people can suffer that cause debilitation and complications, and often require more than what can be found in a medkit to treat. But let's be honest, big complicated walls of text about medical changes make people's eyes glaze over easily- so I created a handy infograph to explain the basics! Also there's a full guide here! dreamseeker_2020-04-18_20-42-19.png The infograph may not be fully up to date with the specifics of the PR's status, but it'll be updated along with major changes so people have something to use as a crash course for familiarizing themselves with how wounds function. I also have another infograph with all 9 of the possible initial wounds coming, and will be up soon. You can also find the longform design doc here with more info on the broad details, including descriptions of treatments: hackmd whee What this does There's a lot to cover, but here's the bullet points of the main features and changes: Getting lots of damage on a limb can result in wounds, with more damage causing worse wounds. These can range from dislocated joints and minor cuts to compound fractures and fourth degree burns, and can affect you in different ways depending on what bodypart they're applied to (namely with broken bones). You can damage individual bodyparts on clothing (only jumpsuits for now) through the use of lasers and sharp weapons. Bodyparts that reach max damage are considered "shredded" and will not apply any protection for that zone until it is repaired with cloth. If all zones are disabled, the entire piece of clothing is shredded and unwearable until repaired with 3 cloth. Jumpsuits give a small amount of wound protection, and since sharp weapons and lasers generally get extra wound bonuses against bare flesh, even a plain jumpsuit provides decent protection from a few laser shots or scalpel stabs. Lasers gain a powerful niche versus unarmored/lightly armored carbons! As noted above, lasers can shred clothing and burn away zones of jumpsuits in 2 shots each, after which the target's bare flesh is exposed (barring other clothing), and lasers excel at dealing burn wounds against uncovered skin. Think big, nasty charring! Bleeding is now totally limb based, and gauze is as well. Bleeding is also 95% cut wound based, meaning sharp weapons make you bleed rather than just having 40+ brute on a limb. The more wounds and damage you get on a bodypart, the easier it'll be to gain more severe wounds. Wounds are arranged from Moderate, to Severe, to Critical in increasing severity, and you'll generally have to suffer the lesser ones before getting the worse ones. dreamseeker_2020-05-15_03-15-59.png Above: Someone having an incredibly bad day from bloodloss dreamseeker_2020-05-04_22-29-29.png Above: Scars from healed wounds ShareX_2020-05-15_06-55-20.png Above: Actual combat involving someone's head getting cracked Here's a quick, if non-exhaustive, list of things I have left to do before I consider it feature complete Finish adding treatments for each wound type/severity (mostly surgeries/triage for critical wounds) Add second winds for bad injuries to give the victim a chance to get away Flesh out severe & critical injuries in general Find sprites for the bonesetter, bone gel, and anything else that might be needed Add the medical items for treating the less severe wounds to the station Polish code and remove any redundancies I left behind Quick balance pass to make sure nothing is horribly abuseable Why It's Good For The Game Adds a flexible new system for representing damage on carbons with injuries that can be treated in different ways. Moderate wounds from getting toolboxed or sliced with a scalpel can usually be treated by a buddy or even by yourself with the right tools, but getting flayed with a fireaxe or a laser gun emptied into your bare skin may require extra attention or even surgery in bad cases! Also makes laser guns cooler and more like 40k lasguns that can flash fry people (cool!) This should also make spessmen more resilient and harder to kill outright, while still adding consequences and complications to getting hurt. Wounds aren't immediately fatal, but they can do things like slow down interactions, deal damage over time through infections, and generally make you more fragile until fixed. They can also give you a "second wind" on being applied that gives you a small adrenaline boost (or whatever) to help disengage and escape immediate danger. Changelog 🆑 Ryll/Shaps add: Introduces medical wounds, new injuries that can happen to fleshy carbons when they sustain lots of damage on a bodypart. There's quite a lot of change here, but you can read the guide at: https://tgstation13.org/wiki/Guide_to_wounds and an extended changelog is available here: https://hackmd.io/l_FI9b3tSqa_woDadewJXA add: Introduces scars and temporal scarring! Healing a wound leaves a scar behind that can be seen by examining someone twice rapidly, and if Temporal Scarring is enabled in character prefs, surviving a round with scars will save them to be granted at roundstart another round! Let your body tell stories! tweak: Bleeding is now fully bodypart-focused, and 95% of bleeding comes from cut wounds from sharp weapons. Gauze is applied on a limb-by-limb basis, and helps staunch bloodflow rather than totally stop it. Notably, you no longer bleed just from having 40+ brute damage on a limb. del: Organic bodyparts are no longer disabled at maximum damage, but are easier to cause wounds to add: O2 medkits in emergency lockers have been replaced with new emergency medkits with basic tools for diagnosing and treating wounds and basic damage tweak: Herapin now rapidly increases bleeding on all open cuts, rather than causing bleeding by itself. The more cuts on the target, the more it will affect them. tweak: Neckgrab table slams now hit the targeted limb rather than just the head, with a large chance to dislocate or break a bone tweak: Sharp weapons and burning weapons can now shred zones on jumpsuits, disabling protection on that limb. Damaged clothes can be repaired with cloth. tweak: Slaughter demons now deal less raw damage, but gain the ability to cause cut wounds, which becomes more powerful with each attack on a humanoid but resets when bloodcrawling. /🆑 --- code/__DEFINES/DNA.dm | 2 + code/__DEFINES/admin.dm | 3 + code/__DEFINES/dcs/signals.dm | 15 +- code/__DEFINES/mobs.dm | 10 +- code/__DEFINES/obj_flags.dm | 5 + code/__DEFINES/status_effects.dm | 4 + code/__DEFINES/tools.dm | 1 + code/__DEFINES/traits.dm | 2 +- code/__DEFINES/wounds.dm | 43 ++ code/__HELPERS/_logging.dm | 4 + code/__HELPERS/type2type.dm | 18 +- code/_onclick/other_mobs.dm | 6 +- code/controllers/subsystem/persistence.dm | 22 + code/controllers/subsystem/shuttle.dm | 1 + code/datums/armor.dm | 27 +- code/datums/brain_damage/magic.dm | 2 +- code/datums/components/butchering.dm | 13 +- code/datums/components/caltrop.dm | 2 +- code/datums/components/embedded.dm | 10 +- code/datums/components/tackle.dm | 1 + .../diseases/advance/symptoms/flesh_eating.dm | 3 +- .../diseases/advance/symptoms/sneeze.dm | 2 +- code/datums/martial/sleeping_carp.dm | 8 +- code/datums/mind.dm | 5 + .../mood_events/generic_negative_events.dm | 10 +- code/datums/mutations/body.dm | 4 +- code/datums/skills/medical.dm | 3 +- code/datums/status_effects/buffs.dm | 4 + code/datums/status_effects/debuffs.dm | 13 +- code/datums/status_effects/status_effect.dm | 4 + code/datums/status_effects/wound_effects.dm | 186 +++++++ code/datums/traits/negative.dm | 2 +- code/datums/traits/neutral.dm | 16 + code/datums/wounds/_wounds.dm | 320 ++++++++++++ code/datums/wounds/bones.dm | 461 ++++++++++++++++ code/datums/wounds/burns.dm | 323 ++++++++++++ code/datums/wounds/cuts.dm | 309 +++++++++++ code/datums/wounds/scars/_scars.dm | 134 +++++ code/game/atoms.dm | 44 ++ code/game/machinery/doors/door.dm | 4 + code/game/machinery/medical_kiosk.dm | 2 +- code/game/objects/items/devices/flashlight.dm | 14 +- code/game/objects/items/devices/scanners.dm | 91 +++- code/game/objects/items/dualsaber.dm | 2 + code/game/objects/items/fireaxe.dm | 1 + code/game/objects/items/grenades/flashbang.dm | 8 + code/game/objects/items/holy_weapons.dm | 3 + code/game/objects/items/kitchen.dm | 2 + code/game/objects/items/manuals.dm | 4 +- code/game/objects/items/melee/misc.dm | 5 + code/game/objects/items/melee/transforming.dm | 2 + code/game/objects/items/powerfist.dm | 2 +- code/game/objects/items/shrapnel.dm | 18 +- code/game/objects/items/spear.dm | 2 + code/game/objects/items/stacks/medical.dm | 187 +++++-- code/game/objects/items/stacks/stack.dm | 10 + code/game/objects/items/stacks/tape.dm | 14 + code/game/objects/items/storage/backpack.dm | 3 + code/game/objects/items/storage/belt.dm | 8 +- code/game/objects/items/storage/firstaid.dm | 22 +- code/game/objects/items/storage/toolbox.dm | 1 + code/game/objects/items/weaponry.dm | 4 +- code/game/objects/objs.dm | 5 + .../crates_lockers/closets/utility_closets.dm | 4 +- code/game/objects/structures/guillotine.dm | 2 +- code/game/objects/structures/tables_racks.dm | 22 +- code/modules/admin/verbs/randomverbs.dm | 33 +- .../blob/blobstrains/blazing_oil.dm | 2 +- .../blob/blobstrains/cryogenic_poison.dm | 2 +- .../blob/blobstrains/electromagnetic_web.dm | 2 +- .../blob/blobstrains/explosive_lattice.dm | 6 +- .../blob/blobstrains/networked_fibers.dm | 4 +- .../blob/blobstrains/pressurized_slime.dm | 2 +- .../blob/blobstrains/replicating_foam.dm | 2 +- .../blob/blobstrains/shifting_fragments.dm | 2 +- .../blob/blobstrains/synchronous_mesh.dm | 4 +- .../changeling/powers/fleshmend.dm | 2 +- .../changeling/powers/mutations.dm | 2 + .../changeling/powers/regenerate.dm | 3 + code/modules/antagonists/cult/cult_items.dm | 6 +- code/modules/antagonists/cult/ritual.dm | 2 +- .../antagonists/slaughter/slaughter.dm | 48 +- .../antagonists/slaughter/slaughter_antag.dm | 1 + .../components/unary_devices/cryo.dm | 33 +- code/modules/cargo/goodies.dm | 10 +- code/modules/cargo/packs.dm | 2 + code/modules/client/client_defines.dm | 2 + code/modules/client/preferences.dm | 24 + code/modules/client/preferences_savefile.dm | 21 + code/modules/clothing/clothing.dm | 170 +++++- code/modules/clothing/gloves/_gloves.dm | 2 +- code/modules/clothing/head/_head.dm | 2 +- code/modules/clothing/masks/_masks.dm | 2 +- code/modules/clothing/shoes/_shoes.dm | 2 +- code/modules/clothing/spacesuits/hardsuit.dm | 60 +-- code/modules/clothing/suits/_suits.dm | 3 +- code/modules/clothing/suits/armor.dm | 18 +- code/modules/clothing/suits/wiz_robe.dm | 2 +- code/modules/clothing/under/_under.dm | 5 +- code/modules/clothing/under/jobs/cargo.dm | 2 +- code/modules/clothing/under/jobs/command.dm | 1 + code/modules/clothing/under/jobs/security.dm | 8 +- .../food_and_drinks/food/snacks_other.dm | 1 + .../browserassets/css/browserOutput.css | 2 + .../browserassets/css/browserOutput_white.css | 2 + code/modules/hydroponics/grown/nettle.dm | 1 + .../jobs/job_types/chief_medical_officer.dm | 4 +- code/modules/jobs/job_types/paramedic.dm | 2 +- .../modules/mining/equipment/explorer_gear.dm | 4 +- .../modules/mob/dead/new_player/new_player.dm | 13 + code/modules/mob/inventory.dm | 1 - code/modules/mob/living/blood.dm | 61 +-- code/modules/mob/living/brain/brain_item.dm | 4 +- code/modules/mob/living/carbon/carbon.dm | 97 +++- .../mob/living/carbon/carbon_defense.dm | 11 +- .../mob/living/carbon/carbon_defines.dm | 5 + .../modules/mob/living/carbon/damage_procs.dm | 22 +- code/modules/mob/living/carbon/examine.dm | 40 ++ .../mob/living/carbon/human/damage_procs.dm | 4 +- .../mob/living/carbon/human/examine.dm | 71 ++- code/modules/mob/living/carbon/human/human.dm | 10 + .../mob/living/carbon/human/human_defense.dm | 57 +- .../mob/living/carbon/human/human_defines.dm | 1 - .../mob/living/carbon/human/human_helpers.dm | 19 + .../mob/living/carbon/human/species.dm | 15 +- .../carbon/human/species_types/humans.dm | 2 +- .../human/species_types/lizardpeople.dm | 4 +- .../carbon/human/species_types/mothmen.dm | 2 +- .../human/species_types/shadowpeople.dm | 2 + .../carbon/human/species_types/zombies.dm | 6 +- code/modules/mob/living/carbon/life.dm | 6 + .../mob/living/carbon/monkey/punpun.dm | 2 + code/modules/mob/living/damage_procs.dm | 4 +- code/modules/mob/living/life.dm | 5 + code/modules/mob/living/living.dm | 2 +- code/modules/mob/living/living_defense.dm | 4 +- .../mob/living/silicon/damage_procs.dm | 2 +- .../mob/living/silicon/robot/robot_modules.dm | 2 + .../mob/living/simple_animal/hostile/bear.dm | 15 +- .../hostile/megafauna/hierophant.dm | 2 +- .../simple_animal/hostile/megafauna/legion.dm | 2 + .../hostile/megafauna/wendigo.dm | 2 +- .../living/simple_animal/hostile/syndicate.dm | 3 + .../mob/living/simple_animal/simple_animal.dm | 7 + code/modules/mob/mob.dm | 18 +- .../ammunition/ballistic/shotgun.dm | 12 + .../projectiles/ammunition/energy/laser.dm | 5 + code/modules/projectiles/gun.dm | 5 + code/modules/projectiles/guns/energy/laser.dm | 7 + code/modules/projectiles/projectile.dm | 5 + code/modules/projectiles/projectile/beams.dm | 18 + .../modules/projectiles/projectile/bullets.dm | 1 + .../projectile/bullets/revolver.dm | 3 + .../projectiles/projectile/bullets/shotgun.dm | 15 +- .../reagents/cat2_medicine_reagents.dm | 2 + .../chemistry/reagents/medicine_reagents.dm | 24 +- .../chemistry/reagents/other_reagents.dm | 33 ++ .../chemistry/reagents/toxin_reagents.dm | 16 +- .../reagents/reagent_containers/hypospray.dm | 13 +- .../research/designs/autolathe_designs.dm | 18 + code/modules/research/techweb/all_nodes.dm | 4 +- .../xenobiology/crossbreeding/_misc.dm | 2 +- code/modules/spells/spell_types/bloodcrawl.dm | 5 + code/modules/spells/spell_types/shapeshift.dm | 4 +- .../bodyparts/{bodyparts.dm => _bodyparts.dm} | 491 +++++++----------- .../surgery/bodyparts/dismemberment.dm | 26 +- code/modules/surgery/bodyparts/head.dm | 3 + code/modules/surgery/bodyparts/helpers.dm | 9 + code/modules/surgery/bodyparts/parts.dm | 307 +++++++++++ code/modules/surgery/bone_mending.dm | 142 +++++ code/modules/surgery/burn_dressing.dm | 108 ++++ code/modules/surgery/coronary_bypass.dm | 9 +- .../surgery/experimental_dissection.dm | 4 +- code/modules/surgery/healing.dm | 2 +- code/modules/surgery/organic_steps.dm | 14 +- code/modules/surgery/organs/vocal_cords.dm | 5 +- code/modules/surgery/surgery.dm | 7 + code/modules/surgery/surgery_helpers.dm | 6 +- code/modules/surgery/tools.dm | 19 +- code/modules/vending/_vending.dm | 27 +- code/modules/vending/medical.dm | 7 +- code/modules/vending/medical_wall.dm | 4 +- code/modules/vending/robotics.dm | 1 + code/modules/zombie/items.dm | 3 + icons/obj/guns/energy.dmi | Bin 39649 -> 40325 bytes icons/obj/lighting.dmi | Bin 77910 -> 77801 bytes sound/effects/blood1.ogg | Bin 0 -> 12388 bytes sound/effects/blood2.ogg | Bin 0 -> 20136 bytes sound/effects/blood3.ogg | Bin 0 -> 13657 bytes sound/effects/butcher.ogg | Bin 0 -> 9666 bytes sound/effects/crack1.ogg | Bin 0 -> 7950 bytes sound/effects/crack2.ogg | Bin 0 -> 15346 bytes sound/effects/dismember.ogg | Bin 0 -> 15382 bytes sound/effects/sizzle1.ogg | Bin 0 -> 52702 bytes sound/effects/sizzle2.ogg | Bin 0 -> 28436 bytes sound/weapons/guillotine.ogg | Bin 0 -> 27777 bytes strings/tips.txt | 6 + tgstation.dme | 12 +- 198 files changed, 4243 insertions(+), 676 deletions(-) create mode 100644 code/__DEFINES/wounds.dm create mode 100644 code/datums/status_effects/wound_effects.dm create mode 100644 code/datums/wounds/_wounds.dm create mode 100644 code/datums/wounds/bones.dm create mode 100644 code/datums/wounds/burns.dm create mode 100644 code/datums/wounds/cuts.dm create mode 100644 code/datums/wounds/scars/_scars.dm rename code/modules/surgery/bodyparts/{bodyparts.dm => _bodyparts.dm} (63%) create mode 100644 code/modules/surgery/bodyparts/parts.dm create mode 100644 code/modules/surgery/bone_mending.dm create mode 100644 code/modules/surgery/burn_dressing.dm create mode 100644 sound/effects/blood1.ogg create mode 100644 sound/effects/blood2.ogg create mode 100644 sound/effects/blood3.ogg create mode 100644 sound/effects/butcher.ogg create mode 100644 sound/effects/crack1.ogg create mode 100644 sound/effects/crack2.ogg create mode 100644 sound/effects/dismember.ogg create mode 100644 sound/effects/sizzle1.ogg create mode 100644 sound/effects/sizzle2.ogg create mode 100644 sound/weapons/guillotine.ogg diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index a077c8a47ef..6610e463163 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -126,6 +126,8 @@ #define AGENDER 16 /// Do not draw eyes or eyeless overlay #define NOEYESPRITES 17 +/// If this species can be scarred (fleshy) +#define CAN_SCAR 18 //organ slots #define ORGAN_SLOT_BRAIN "brain" diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index fca7032074b..fb78a0dcd00 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -79,6 +79,9 @@ #define ADMIN_PUNISHMENT_FAT "Fatten up" #define ADMIN_PUNISHMENT_FAKEBWOINK "Fake bwoink" #define ADMIN_PUNISHMENT_NUGGET "Nugget" +#define ADMIN_PUNISHMENT_CRACK ":B:oneless" +#define ADMIN_PUNISHMENT_BLEED ":B:loodless" +#define ADMIN_PUNISHMENT_SCARIFY "Scarify" #define AHELP_ACTIVE 1 #define AHELP_CLOSED 2 diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 9609f19ceb4..6083b933145 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -65,6 +65,7 @@ #define COMSIG_PARENT_EXAMINE "atom_examine" ///from base of atom/get_examine_name(): (/mob, list/overrides) #define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" +#define COMSIG_PARENT_EXAMINE_MORE "atom_examine_more" ///from base of atom/examine_more(): (/mob) //Positions for overrides list #define EXAMINE_POSITION_ARTICLE (1<<0) #define EXAMINE_POSITION_BEFORE (1<<1) @@ -327,8 +328,6 @@ #define COMSIG_MOB_SWAP_HANDS "mob_swap_hands" #define COMPONENT_BLOCK_SWAP (1<<0) -// /mob/living signals - ///from base of mob/living/resist() (/mob/living) #define COMSIG_LIVING_RESIST "living_resist" ///from base of mob/living/IgniteMob() (/mob/living) @@ -345,9 +344,7 @@ #define COMSIG_LIVING_REVIVE "living_revive" ///from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs) #define COMSIG_LIVING_REGENERATE_LIMBS "living_regen_limbs" -///from base of /obj/item/bodypart/proc/attach_limb(): (new_limb, special) allows you to fail limb attachment -#define COMSIG_LIVING_ATTACH_LIMB "living_attach_limb" - #define COMPONENT_NO_ATTACH (1<<0) + ///sent from borg recharge stations: (amount, repairs) #define COMSIG_PROCESS_BORGCHARGER_OCCUPANT "living_charge" ///sent when a mob/login() finishes: (client) @@ -374,7 +371,13 @@ #define COMSIG_LIVING_CAN_TRACK "mob_cantrack" #define COMPONENT_CANT_TRACK (1<<0) -// /mob/living/carbon signals +// /mob/living/carbon physiology signals +#define COMSIG_CARBON_GAIN_WOUND "carbon_gain_wound" //from /datum/wound/proc/apply_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L) +#define COMSIG_CARBON_LOSE_WOUND "carbon_lose_wound" //from /datum/wound/proc/remove_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L) +///from base of /obj/item/bodypart/proc/attach_limb(): (new_limb, special) allows you to fail limb attachment +#define COMSIG_CARBON_ATTACH_LIMB "carbon_attach_limb" + #define COMPONENT_NO_ATTACH (1<<0) +#define COMSIG_CARBON_REMOVE_LIMB "carbon_remove_limb" //from base of /obj/item/bodypart/proc/drop_limb(special, dismembered) ///from base of mob/living/carbon/soundbang_act(): (list(intensity)) #define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index b9a53e85e4c..6ed26789093 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -66,6 +66,7 @@ #define BODYPART_NOT_DISABLED 0 #define BODYPART_DISABLED_DAMAGE 1 #define BODYPART_DISABLED_PARALYSIS 2 +#define BODYPART_DISABLED_WOUND 3 #define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi' #define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi' @@ -112,12 +113,14 @@ #define TRAUMA_RESILIENCE_BASIC 1 //Curable with chems #define TRAUMA_RESILIENCE_SURGERY 2 //Curable with brain surgery #define TRAUMA_RESILIENCE_LOBOTOMY 3 //Curable with lobotomy -#define TRAUMA_RESILIENCE_MAGIC 4 //Curable only with magic -#define TRAUMA_RESILIENCE_ABSOLUTE 5 //This is here to stay +#define TRAUMA_RESILIENCE_WOUND 4 //Curable by healing the head wound +#define TRAUMA_RESILIENCE_MAGIC 5 //Curable only with magic +#define TRAUMA_RESILIENCE_ABSOLUTE 6 //This is here to stay //Limit of traumas for each resilience tier #define TRAUMA_LIMIT_BASIC 3 #define TRAUMA_LIMIT_SURGERY 2 +#define TRAUMA_LIMIT_WOUND 2 #define TRAUMA_LIMIT_LOBOTOMY 3 #define TRAUMA_LIMIT_MAGIC 3 #define TRAUMA_LIMIT_ABSOLUTE INFINITY @@ -360,3 +363,6 @@ #define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return; #define INTERACTING_WITH(X, Y) (Y in X.do_afters) + +/// If you examine the same atom twice in this timeframe, we call examine_more() instead of examine() +#define EXAMINE_MORE_TIME 1 SECONDS diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index c29184e5c30..b73d5bc5252 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -56,3 +56,8 @@ #define ORGAN_VITAL (1<<4) //Currently only the brain #define ORGAN_EDIBLE (1<<5) //is a snack? :D #define ORGAN_SYNTHETIC_EMP (1<<6) //Synthetic organ affected by an EMP. Deteriorates over time. + +/// Integrity defines for clothing (not flags but close enough) +#define CLOTHING_PRISTINE 0 // We have no damage on the clothing +#define CLOTHING_DAMAGED 1 // There's some damage on the clothing but it still has at least one functioning bodypart and can be equipped +#define CLOTHING_SHREDDED 2 // The clothing is useless and cannot be equipped unless repaired first diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 59a0a4c22a7..a7f830dedce 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -36,6 +36,8 @@ #define STATUS_EFFECT_ANTIMAGIC /datum/status_effect/antimagic //grants antimagic (and reapplies if lost) for the duration +#define STATUS_EFFECT_DETERMINED /datum/status_effect/determined //currently in a combat high from being seriously wounded + ///////////// // DEBUFFS // ///////////// @@ -99,6 +101,8 @@ #define STATUS_EFFECT_FAKE_VIRUS /datum/status_effect/fake_virus //gives you fluff messages for cough, sneeze, headache, etc but without an actual virus +#define STATUS_EFFECT_LIMP /datum/status_effect/limp //For when you have a busted leg (or two!) and want additional slowdown when walking on that leg + ///////////// // NEUTRAL // ///////////// diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm index 2385387d2d0..4605975e78c 100644 --- a/code/__DEFINES/tools.dm +++ b/code/__DEFINES/tools.dm @@ -14,6 +14,7 @@ #define TOOL_DRILL "drill" #define TOOL_SCALPEL "scalpel" #define TOOL_SAW "saw" +#define TOOL_BONESET "bonesetter" // If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY, // tool sound is only played when op is started. If not, it's played twice. diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index aff6571082d..51505ae52b3 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -187,7 +187,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NICE_SHOT "nice_shot" //hnnnnnnnggggg..... you're pretty good.... //non-mob traits -#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it +#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it ///Used for managing KEEP_TOGETHER in [appearance_flags] #define TRAIT_KEEP_TOGETHER "keep-together" diff --git a/code/__DEFINES/wounds.dm b/code/__DEFINES/wounds.dm new file mode 100644 index 00000000000..b993429961d --- /dev/null +++ b/code/__DEFINES/wounds.dm @@ -0,0 +1,43 @@ +#define WOUND_DAMAGE_EXPONENT 1.4 + +#define WOUND_SEVERITY_TRIVIAL 0 // for jokey/meme wounds like stubbed toe, no standard messages/sounds or second winds +#define WOUND_SEVERITY_MODERATE 1 +#define WOUND_SEVERITY_SEVERE 2 +#define WOUND_SEVERITY_CRITICAL 3 +#define WOUND_SEVERITY_LOSS 4 // theoretical total limb loss, like dismemberment for cuts + +#define WOUND_BRUTE 0 +#define WOUND_SHARP 1 +#define WOUND_BURN 2 + +// How much determination reagent to add each time someone gains a new wound in [/datum/wound/proc/second_wind()] +#define WOUND_DETERMINATION_MODERATE 1 +#define WOUND_DETERMINATION_SEVERE 2.5 +#define WOUND_DETERMINATION_CRITICAL 5 + +#define WOUND_DETERMINATION_MAX 10 + +// set wound_bonus on an item or attack to this to disable checking wounding for the attack +#define CANT_WOUND -100 + +// list in order of highest severity to lowest +#define WOUND_LIST_BONE list(/datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/moderate) +#define WOUND_LIST_CUT list(/datum/wound/brute/cut/loss, /datum/wound/brute/cut/critical, /datum/wound/brute/cut/severe, /datum/wound/brute/cut/moderate) +#define WOUND_LIST_BURN list(/datum/wound/burn/critical, /datum/wound/burn/severe, /datum/wound/burn/moderate) + +// Thresholds for infection for burn wounds, once infestation hits each threshold, things get steadily worse +#define WOUND_INFECTION_MODERATE 4 // below this has no ill effects from infection +#define WOUND_INFECTION_SEVERE 8 // then below here, you ooze some pus and suffer minor tox damage, but nothing serious +#define WOUND_INFECTION_CRITICAL 12 // then below here, your limb occasionally locks up from damage and infection and briefly becomes disabled. Things are getting really bad +#define WOUND_INFECTION_SEPTIC 20 // below here, your skin is almost entirely falling off and your limb locks up more frequently. You are within a stone's throw of septic paralysis and losing the limb +// above WOUND_INFECTION_SEPTIC, your limb is completely putrid and you start rolling to lose the entire limb by way of paralyzation. After 3 failed rolls (~4-5% each probably), the limb is paralyzed + +#define WOUND_BURN_SANITIZATION_RATE 0.15 // how quickly sanitization removes infestation and decays per tick +#define WOUND_CUT_MAX_BLOODFLOW 8 // how much blood you can lose per tick per cut max. 8 is a LOT of blood for one cut so don't worry about hitting it easily +#define WOUND_BONE_HEAD_TIME_VARIANCE 20 // if we suffer a bone wound to the head that creates brain traumas, the timer for the trauma cycle is +/- by this percent (0-100) + +// The following are for persistent scar save formats +#define SCAR_SAVE_ZONE 1 // The body_zone we're applying to on granting +#define SCAR_SAVE_DESC 2 // The description we're loading +#define SCAR_SAVE_PRECISE_LOCATION 3 // The precise location we're loading +#define SCAR_SAVE_SEVERITY 4 // The severity the scar had diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index d919d0d7a24..a7d5f43ff08 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -90,6 +90,10 @@ if (CONFIG_GET(flag/log_attack)) WRITE_LOG(GLOB.world_attack_log, "ATTACK: [text]") +/proc/log_wounded(text) + if (CONFIG_GET(flag/log_attack)) + WRITE_LOG(GLOB.world_attack_log, "WOUND: [text]") + /proc/log_econ(text) if (CONFIG_GET(flag/log_econ)) WRITE_LOG(GLOB.world_econ_log, "MONEY: [text]") diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 3a9a730606e..62cbe99e572 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -217,8 +217,24 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH, return (a+(b-a)*((2/3)-hue)*6) return a +/// For finding out what body parts a body zone covers, the inverse of the below basically +/proc/zone2body_parts_covered(def_zone) + switch(def_zone) + if(BODY_ZONE_CHEST) + return list(CHEST, GROIN) + if(BODY_ZONE_HEAD) + return list(HEAD) + if(BODY_ZONE_L_ARM) + return list(ARM_LEFT, HAND_LEFT) + if(BODY_ZONE_R_ARM) + return list(ARM_RIGHT, HAND_RIGHT) + if(BODY_ZONE_L_LEG) + return list(LEG_LEFT, FOOT_LEFT) + if(BODY_ZONE_R_LEG) + return list(LEG_RIGHT, FOOT_RIGHT) + //Turns a Body_parts_covered bitfield into a list of organ/limb names. -//(I challenge you to find a use for this) +//(I challenge you to find a use for this) -I found a use for it!! /proc/body_parts_covered2organ_names(bpc) var/list/covered_parts = list() diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 993cdc41048..6c9e5964ba8 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -5,8 +5,12 @@ Otherwise pretty standard. */ /mob/living/carbon/human/UnarmedAttack(atom/A, proximity) - if(!has_active_hand()) //can't attack without a hand. + var/obj/item/bodypart/check_arm = get_active_hand() + if(check_arm && check_arm.is_disabled() == BODYPART_DISABLED_WOUND) + to_chat(src, "The damage in your [check_arm.name] is preventing you from using it! Get it fixed, or at least splinted!") + return + to_chat(src, "You look at your arm and sigh.") return diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index c60b5e685c7..ab75a1c619a 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -180,6 +180,7 @@ SUBSYSTEM_DEF(persistence) CollectAntagReputation() SaveRandomizedRecipes() SavePaintings() + SaveScars() /datum/controller/subsystem/persistence/proc/GetPhotoAlbums() var/album_path = file("data/photo_albums.json") @@ -388,3 +389,24 @@ SUBSYSTEM_DEF(persistence) var/json_file = file("data/paintings.json") fdel(json_file) WRITE_FILE(json_file, json_encode(paintings)) + +/datum/controller/subsystem/persistence/proc/SaveScars() + for(var/i in GLOB.joined_player_list) + var/mob/living/carbon/human/ending_human = get_mob_by_ckey(i) + if(!istype(ending_human) || !ending_human.mind || !ending_human.client || !ending_human.client.prefs || !ending_human.client.prefs.persistent_scars) + continue + + var/mob/living/carbon/human/original_human = ending_human.mind.original_character + if(!original_human || original_human.stat == DEAD || !original_human.all_scars || !(original_human == ending_human)) + if(ending_human.client) // i was told if i don't check this every step of the way byond might decide a client ceases to exist mid proc so here we go + ending_human.client.prefs.scars_list["[ending_human.client.prefs.scars_index]"] = "" + else + for(var/k in ending_human.all_wounds) + var/datum/wound/W = k + W.remove_wound() // so we can get the scars for open wounds + if(!ending_human.client) + return + ending_human.client.prefs.scars_list["[ending_human.client.prefs.scars_index]"] = ending_human.format_scars() + if(!ending_human.client) + return + ending_human.client.prefs.save_character() diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 94ce94393e8..5024a1803c5 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -890,3 +890,4 @@ SUBSYSTEM_DEF(shuttle) message_admins("[key_name_admin(usr)] loaded [mdp] with the shuttle manipulator.") log_admin("[key_name(usr)] loaded [mdp] with the shuttle manipulator.") SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[mdp.name]") + diff --git a/code/datums/armor.dm b/code/datums/armor.dm index cbf4b76c60f..e317a05de2b 100644 --- a/code/datums/armor.dm +++ b/code/datums/armor.dm @@ -1,9 +1,9 @@ -#define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]" +#define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]-[wound]" -/proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0) +/proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0) . = locate(ARMORID) if (!.) - . = new /datum/armor(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic) + . = new /datum/armor(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic, wound) /datum/armor datum_flags = DF_USE_TAG @@ -17,8 +17,9 @@ var/fire var/acid var/magic + var/wound -/datum/armor/New(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0) +/datum/armor/New(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0) src.melee = melee src.bullet = bullet src.laser = laser @@ -29,15 +30,16 @@ src.fire = fire src.acid = acid src.magic = magic + src.wound = wound tag = ARMORID -/datum/armor/proc/modifyRating(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0) - return getArmor(src.melee+melee, src.bullet+bullet, src.laser+laser, src.energy+energy, src.bomb+bomb, src.bio+bio, src.rad+rad, src.fire+fire, src.acid+acid, src.magic+magic) +/datum/armor/proc/modifyRating(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0) + return getArmor(src.melee+melee, src.bullet+bullet, src.laser+laser, src.energy+energy, src.bomb+bomb, src.bio+bio, src.rad+rad, src.fire+fire, src.acid+acid, src.magic+magic, src.wound+wound) /datum/armor/proc/modifyAllRatings(modifier = 0) - return getArmor(melee+modifier, bullet+modifier, laser+modifier, energy+modifier, bomb+modifier, bio+modifier, rad+modifier, fire+modifier, acid+modifier, magic+modifier) + return getArmor(melee+modifier, bullet+modifier, laser+modifier, energy+modifier, bomb+modifier, bio+modifier, rad+modifier, fire+modifier, acid+modifier, magic+modifier, wound+modifier) -/datum/armor/proc/setRating(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic) +/datum/armor/proc/setRating(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic, wound) return getArmor((isnull(melee) ? src.melee : melee),\ (isnull(bullet) ? src.bullet : bullet),\ (isnull(laser) ? src.laser : laser),\ @@ -47,19 +49,20 @@ (isnull(rad) ? src.rad : rad),\ (isnull(fire) ? src.fire : fire),\ (isnull(acid) ? src.acid : acid),\ - (isnull(magic) ? src.magic : magic)) + (isnull(magic) ? src.magic : magic),\ + (isnull(wound) ? src.wound : wound)) /datum/armor/proc/getRating(rating) return vars[rating] /datum/armor/proc/getList() - return list("melee" = melee, "bullet" = bullet, "laser" = laser, "energy" = energy, "bomb" = bomb, "bio" = bio, "rad" = rad, "fire" = fire, "acid" = acid, "magic" = magic) + return list("melee" = melee, "bullet" = bullet, "laser" = laser, "energy" = energy, "bomb" = bomb, "bio" = bio, "rad" = rad, "fire" = fire, "acid" = acid, "magic" = magic, "wound" = wound) /datum/armor/proc/attachArmor(datum/armor/AA) - return getArmor(melee+AA.melee, bullet+AA.bullet, laser+AA.laser, energy+AA.energy, bomb+AA.bomb, bio+AA.bio, rad+AA.rad, fire+AA.fire, acid+AA.acid, magic+AA.magic) + return getArmor(melee+AA.melee, bullet+AA.bullet, laser+AA.laser, energy+AA.energy, bomb+AA.bomb, bio+AA.bio, rad+AA.rad, fire+AA.fire, acid+AA.acid, magic+AA.magic, wound+AA.wound) /datum/armor/proc/detachArmor(datum/armor/AA) - return getArmor(melee-AA.melee, bullet-AA.bullet, laser-AA.laser, energy-AA.energy, bomb-AA.bomb, bio-AA.bio, rad-AA.rad, fire-AA.fire, acid-AA.acid, magic-AA.magic) + return getArmor(melee-AA.melee, bullet-AA.bullet, laser-AA.laser, energy-AA.energy, bomb-AA.bomb, bio-AA.bio, rad-AA.rad, fire-AA.fire, acid-AA.acid, magic-AA.magic, wound-AA.wound) /datum/armor/vv_edit_var(var_name, var_value) if (var_name == NAMEOF(src, tag)) diff --git a/code/datums/brain_damage/magic.dm b/code/datums/brain_damage/magic.dm index ff04ceead93..a00b341b820 100644 --- a/code/datums/brain_damage/magic.dm +++ b/code/datums/brain_damage/magic.dm @@ -94,7 +94,7 @@ if(get_dist(owner, stalker) <= 1) playsound(owner, 'sound/magic/demon_attack1.ogg', 50) owner.visible_message("[owner] is torn apart by invisible claws!", "Ghostly claws tear your body apart!") - owner.take_bodypart_damage(rand(20, 45)) + owner.take_bodypart_damage(rand(20, 45), wound_bonus=CANT_WOUND) else if(prob(50)) stalker.forceMove(get_step_towards(stalker, owner)) if(get_dist(owner, stalker) <= 8) diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm index 6a964029b47..c34cd5bcd2f 100644 --- a/code/datums/components/butchering.dm +++ b/code/datums/components/butchering.dm @@ -2,7 +2,7 @@ var/speed = 80 //time in deciseconds taken to butcher something var/effectiveness = 100 //percentage effectiveness; numbers above 100 yield extra drops var/bonus_modifier = 0 //percentage increase to bonus item chance - var/butcher_sound = 'sound/weapons/slice.ogg' //sound played when butchering + var/butcher_sound = 'sound/effects/butcher.ogg' //sound played when butchering var/butchering_enabled = TRUE var/can_be_blunt = FALSE @@ -47,6 +47,10 @@ Butcher(user, M) /datum/component/butchering/proc/startNeckSlice(obj/item/source, mob/living/carbon/human/H, mob/living/user) + if(INTERACTING_WITH(user, H)) + to_chat(user, "You're already interacting with [H]!") + return + user.visible_message("[user] is slitting [H]'s throat!", \ "You start slicing [H]'s throat!", \ "You hear a cutting noise!", ignored_mobs = H) @@ -64,8 +68,11 @@ H.visible_message("[user] slits [H]'s throat!", \ "[user] slits your throat...") log_combat(user, H, "finishes slicing the throat of") - H.apply_damage(source.force, BRUTE, BODY_ZONE_HEAD) - H.bleed_rate = clamp(H.bleed_rate + 20, 0, 30) + H.apply_damage(source.force, BRUTE, BODY_ZONE_HEAD, wound_bonus=CANT_WOUND) // easy tiger, we'll get to that in a sec + var/obj/item/bodypart/slit_throat = H.get_bodypart(BODY_ZONE_HEAD) + if(slit_throat) + var/datum/wound/brute/cut/critical/screaming_through_a_slit_throat = new + screaming_through_a_slit_throat.apply_wound(slit_throat) H.apply_status_effect(/datum/status_effect/neck_slice) /datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat) diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm index 3300392811c..1e91d771685 100644 --- a/code/datums/components/caltrop.dm +++ b/code/datums/components/caltrop.dm @@ -60,5 +60,5 @@ "You slide on [A]!") cooldown = world.time - H.apply_damage(damage, BRUTE, picked_def_zone) + H.apply_damage(damage, BRUTE, picked_def_zone, wound_bonus = CANT_WOUND) H.Paralyze(60) diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index 41ad39e291f..2803fee3060 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -147,7 +147,7 @@ playsound(victim,'sound/weapons/bladeslice.ogg', 40) weapon.add_mob_blood(victim)//it embedded itself in you, of course it's bloody! var/damage = weapon.w_class * impact_pain_mult - limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage) + limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus=-30, sharpness = TRUE) SEND_SIGNAL(victim, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded) else victim.visible_message("[weapon] sticks itself to [victim]'s [limb.name]!",ignored_mobs=victim) @@ -163,7 +163,7 @@ if(harmful && prob(chance)) var/damage = weapon.w_class * jostle_pain_mult - limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage) + limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND) to_chat(victim, "[weapon] embedded in your [limb.name] jostles and stings!") @@ -173,7 +173,7 @@ if(harmful) var/damage = weapon.w_class * remove_pain_mult - limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage) + limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND) victim.visible_message("[weapon] falls out of [victim.name]'s [limb.name]!", ignored_mobs=victim) to_chat(victim, "[weapon] falls out of your [limb.name]!") else @@ -199,7 +199,7 @@ if(harmful) var/damage = weapon.w_class * remove_pain_mult - limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage) //It hurts to rip it out, get surgery you dingus. + limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, sharpness=TRUE) //It hurts to rip it out, get surgery you dingus. victim.emote("scream") victim.visible_message("[victim] successfully rips [weapon] out of [victim.p_their()] [limb.name]!", "You successfully remove [weapon] from your [limb.name].") else @@ -276,7 +276,7 @@ damage *= 0.7 if(harmful && prob(chance)) - limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage) + limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND) to_chat(victim, "[weapon] embedded in your [limb.name] hurts!") if(prob(fall_chance)) diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index 7d203665765..25620f97bbb 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -64,6 +64,7 @@ ///Store the thrownthing datum for later use /datum/component/tackler/proc/registerTackle(mob/living/carbon/user, datum/thrownthing/TT) tackle = TT + tackle.thrower = user ///See if we can tackle or not. If we can, leap! /datum/component/tackler/proc/checkTackle(mob/living/carbon/user, atom/A, params) diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm index 2fbc4d8a4a6..f5c97e6f900 100644 --- a/code/datums/diseases/advance/symptoms/flesh_eating.dm +++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm @@ -63,7 +63,8 @@ Bonus if(bleed) if(ishuman(M)) var/mob/living/carbon/human/H = M - H.bleed_rate += 5 * power + var/obj/item/bodypart/random_part = pick(H.bodyparts) + random_part.generic_bleedstacks += 5 * power return 1 /* diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm index ac32f416aa5..d6e6d408c56 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -62,4 +62,4 @@ Bonus if(cartoon_sneezing) //Yeah, this can fling you around even if you have a space suit helmet on. It's, uh, bluespace snot, yeah. var/sneeze_distance = rand(2,4) //twice as far as a normal baseball bat strike will fling you var/turf/target = get_ranged_target_turf(M, turn(M.dir, 180), sneeze_distance) - M.throw_at(target, sneeze_distance, 7) //flings you at the speed that a normal baseball bat would fling you at + M.throw_at(target, sneeze_distance, rand(1,4)) //with the wounds update, sneezing at 7 speed was causing peoples bones to spontaneously explode, turning cartoonish sneezing into a nightmarishly lethal GBS 2.0 outbreak diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index 9e7850ba800..75e80df4cd9 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -45,7 +45,7 @@ playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, TRUE, -1) var/atom/throw_target = get_edge_target_turf(D, A.dir) D.throw_at(throw_target, 7, 14, A) - D.apply_damage(15, A.dna.species.attack_type, BODY_ZONE_CHEST) + D.apply_damage(15, A.dna.species.attack_type, BODY_ZONE_CHEST, wound_bonus = CANT_WOUND) log_combat(A, D, "launchkicked (Sleeping Carp)") return @@ -54,13 +54,13 @@ A.do_attack_animation(D, ATTACK_EFFECT_KICK) playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, TRUE, -1) if((D.mobility_flags & MOBILITY_STAND)) - D.apply_damage(10, A.dna.species.attack_type, BODY_ZONE_HEAD) + D.apply_damage(10, A.dna.species.attack_type, BODY_ZONE_HEAD, wound_bonus = CANT_WOUND) D.apply_damage(40, STAMINA, BODY_ZONE_HEAD) D.Knockdown(40) D.visible_message("[A] kicks [D] in the head, sending them face first into the floor!", \ "You are kicked in the head by [A], sending you crashing to the floor!", "You hear a sickening sound of flesh hitting flesh!", COMBAT_MESSAGE_RANGE, A) else - D.apply_damage(5, A.dna.species.attack_type, BODY_ZONE_HEAD) + D.apply_damage(5, A.dna.species.attack_type, BODY_ZONE_HEAD, wound_bonus = CANT_WOUND) D.apply_damage(40, STAMINA, BODY_ZONE_HEAD) D.drop_all_held_items() D.visible_message("[A] kicks [D] in the head!", \ @@ -85,7 +85,7 @@ D.visible_message("[A] [atk_verb]s [D]!", \ "[A] [atk_verb]s you!", null, null, A) to_chat(A, "You [atk_verb] [D]!") - D.apply_damage(rand(10,15), BRUTE, affecting) + D.apply_damage(rand(10,15), BRUTE, affecting, wound_bonus = CANT_WOUND) playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, TRUE, -1) log_combat(A, D, "punched (Sleeping Carp)") return TRUE diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 3e5854fe77f..651cd7501e1 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -71,6 +71,8 @@ var/list/skills_rewarded ///Assoc list of skills. Use SKILL_LVL to access level, and SKILL_EXP to access skill's exp. var/list/known_skills = list() + ///What character we spawned in as- either at roundstart or latejoin, so we know for persistent scars if we ended as the same person or not + var/mob/original_character /datum/mind/New(key) src.key = key @@ -90,6 +92,7 @@ return language_holder /datum/mind/proc/transfer_to(mob/new_character, force_key_move = 0) + original_character = null if(current) // remove ourself from our old body's mind variable current.mind = null UnregisterSignal(current, COMSIG_MOB_DEATH) @@ -122,6 +125,8 @@ RegisterSignal(new_character, COMSIG_MOB_DEATH, .proc/set_death_time) if(active || force_key_move) new_character.key = key //now transfer the key to link the client to our new body + if(new_character.client) + LAZYCLEARLIST(new_character.client.recent_examines) current.update_atom_languages() /datum/mind/proc/init_known_skills() diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 3f779cc8df3..7fd2a06b1d1 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -96,14 +96,18 @@ var/mob/living/carbon/human/H = owner H.dna.species.start_wagging_tail(H) addtimer(CALLBACK(H.dna.species, /datum/species.proc/stop_wagging_tail, H), 30) - description = "They want to play on the table!\n" + description = "They want to play on the table!\n" mood_change = 2 -/datum/mood_event/table_headsmash - description = "My fucking head, that hurts..." +/datum/mood_event/table_limbsmash + description = "That fucking table, man that hurts...\n" mood_change = -3 timeout = 3 MINUTES +/datum/mood_event/table_limbsmash/add_effects(obj/item/bodypart/banged_limb) + if(banged_limb) + description = "My fucking [banged_limb.name], man that hurts...\n" + /datum/mood_event/brain_damage mood_change = -3 diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index b1b2fcb3644..24c213ecab8 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -477,13 +477,13 @@ head.drop_organs() qdel(head) owner.regenerate_icons() - RegisterSignal(owner, COMSIG_LIVING_ATTACH_LIMB, .proc/abortattachment) + RegisterSignal(owner, COMSIG_CARBON_ATTACH_LIMB, .proc/abortattachment) /datum/mutation/human/headless/on_losing() . = ..() if(.) return TRUE - UnregisterSignal(owner, COMSIG_LIVING_ATTACH_LIMB) + UnregisterSignal(owner, COMSIG_CARBON_ATTACH_LIMB) var/successful = owner.regenerate_limb(BODY_ZONE_HEAD, noheal = TRUE) //noheal needs to be TRUE to prevent weird adding and removing mutation healing if(!successful) stack_trace("HARS mutation head regeneration failed! (usually caused by headless syndrome having a head)") diff --git a/code/datums/skills/medical.dm b/code/datums/skills/medical.dm index f9bd5d541e6..07bc08d1e17 100644 --- a/code/datums/skills/medical.dm +++ b/code/datums/skills/medical.dm @@ -2,5 +2,6 @@ name = "Healing" title = "Healer" desc = "From Bandaids to biopsies, this improves your ability to get people back up both in the field and on the operating table." - modifiers = list(SKILL_SPEED_MODIFIER = list(1, 0.95, 0.9, 0.85, 0.75, 0.6, 0.5)) + modifiers = list(SKILL_SPEED_MODIFIER = list(1, 0.95, 0.9, 0.85, 0.75, 0.6, 0.5), + SKILL_PROBS_MODIFIER = list(0, 2, 4, 6, 8, 10, 12)) skill_cape_path = /obj/item/clothing/neck/cloak/skill_reward/healing diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index e4afaff7c63..c103097c454 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -252,6 +252,10 @@ owner.adjustBruteLoss(-10, FALSE) owner.adjustFireLoss(-5, FALSE) owner.adjustOxyLoss(-10) + if(!iscarbon(owner)) + return + var/mob/living/carbon/C = owner + QDEL_LIST(C.all_scars) /obj/screen/alert/status_effect/fleshmend name = "Fleshmend" diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 6ccf07e32b2..f9a722eedbf 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -334,8 +334,19 @@ /datum/status_effect/neck_slice/tick() var/mob/living/carbon/human/H = owner - if(H.stat == DEAD || H.bleed_rate <= 8) + var/obj/item/bodypart/throat = H.get_bodypart(BODY_ZONE_HEAD) + if(H.stat == DEAD || !throat) H.remove_status_effect(/datum/status_effect/neck_slice) + + var/still_bleeding = FALSE + for(var/thing in throat.wounds) + var/datum/wound/W = thing + if(W.wound_type == WOUND_LIST_CUT && W.severity > WOUND_SEVERITY_MODERATE) + still_bleeding = TRUE + break + if(!still_bleeding) + H.remove_status_effect(/datum/status_effect/neck_slice) + if(prob(10)) H.emote(pick("gasp", "gag", "choke")) diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm index 3130dd9a749..c0ffc35e788 100644 --- a/code/datums/status_effects/status_effect.dm +++ b/code/datums/status_effects/status_effect.dm @@ -73,6 +73,10 @@ return duration = world.time + original_duration +//do_after modifier! +/datum/status_effect/proc/interact_speed_modifier() + return 1 + //clickdelay/nextmove modifiers! /datum/status_effect/proc/nextmove_modifier() return 1 diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm new file mode 100644 index 00000000000..751a3508a38 --- /dev/null +++ b/code/datums/status_effects/wound_effects.dm @@ -0,0 +1,186 @@ + +// The shattered remnants of your broken limbs fill you with determination! +/obj/screen/alert/status_effect/determined + name = "Determined" + desc = "The serious wounds you've sustained have put your body into fight-or-flight mode! Now's the time to look for an exit!" + icon_state = "regenerative_core" + +/datum/status_effect/determined + id = "determined" + alert_type = /obj/screen/alert/status_effect/determined + +/datum/status_effect/determined/on_apply() + . = ..() + owner.visible_message("[owner] grits [owner.p_their()] teeth in pain!", "Your senses sharpen as your body tenses up from the wounds you've sustained!", vision_distance=COMBAT_MESSAGE_RANGE) + +/datum/status_effect/determined/on_remove() + owner.visible_message("[owner]'s body slackens noticeably!", "Your adrenaline rush dies off, and the pain from your wounds come aching back in...", vision_distance=COMBAT_MESSAGE_RANGE) + return ..() + +/datum/status_effect/limp + id = "limp" + status_type = STATUS_EFFECT_REPLACE + tick_interval = 10 + alert_type = /obj/screen/alert/status_effect/limp + var/msg_stage = 0//so you dont get the most intense messages immediately + /// The left leg of the limping person + var/obj/item/bodypart/l_leg/left + /// The right leg of the limping person + var/obj/item/bodypart/r_leg/right + /// Which leg we're limping with next + var/obj/item/bodypart/next_leg + /// How many deciseconds we limp for on the left leg + var/slowdown_left = 0 + /// How many deciseconds we limp for on the right leg + var/slowdown_right = 0 + +/datum/status_effect/limp/on_apply() + if(!iscarbon(owner)) + return FALSE + var/mob/living/carbon/C = owner + left = C.get_bodypart(BODY_ZONE_L_LEG) + right = C.get_bodypart(BODY_ZONE_R_LEG) + update_limp() + RegisterSignal(C, COMSIG_MOVABLE_MOVED, .proc/check_step) + RegisterSignal(C, list(COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_LOSE_WOUND, COMSIG_CARBON_ATTACH_LIMB, COMSIG_CARBON_REMOVE_LIMB), .proc/update_limp) + return TRUE + +/datum/status_effect/limp/on_remove() + UnregisterSignal(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_LOSE_WOUND, COMSIG_CARBON_ATTACH_LIMB, COMSIG_CARBON_REMOVE_LIMB)) + +/obj/screen/alert/status_effect/limp + name = "Limping" + desc = "One or more of your legs has been wounded, slowing down steps with that leg! Get it fixed, or at least splinted!" + +/datum/status_effect/limp/proc/check_step(mob/whocares, OldLoc, Dir, forced) + if(!owner.client || !(owner.mobility_flags & MOBILITY_STAND) || !owner.has_gravity() || (owner.movement_type & FLYING) || forced) + return + var/determined_mod = 1 + if(owner.has_status_effect(STATUS_EFFECT_DETERMINED)) + determined_mod = 0.25 + if(next_leg == left) + owner.client.move_delay += slowdown_left * determined_mod + next_leg = right + else + owner.client.move_delay += slowdown_right * determined_mod + next_leg = left + +/datum/status_effect/limp/proc/update_limp() + var/mob/living/carbon/C = owner + left = C.get_bodypart(BODY_ZONE_L_LEG) + right = C.get_bodypart(BODY_ZONE_R_LEG) + + if(!left && !right) + C.remove_status_effect(src) + return + + slowdown_left = 0 + slowdown_right = 0 + + if(left) + for(var/thing in left.wounds) + var/datum/wound/W = thing + slowdown_left += W.limp_slowdown + + if(right) + for(var/thing in right.wounds) + var/datum/wound/W = thing + slowdown_right += W.limp_slowdown + + // this handles losing your leg with the limp and the other one being in good shape as well + if(!slowdown_left && !slowdown_right) + C.remove_status_effect(src) + return + + +///////////////////////// +//////// WOUNDS ///////// +///////////////////////// + +// wound alert +/obj/screen/alert/status_effect/wound + name = "Wounded" + desc = "Your body has sustained serious damage, click here to inspect yourself." + +/obj/screen/alert/status_effect/wound/Click() + var/mob/living/carbon/C = usr + C.check_self_for_injuries() + +// wound status effect base +/datum/status_effect/wound + id = "wound" + status_type = STATUS_EFFECT_MULTIPLE + var/obj/item/bodypart/linked_limb + var/datum/wound/linked_wound + alert_type = NONE + +/datum/status_effect/wound/on_creation(mob/living/new_owner, incoming_wound) + . = ..() + var/datum/wound/W = incoming_wound + linked_wound = W + linked_limb = linked_wound.limb + +/datum/status_effect/wound/on_remove() + linked_wound = null + linked_limb = null + UnregisterSignal(owner, COMSIG_CARBON_LOSE_WOUND) + +/datum/status_effect/wound/on_apply() + if(!iscarbon(owner)) + return FALSE + RegisterSignal(owner, COMSIG_CARBON_LOSE_WOUND, .proc/check_remove) + return TRUE + +/// check if the wound getting removed is the wound we're tied to +/datum/status_effect/wound/proc/check_remove(mob/living/L, datum/wound/W) + if(W == linked_wound) + qdel(src) + + +// bones +/datum/status_effect/wound/bone + +/datum/status_effect/wound/bone/interact_speed_modifier() + var/mob/living/carbon/C = owner + + if(C.get_active_hand() == linked_limb) + to_chat(C, "The [lowertext(linked_wound)] in your [linked_limb.name] slows your progress!") + return linked_wound.interaction_efficiency_penalty + + return 1 + +/datum/status_effect/wound/bone/nextmove_modifier() + var/mob/living/carbon/C = owner + + if(C.get_active_hand() == linked_limb) + return linked_wound.interaction_efficiency_penalty + + return 1 + +/datum/status_effect/wound/bone/moderate + id = "disjoint" +/datum/status_effect/wound/bone/severe + id = "hairline" + +/datum/status_effect/wound/bone/critical + id = "compound" + +// cuts +/datum/status_effect/wound/cut/moderate + id = "abrasion" + +/datum/status_effect/wound/cut/severe + id = "laceration" + +/datum/status_effect/wound/cut/critical + id = "avulsion" + +// burns +/datum/status_effect/wound/burn/moderate + id = "seconddeg" + +/datum/status_effect/wound/burn/severe + id = "thirddeg" + +/datum/status_effect/wound/burn/critical + id = "fourthdeg" diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index 1e9e2187ee1..bb066f106f2 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -217,7 +217,7 @@ /datum/quirk/frail name = "Frail" - desc = "Your bones might as well be made of glass! Your limbs can take less damage before they become disabled." + desc = "Your bones might as well be made of glass! You suffer wounds much more easily than most." value = -2 mob_trait = TRAIT_EASYLIMBDISABLE gain_text = "You feel frail." diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm index 48810769fce..88438040111 100644 --- a/code/datums/traits/neutral.dm +++ b/code/datums/traits/neutral.dm @@ -240,3 +240,19 @@ ///Applies a bad moodlet for having an uncovered head /datum/quirk/bald/proc/unequip_hat(mob/user, obj/item/clothing, force, newloc, no_move, invdrop, silent) SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "bad_hair_day", /datum/mood_event/bald) + +/datum/quirk/longtimer + name = "Longtimer" + desc = "You've been around for a long time and seen more than your fair share of action, suffering some pretty nasty scars along the way. For whatever reason, you've declined to get them removed or augmented." + value = 0 + gain_text = "Your body has seen better days." + lose_text = "Your sins may wash away, but those scars are here to stay..." + medical_record_text = "Patient has withstood significant physical trauma and declined plastic surgery procedures to heal scarring." + /// the minimum amount of scars we can generate + var/min_scars = 3 + /// the maximum amount of scars we can generate + var/max_scars = 7 + +/datum/quirk/longtimer/on_spawn() + var/mob/living/carbon/C = quirk_holder + C.generate_fake_scars(rand(min_scars, max_scars)) diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm new file mode 100644 index 00000000000..d70a4ebdb2d --- /dev/null +++ b/code/datums/wounds/_wounds.dm @@ -0,0 +1,320 @@ +/* + Wounds are specific medical complications that can arise and be applied to (currently) carbons, with a focus on humans. All of the code for and related to this is heavily WIP, + and the documentation will be slanted towards explaining what each part/piece is leading up to, until such a time as I finish the core implementations. The original design doc + can be found at https://hackmd.io/@Ryll/r1lb4SOwU + + Wounds are datums that operate like a mix of diseases, brain traumas, and components, and are applied to a /obj/item/bodypart (preferably attached to a carbon) when they take large spikes of damage + or under other certain conditions (thrown hard against a wall, sustained exposure to plasma fire, etc). Wounds are categorized by the three following criteria: + 1. Severity: Either MODERATE, SEVERE, or CRITICAL. See the hackmd for more details + 2. Viable zones: What body parts the wound is applicable to. Generic wounds like broken bones and severe burns can apply to every zone, but you may want to add special wounds for certain limbs + like a twisted ankle for legs only, or open air exposure of the organs for particularly gruesome chest wounds. Wounds should be able to function for every zone they are marked viable for. + 3. Damage type: Currently either BRUTE or BURN. Again, see the hackmd for a breakdown of my plans for each type. + + When a body part suffers enough damage to get a wound, the severity (determined by a roll or something, worse damage leading to worse wounds), affected limb, and damage type sustained are factored into + deciding what specific wound will be applied. I'd like to have a few different types of wounds for at least some of the choices, but I'm just doing rough generals for now. Expect polishing +*/ + +/datum/wound + /// What it's named + var/name = "ouchie" + /// The description shown on the scanners + var/desc = "" + /// The basic treatment suggested by health analyzers + var/treat_text = "" + /// What the limb looks like on a cursory examine + var/examine_desc = "is badly hurt" + + /// needed for "your arm has a compound fracture" vs "your arm has some third degree burns" + var/a_or_from = "a" + /// The visible message when this happens + var/occur_text = "" + /// This sound will be played upon the wound being applied + var/sound_effect + + /// Either WOUND_SEVERITY_TRIVIAL (meme wounds like stubbed toe), WOUND_SEVERITY_MODERATE, WOUND_SEVERITY_SEVERE, or WOUND_SEVERITY_CRITICAL (or maybe WOUND_SEVERITY_LOSS) + var/severity = WOUND_SEVERITY_MODERATE + /// The list of wounds it belongs in, WOUND_LIST_BONE, WOUND_LIST_CUT, or WOUND_LIST_BURN + var/wound_type + + /// What body zones can we affect + var/list/viable_zones = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + /// Who owns the body part that we're wounding + var/mob/living/carbon/victim = null + /// If we only work on organics (everything right now) + var/organic_only = TRUE + /// The bodypart we're parented to + var/obj/item/bodypart/limb = null + + /// Specific items such as bandages or sutures that can try directly treating this wound + var/list/treatable_by + /// Specific items such as bandages or sutures that can try directly treating this wound only if the user has the victim in an aggressive grab or higher + var/list/treatable_by_grabbed + /// Tools with the specified tool flag will also be able to try directly treating this wound + var/treatable_tool + /// Set to TRUE if we don't give a shit about the patient's comfort and are allowed to just use any random sharp thing on this wound. Will require an aggressive grab or more to perform + var/treatable_sharp + /// How long it will take to treat this wound with a standard effective tool, assuming it doesn't need surgery + var/base_treat_time = 5 SECONDS + + /// Using this limb in a do_after interaction will multiply the length by this duration (arms) + var/interaction_efficiency_penalty = 1 + /// Incoming damage on this limb will be multiplied by this, to simulate tenderness and vulnerability (mostly burns). + var/damage_mulitplier_penalty = 1 + /// If set and this wound is applied to a leg, we take this many deciseconds extra per step on this leg + var/limp_slowdown + /// How much we're contributing to this limb's bleed_rate + var/blood_flow + + /// The minimum we need to roll on [/obj/item/bodypart/proc/check_wounding()] to begin suffering this wound, see check_wounding_mods() for more + var/threshold_minimum + /// How much having this wound will add to all future check_wounding() rolls on this limb, to allow progression to worse injuries with repeated damage + var/threshold_penalty + /// If we need to process each life tick + var/processes = FALSE + + /// If TRUE and an item that can treat multiple different types of coexisting wounds (gauze can be used to splint broken bones, staunch bleeding, and cover burns), we get first dibs if we come up first for it, then become nonpriority. + /// Otherwise, if no untreated wound claims the item, we cycle through the non priority wounds and pick a random one who can use that item. + var/treat_priority = FALSE + + /// If having this wound makes currently makes the parent bodypart unusable + var/disabling + + /// What status effect we assign on application + var/status_effect_type + /// The status effect we're linked to + var/datum/status_effect/linked_status_effect + /// If we're operating on this wound and it gets healed, we'll nix the surgery too + var/datum/surgery/attached_surgery + /// if you're a lazy git and just throw them in cryo, the wound will go away after accumulating severity * 25 power + var/cryo_progress + + /// What kind of scars this wound will create description wise once healed + var/list/scarring_descriptions = list("general disfigurement") + /// If we've already tried scarring while removing (since remove_wound calls qdel, and qdel calls remove wound, .....) TODO: make this cleaner + var/already_scarred = FALSE + /// If we forced this wound through badmin smite, we won't count it towards the round totals + var/from_smite + +/datum/wound/Destroy() + if(attached_surgery) + QDEL_NULL(attached_surgery) + if(limb?.wounds && (src in limb.wounds)) // destroy can call remove_wound() and remove_wound() calls qdel, so we check to make sure there's anything to remove first + remove_wound() + limb = null + victim = null + return ..() + +/** + * apply_wound() is used once a wound type is instantiated to assign it to a bodypart, and actually come into play. + * + * + * Arguments: + * * L: The bodypart we're wounding, we don't care about the person, we can get them through the limb + * * silent: Not actually necessary I don't think, was originally used for demoting wounds so they wouldn't make new messages, but I believe old_wound took over that, I may remove this shortly + * * old_wound: If our new wound is a replacement for one of the same time (promotion or demotion), we can reference the old one just before it's removed to copy over necessary vars + * * smited- If this is a smite, we don't care about this wound for stat tracking purposes (not yet implemented) + */ +/datum/wound/proc/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE) + if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || isalien(L.owner)) + qdel(src) + return + + if(ishuman(L.owner)) + var/mob/living/carbon/human/H = L.owner + if(organic_only && ((NOBLOOD in H.dna.species.species_traits) || !L.is_organic_limb())) + qdel(src) + return + + // we accept promotions and demotions, but no point in redundancy. This should have already been checked wherever the wound was rolled and applied for (see: bodypart damage code), but we do an extra check + // in case we ever directly add wounds + for(var/i in L.wounds) + var/datum/wound/preexisting_wound = i + if((preexisting_wound.type == type) && (preexisting_wound != old_wound)) + qdel(src) + return + + victim = L.owner + limb = L + LAZYADD(victim.all_wounds, src) + LAZYADD(limb.wounds, src) + limb.update_wounds() + if(status_effect_type) + linked_status_effect = victim.apply_status_effect(status_effect_type, src) + SEND_SIGNAL(victim, COMSIG_CARBON_GAIN_WOUND, src, limb) + if(!victim.alerts["wound"]) // only one alert is shared between all of the wounds + victim.throw_alert("wound", /obj/screen/alert/status_effect/wound) + + var/demoted + if(old_wound) + demoted = (severity <= old_wound.severity) + + if(severity == WOUND_SEVERITY_TRIVIAL) + return + + if(!(silent || demoted)) + var/msg = "[victim]'s [limb.name] [occur_text]!" + var/vis_dist = COMBAT_MESSAGE_RANGE + + if(severity != WOUND_SEVERITY_MODERATE) + msg = "[msg]" + vis_dist = DEFAULT_MESSAGE_RANGE + + victim.visible_message(msg, "Your [limb.name] [occur_text]!", vision_distance = vis_dist) + if(sound_effect) + playsound(L.owner, sound_effect, 60 + 20 * severity, TRUE) + + if(!demoted) + wound_injury(old_wound) + second_wind() + +/// Remove the wound from whatever it's afflicting, and cleans up whateverstatus effects it had or modifiers it had on interaction times. ignore_limb is used for detachments where we only want to forget the victim +/datum/wound/proc/remove_wound(ignore_limb, replaced = FALSE) + //TODO: have better way to tell if we're getting removed without replacement (full heal) scar stuff + if(limb && !already_scarred && !replaced) + already_scarred = TRUE + var/datum/scar/new_scar = new + new_scar.generate(limb, src) + if(victim) + LAZYREMOVE(victim.all_wounds, src) + if(!victim.all_wounds) + victim.clear_alert("wound") + SEND_SIGNAL(victim, COMSIG_CARBON_LOSE_WOUND, src, limb) + if(limb && !ignore_limb) + LAZYREMOVE(limb.wounds, src) + limb.update_wounds() + +/** + * replace_wound() is used when you want to replace the current wound with a new wound, presumably of the same category, just of a different severity (either up or down counts) + * + * This proc actually instantiates the new wound based off the specific type path passed, then returns the new instantiated wound datum. + * + * Arguments: + * * new_type- The TYPE PATH of the wound you want to replace this, like /datum/wound/brute/cut/severe + * * smited- If this is a smite, we don't care about this wound for stat tracking purposes (not yet implemented) + */ +/datum/wound/proc/replace_wound(new_type, smited = FALSE) + var/datum/wound/new_wound = new new_type + already_scarred = TRUE + remove_wound(replaced=TRUE) + new_wound.apply_wound(limb, old_wound = src, smited = smited) + qdel(src) + return new_wound + +/// The immediate negative effects faced as a result of the wound +/datum/wound/proc/wound_injury(datum/wound/old_wound = null) + return + +/// Additional beneficial effects when the wound is gained, in case you want to give a temporary boost to allow the victim to try an escape or last stand +/datum/wound/proc/second_wind() + if(HAS_TRAIT(victim, TRAIT_NOMETABOLISM)) + return + + switch(severity) + if(WOUND_SEVERITY_MODERATE) + victim.reagents.add_reagent(/datum/reagent/determination, WOUND_DETERMINATION_MODERATE) + if(WOUND_SEVERITY_SEVERE) + victim.reagents.add_reagent(/datum/reagent/determination, WOUND_DETERMINATION_SEVERE) + if(WOUND_SEVERITY_CRITICAL) + victim.reagents.add_reagent(/datum/reagent/determination, WOUND_DETERMINATION_CRITICAL) + +/** + * try_treating() is an intercept run from [/mob/living/carbon/attackby()] right after surgeries but before anything else. Return TRUE here if the item is something that is relevant to treatment to take over the interaction. + * + * This proc leads into [/datum/wound/proc/treat()] and probably shouldn't be added onto in children types. You can specify what items or tools you want to be intercepted + * with var/list/treatable_by and var/treatable_tool, then if an item fulfills one of those requirements and our wound claims it first, it goes over to treat() and treat_self(). + * + * Arguments: + * * I: The item we're trying to use + * * user: The mob trying to use it on us + */ +/datum/wound/proc/try_treating(obj/item/I, mob/user) + // first we weed out if we're not dealing with our wound's bodypart, or if it might be an attack + if(!I || limb.body_zone != user.zone_selected || (I.force && user.a_intent != INTENT_HELP)) + return FALSE + + var/allowed = FALSE + + // check if we have a valid treatable tool (or, if cauteries are allowed, if we have something hot) + if((I.tool_behaviour == treatable_tool) || (treatable_tool == TOOL_CAUTERY && I.get_temperature())) + allowed = TRUE + // failing that, see if we're aggro grabbing them and if we have an item that works for aggro grabs only + else if(user.pulling == victim && user.grab_state >= GRAB_AGGRESSIVE && check_grab_treatments(I, user)) + allowed = TRUE + // failing THAT, we check if we have a generally allowed item + else + for(var/allowed_type in treatable_by) + if(istype(I, allowed_type)) + allowed = TRUE + break + + // if none of those apply, we return false to avoid interrupting + if(!allowed) + return FALSE + + // now that we've determined we have a valid attempt at treating, we can stomp on their dreams if we're already interacting with the patient + if(INTERACTING_WITH(user, victim)) + to_chat(user, "You're already interacting with [victim]!") + return TRUE + + // lastly, treat them + treat(I, user) + return TRUE + +/// Return TRUE if we have an item that can only be used while aggro grabbed (unhanded aggro grab treatments go in [/datum/wound/proc/try_handling()]). Treatment is still is handled in [/datum/wound/proc/treat()] +/datum/wound/proc/check_grab_treatments(obj/item/I, mob/user) + return FALSE + +/// Like try_treating() but for unhanded interactions from humans, used by joint dislocations for manual bodypart chiropractice for example. +/datum/wound/proc/try_handling(mob/living/carbon/human/user) + return FALSE + +/// Someone is using something that might be used for treating the wound on this limb +/datum/wound/proc/treat(obj/item/I, mob/user) + return + +/// If var/processing is TRUE, this is run on each life tick +/datum/wound/proc/handle_process() + return + +/// For use in do_after callback checks +/datum/wound/proc/still_exists() + return (!QDELETED(src) && limb) + +/// When our parent bodypart is hurt +/datum/wound/proc/receive_damage(wounding_type, wounding_dmg, wound_bonus) + return + +/// Called from cryoxadone and pyroxadone when they're proc'ing. Wounds will slowly be fixed separately from other methods when these are in effect. crappy name but eh +/datum/wound/proc/on_xadone(power) + cryo_progress += power + if(cryo_progress > 33 * severity) + qdel(src) + +/// Called when we're crushed in an airlock or firedoor, for one of the improvised joint dislocation fixes +/datum/wound/proc/crush() + return + +/** + * get_examine_description() is used in carbon/examine and human/examine to show the status of this wound. Useful if you need to show some status like the wound being splinted or bandaged. + * + * Return the full string line you want to show, note that we're already dealing with the 'warning' span at this point, and that \n is already appended for you in the place this is called from + * + * Arguments: + * * mob/user: The user examining the wound's owner, if that matters + */ +/datum/wound/proc/get_examine_description(mob/user) + return "[victim.p_their(TRUE)] [limb.name] [examine_desc]!" + +/datum/wound/proc/get_scanner_description(mob/user) + return "Type: [name]\nSeverity: [severity_text()]\nDescription: [desc]\nRecommended Treatment: [treat_text]" + +/datum/wound/proc/severity_text() + switch(severity) + if(WOUND_SEVERITY_TRIVIAL) + return "Trivial" + if(WOUND_SEVERITY_MODERATE) + return "Moderate" + if(WOUND_SEVERITY_SEVERE) + return "Severe" + if(WOUND_SEVERITY_CRITICAL) + return "Critical" diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm new file mode 100644 index 00000000000..6926d321660 --- /dev/null +++ b/code/datums/wounds/bones.dm @@ -0,0 +1,461 @@ + +/* + Bones +*/ +// TODO: well, a lot really, but i'd kill to get overlays and a bonebreaking effect like Blitz: The League, similar to electric shock skeletons + +/* + Base definition +*/ +/datum/wound/brute/bone + sound_effect = 'sound/effects/crack1.ogg' + wound_type = WOUND_LIST_BONE + + /// The item we're currently splinted with, if there is one + var/obj/item/stack/splinted + + /// Have we been taped? + var/taped + /// Have we been bone gel'd? + var/gelled + /// If we did the gel + surgical tape healing method for fractures, how many regen points we need + var/regen_points_needed + /// Our current counter for gel + surgical tape regeneration + var/regen_points_current + /// 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 + /// If this is a chest wound and this is set, we have this chance to cough up blood when hit in the chest + var/chance_internal_bleeding = 0 + +/* + Overwriting of base procs +*/ +/datum/wound/brute/bone/wound_injury(datum/wound/old_wound = null) + 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) + + RegisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, .proc/attack_with_hurt_hand) + 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() + + if(I && victim.dropItemToGround(I)) + victim.visible_message("[victim] drops [I] in shock!", "The force on your [limb.name] causes you to drop [I]!", vision_distance=COMBAT_MESSAGE_RANGE) + + update_inefficiencies() + +/datum/wound/brute/bone/remove_wound(ignore_limb, replaced) + limp_slowdown = 0 + QDEL_NULL(active_trauma) + if(victim) + UnregisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK) + return ..() + +/datum/wound/brute/bone/handle_process() + . = ..() + 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(!regen_points_needed) + return + + regen_points_current++ + if(prob(severity * 2)) + victim.take_bodypart_damage(rand(2, severity * 2), stamina=rand(2, severity * 2.5), wound_bonus=CANT_WOUND) + if(prob(33)) + to_chat(victim, "You feel a sharp pain in your body as your bones are reforming!") + + if(regen_points_current > regen_points_needed) + if(!victim || !limb) + qdel(src) + return + to_chat(victim, "Your [limb.name] has recovered from your fracture!") + remove_wound() + +/// If we're a human who's punching something with a broken arm, we might hurt ourselves doing so +/datum/wound/brute/bone/proc/attack_with_hurt_hand(mob/M, atom/target, proximity) + if(victim.get_active_hand() != limb || victim.a_intent == INTENT_HELP || !ismob(target) || severity <= WOUND_SEVERITY_MODERATE) + return + + // With a severe or critical wound, you have a 15% or 30% chance to proc pain on hit + if(prob((severity - 1) * 15)) + // And you have a 70% or 50% chance to actually land the blow, respectively + if(prob(70 - 20 * (severity - 1))) + to_chat(victim, "The fracture in your [limb.name] shoots with pain as you strike [target]!") + limb.receive_damage(brute=rand(1,5)) + else + victim.visible_message("[victim] weakly strikes [target] with [victim.p_their()] broken [limb.name], recoiling from pain!", \ + "You fail to strike [target] as the fracture in your [limb.name] lights up in unbearable pain!", vision_distance=COMBAT_MESSAGE_RANGE) + victim.emote("scream") + victim.Stun(0.5 SECONDS) + limb.receive_damage(brute=rand(3,7)) + return COMPONENT_NO_ATTACK_HAND + +/datum/wound/brute/bone/receive_damage(wounding_type, wounding_dmg, wound_bonus) + if(!victim) + return + + if(limb.body_zone == BODY_ZONE_CHEST && victim.blood_volume && prob(chance_internal_bleeding + wounding_dmg)) + var/blood_bled = rand(1, wounding_dmg * (severity == WOUND_SEVERITY_CRITICAL ? 2 : 1.5)) // 12 brute toolbox can cause up to 18/24 bleeding with a severe/critical chest wound + switch(blood_bled) + if(1 to 6) + victim.bleed(blood_bled, TRUE) + if(7 to 13) + victim.visible_message("[victim] coughs up a bit of blood from the blow to [victim.p_their()] chest.", "You cough up a bit of blood from the blow to your chest.") + victim.bleed(blood_bled, TRUE) + if(14 to 19) + victim.visible_message("[victim] spits out a string of blood from the blow to [victim.p_their()] chest!", "You spit out a string of blood from the blow to your chest!") + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) + victim.bleed(blood_bled) + if(20 to INFINITY) + victim.visible_message("[victim] chokes up a spray of blood from the blow to [victim.p_their()] chest!", "You choke up on a spray of blood from the blow to your chest!") + victim.bleed(blood_bled) + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) + victim.add_splatter_floor(get_step(victim.loc, victim.dir)) + + if(!(wounding_type in list(WOUND_SHARP, WOUND_BURN)) || !splinted || wound_bonus == CANT_WOUND) + return + + splinted.take_damage(wounding_dmg, damage_type = (wounding_type == WOUND_SHARP ? BRUTE : BURN), sound_effect = FALSE) + if(QDELETED(splinted)) + var/destroyed_verb = (wounding_type == WOUND_SHARP ? "torn" : "burned") + victim.visible_message("The splint securing [victim]'s [limb.name] is [destroyed_verb] away!", "The splint securing your [limb.name] is [destroyed_verb] away!", vision_distance=COMBAT_MESSAGE_RANGE) + splinted = null + treat_priority = TRUE + update_inefficiencies() + + +/datum/wound/brute/bone/get_examine_description(mob/user) + if(!splinted && !gelled && !taped) + return ..() + + var/msg = "" + if(!splinted) + msg = "[victim.p_their(TRUE)] [limb.name] [examine_desc]" + else + var/splint_condition = "" + // how much life we have left in these bandages + switch(splinted.obj_integrity / splinted.max_integrity * 100) + if(0 to 25) + splint_condition = "just barely " + if(25 to 50) + splint_condition = "loosely " + if(50 to 75) + splint_condition = "mostly " + if(75 to INFINITY) + splint_condition = "tightly " + + msg = "[victim.p_their(TRUE)] [limb.name] is [splint_condition] fastened in a splint of [splinted.name]" + + if(taped) + msg += ", and appears to be reforming itself under some surgical tape!" + else if(gelled) + msg += ", with fizzing flecks of blue bone gel sparking off the bone!" + else + msg += "!" + return "[msg]" + +/* + New common procs for /datum/wound/brute/bone/ +*/ + +/datum/wound/brute/bone/proc/update_inefficiencies() + if(limb.body_zone in list(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) + if(splinted) + limp_slowdown = initial(limp_slowdown) * splinted.splint_factor + else + limp_slowdown = initial(limp_slowdown) + victim.apply_status_effect(STATUS_EFFECT_LIMP) + else if(limb.body_zone in list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + if(splinted) + interaction_efficiency_penalty = 1 + ((interaction_efficiency_penalty - 1) * splinted.splint_factor) + else + interaction_efficiency_penalty = interaction_efficiency_penalty + + if(initial(disabling) && splinted) + disabling = FALSE + else if(initial(disabling)) + disabling = TRUE + + limb.update_wounds() + +/* + BEWARE OF REDUNDANCY AHEAD THAT I MUST PARE DOWN +*/ + +/datum/wound/brute/bone/proc/splint(obj/item/stack/I, mob/user) + if(splinted && splinted.splint_factor >= I.splint_factor) + to_chat(user, "The splint already on [user == victim ? "your" : "[victim]'s"] [limb.name] is better than you can do with [I].") + return + + user.visible_message("[user] begins splinting [victim]'s [limb.name] with [I].", "You begin splinting [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...") + + if(!do_after(user, base_treat_time * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, .proc/still_exists))) + return + + user.visible_message("[user] finishes splinting [victim]'s [limb.name]!", "You finish splinting [user == victim ? "your" : "[victim]'s"] [limb.name]!") + treat_priority = FALSE + splinted = new I.type(limb) + splinted.amount = 1 + I.use(1) + update_inefficiencies() + +/* + Moderate (Joint Dislocation) +*/ + +/datum/wound/brute/bone/moderate + name = "Joint Dislocation" + desc = "Patient's bone has been unset from socket, causing pain and reduced motor function." + treat_text = "Recommended application of bonesetter to affected limb, though manual relocation by applying an aggressive grab to the patient and helpfully interacting with afflicted limb may suffice." + examine_desc = "is awkwardly jammed out of place" + occur_text = "jerks violently and becomes unseated" + severity = WOUND_SEVERITY_MODERATE + viable_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + interaction_efficiency_penalty = 1.5 + limp_slowdown = 3 + threshold_minimum = 35 + threshold_penalty = 15 + treatable_tool = TOOL_BONESET + status_effect_type = /datum/status_effect/wound/bone/moderate + scarring_descriptions = list("light discoloring", "a slight blue tint") + +/datum/wound/brute/bone/moderate/crush() + if(prob(33)) + victim.visible_message("[victim]'s dislocated [limb.name] pops back into place!", "Your dislocated [limb.name] pops back into place! Ow!") + remove_wound() + +/datum/wound/brute/bone/moderate/try_handling(mob/living/carbon/human/user) + if(user.pulling != victim || user.zone_selected != limb.body_zone || user.a_intent == INTENT_GRAB) + return FALSE + + if(user.grab_state == GRAB_PASSIVE) + to_chat(user, "You must have [victim] in an aggressive grab to manipulate [victim.p_their()] [lowertext(name)]!") + return TRUE + + if(user.grab_state >= GRAB_AGGRESSIVE) + user.visible_message("[user] begins twisting and straining [victim]'s dislocated [limb.name]!", "You begin twisting and straining [victim]'s dislocated [limb.name]...", ignored_mobs=victim) + to_chat(victim, "[user] begins twisting and straining your dislocated [limb.name]!") + if(user.a_intent == INTENT_HELP) + chiropractice(user) + else + malpractice(user) + return TRUE + +/// If someone is snapping our dislocated joint back into place by hand with an aggro grab and help intent +/datum/wound/brute/bone/moderate/proc/chiropractice(mob/living/carbon/human/user) + var/time = base_treat_time + var/time_mod = user.mind?.get_skill_modifier(/datum/skill/healing, SKILL_SPEED_MODIFIER) + var/prob_mod = user.mind?.get_skill_modifier(/datum/skill/healing, SKILL_PROBS_MODIFIER) + if(time_mod) + time *= time_mod + + if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + + if(prob(65 + prob_mod)) + user.visible_message("[user] snaps [victim]'s dislocated [limb.name] back into place!", "You snap [victim]'s dislocated [limb.name] back into place!", ignored_mobs=victim) + to_chat(victim, "[user] snaps your dislocated [limb.name] back into place!") + victim.emote("scream") + limb.receive_damage(brute=20, wound_bonus=CANT_WOUND) + qdel(src) + else + user.visible_message("[user] wrenches [victim]'s dislocated [limb.name] around painfully!", "You wrench [victim]'s dislocated [limb.name] around painfully!", ignored_mobs=victim) + to_chat(victim, "[user] wrenches your dislocated [limb.name] around painfully!") + limb.receive_damage(brute=10, wound_bonus=CANT_WOUND) + chiropractice(user) + +/// If someone is snapping our dislocated joint into a fracture by hand with an aggro grab and harm or disarm intent +/datum/wound/brute/bone/moderate/proc/malpractice(mob/living/carbon/human/user) + var/time = base_treat_time + var/time_mod = user.mind?.get_skill_modifier(/datum/skill/healing, SKILL_SPEED_MODIFIER) + var/prob_mod = user.mind?.get_skill_modifier(/datum/skill/healing, SKILL_PROBS_MODIFIER) + if(time_mod) + time *= time_mod + + if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + + if(prob(65 + prob_mod)) + user.visible_message("[user] snaps [victim]'s dislocated [limb.name] with a sickening crack!", "You snap [victim]'s dislocated [limb.name] with a sickening crack!", ignored_mobs=victim) + to_chat(victim, "[user] snaps your dislocated [limb.name] with a sickening crack!") + victim.emote("scream") + limb.receive_damage(brute=25, wound_bonus=30 + prob_mod * 3) + else + user.visible_message("[user] wrenches [victim]'s dislocated [limb.name] around painfully!", "You wrench [victim]'s dislocated [limb.name] around painfully!", ignored_mobs=victim) + to_chat(victim, "[user] wrenches your dislocated [limb.name] around painfully!") + limb.receive_damage(brute=10, wound_bonus=CANT_WOUND) + malpractice(user) + + +/datum/wound/brute/bone/moderate/treat(obj/item/I, mob/user) + if(victim == user) + victim.visible_message("[user] begins resetting [victim.p_their()] [limb.name] with [I].", "You begin resetting your [limb.name] with [I]...") + else + user.visible_message("[user] begins resetting [victim]'s [limb.name] with [I].", "You begin resetting [victim]'s [limb.name] with [I]...") + + if(!do_after(user, base_treat_time * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, .proc/still_exists))) + return + + if(victim == user) + limb.receive_damage(brute=15, wound_bonus=CANT_WOUND) + victim.visible_message("[user] finishes resetting [victim.p_their()] [limb.name]!", "You reset your [limb.name]!") + else + limb.receive_damage(brute=10, wound_bonus=CANT_WOUND) + user.visible_message("[user] finishes resetting [victim]'s [limb.name]!", "You finish resetting [victim]'s [limb.name]!", victim) + to_chat(victim, "[user] resets your [limb.name]!") + + victim.emote("scream") + qdel(src) + +/* + Severe (Hairline Fracture) +*/ + +/datum/wound/brute/bone/severe + name = "Hairline Fracture" + desc = "Patient's bone has suffered a crack in the foundation, causing serious pain and reduced limb functionality." + treat_text = "Recommended light surgical application of bone gel, though splinting will prevent worsening situation." + examine_desc = "appears bruised and grotesquely swollen" + + occur_text = "sprays chips of bone and develops a nasty looking bruise" + severity = WOUND_SEVERITY_SEVERE + interaction_efficiency_penalty = 2 + limp_slowdown = 6 + threshold_minimum = 60 + threshold_penalty = 30 + treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/gauze, /obj/item/stack/medical/bone_gel) + status_effect_type = /datum/status_effect/wound/bone/severe + treat_priority = TRUE + scarring_descriptions = list("a faded, fist-sized bruise", "a vaguely triangular peel scar") + brain_trauma_group = BRAIN_TRAUMA_MILD + trauma_cycle_cooldown = 1.5 MINUTES + chance_internal_bleeding = 40 + +/datum/wound/brute/bone/critical + name = "Compound Fracture" + desc = "Patient's bones have suffered multiple gruesome fractures, causing significant pain and near uselessness of limb." + treat_text = "Immediate binding of affected limb, followed by surgical intervention ASAP." + examine_desc = "has a cracked bone sticking out of it" + occur_text = "cracks apart, exposing broken bones to open air" + severity = WOUND_SEVERITY_CRITICAL + interaction_efficiency_penalty = 4 + limp_slowdown = 9 + sound_effect = 'sound/effects/crack2.ogg' + threshold_minimum = 115 + threshold_penalty = 50 + disabling = TRUE + treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/gauze, /obj/item/stack/medical/bone_gel) + status_effect_type = /datum/status_effect/wound/bone/critical + treat_priority = TRUE + scarring_descriptions = list("a section of janky skin lines and badly healed scars", "a large patch of uneven skin tone", "a cluster of calluses") + brain_trauma_group = BRAIN_TRAUMA_SEVERE + trauma_cycle_cooldown = 2.5 MINUTES + chance_internal_bleeding = 60 + +// doesn't make much sense for "a" bone to stick out of your head +/datum/wound/brute/bone/critical/apply_wound(obj/item/bodypart/L, silent, datum/wound/old_wound, smited) + if(L.body_zone == BODY_ZONE_HEAD) + occur_text = "splits open, exposing a bare, cracked skull through the flesh and blood" + examine_desc = "has an unsettling indent, with bits of skull poking out" + . = ..() + +/// if someone is using bone gel on our wound +/datum/wound/brute/bone/proc/gel(obj/item/stack/medical/bone_gel/I, mob/user) + if(gelled) + to_chat(user, "[user == victim ? "Your" : "[victim]'s"] [limb.name] is already coated with bone gel!") + return + + user.visible_message("[user] begins hastily applying [I] to [victim]'s' [limb.name]...", "You begin hastily applying [I] to [user == victim ? "your" : "[victim]'s"] [limb.name], disregarding the warning label...") + + if(!do_after(user, base_treat_time * 1.5 * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, .proc/still_exists))) + return + + I.use(1) + victim.emote("scream") + if(user != victim) + user.visible_message("[user] finishes applying [I] to [victim]'s [limb.name], emitting a fizzing noise!", "You finish applying [I] to [victim]'s [limb.name]!", ignored_mobs=victim) + to_chat(victim, "[user] finishes applying [I] to your [limb.name], and you can feel the bones exploding with pain as they begin melting and reforming!") + else + var/painkiller_bonus = 0 + if(victim.drunkenness) + painkiller_bonus += 5 + if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/medicine/morphine)) + painkiller_bonus += 10 + if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/determination)) + painkiller_bonus += 5 + + if(prob(25 + (20 * severity - 2) - painkiller_bonus)) // 25%/45% chance to fail self-applying with severe and critical wounds, modded by painkillers + victim.visible_message("[victim] fails to finish applying [I] to [victim.p_their()] [limb.name], passing out from the pain!", "You black out from the pain of applying [I] to your [limb.name] before you can finish!") + victim.AdjustUnconscious(5 SECONDS) + return + victim.visible_message("[victim] finishes applying [I] to [victim.p_their()] [limb.name], grimacing from the pain!", "You finish applying [I] to your [limb.name], and your bones explode in pain!") + + limb.receive_damage(30, stamina=100, wound_bonus=CANT_WOUND) + if(!gelled) + gelled = TRUE + +/// if someone is using surgical tape on our wound +/datum/wound/brute/bone/proc/tape(obj/item/stack/sticky_tape/surgical/I, mob/user) + if(!gelled) + to_chat(user, "[user == victim ? "Your" : "[victim]'s"] [limb.name] must be coated with bone gel to perform this emergency operation!") + return + if(taped) + to_chat(user, "[user == victim ? "Your" : "[victim]'s"] [limb.name] is already wrapped in [I.name] and reforming!") + return + + user.visible_message("[user] begins applying [I] to [victim]'s' [limb.name]...", "You begin applying [I] to [user == victim ? "your" : "[victim]'s"] [limb.name]...") + + if(!do_after(user, base_treat_time * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, .proc/still_exists))) + return + + regen_points_current = 0 + regen_points_needed = 30 SECONDS * (user == victim ? 1.5 : 1) * (severity - 1) + I.use(1) + if(user != victim) + user.visible_message("[user] finishes applying [I] to [victim]'s [limb.name], emitting a fizzing noise!", "You finish applying [I] to [victim]'s [limb.name]!", ignored_mobs=victim) + to_chat(victim, "[user] finishes applying [I] to your [limb.name], you immediately begin to feel your bones start to reform!") + else + victim.visible_message("[victim] finishes applying [I] to [victim.p_their()] [limb.name], !", "You finish applying [I] to your [limb.name], and you immediately begin to feel your bones start to reform!") + + taped = TRUE + processes = TRUE + +/datum/wound/brute/bone/treat(obj/item/I, mob/user) + if(istype(I, /obj/item/stack/medical/bone_gel)) + gel(I, user) + else if(istype(I, /obj/item/stack/sticky_tape/surgical)) + tape(I, user) + else if(istype(I, /obj/item/stack/medical/gauze)) + splint(I, user) + +/datum/wound/brute/bone/get_scanner_description(mob/user) + . = ..() + + . += "
" + + if(!gelled) + . += "Alternative Treatment: Apply bone gel directly to injured limb, then apply surgical tape to begin bone regeneration. This is both excruciatingly painful and slow, and only recommended in dire circumstances.\n" + else if(!taped) + . += "Continue Alternative Treatment: Apply surgical tape directly to injured limb to begin bone regeneration. Note, this is both excruciatingly painful and slow.\n" + else + . += "Note: Bone regeneration in effect. Bone is [round(regen_points_current/regen_points_needed)]% regenerated.\n" + + if(limb.body_zone == BODY_ZONE_HEAD) + . += "Cranial Trauma Detected: Patient will suffer random bouts of [severity == WOUND_SEVERITY_SEVERE ? "mild" : "severe"] brain traumas until bone is repaired." + else if(limb.body_zone == BODY_ZONE_CHEST && victim.blood_volume) + . += "Ribcage Trauma Detected: Further trauma to chest is likely to worsen internal bleeding until bone is repaired." + . += "
" diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm new file mode 100644 index 00000000000..feff9bf4de4 --- /dev/null +++ b/code/datums/wounds/burns.dm @@ -0,0 +1,323 @@ + + + +// TODO: well, a lot really, but specifically I want to add potential fusing of clothing/equipment on the affected area, and limb infections, though those may go in body part code +/datum/wound/burn + a_or_from = "from" + wound_type = WOUND_LIST_BURN + processes = TRUE + sound_effect = 'sound/effects/sizzle1.ogg' + + treatable_by = list(/obj/item/stack/medical/gauze, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh) // sterilizer and alcohol will require reagent treatments, coming soon + + // Flesh damage vars + /// How much damage to our flesh we currently have. Once both this and infestation reach 0, the wound is considered healed + var/flesh_damage = 5 + /// Our current counter for how much flesh regeneration we have stacked from regenerative mesh/synthflesh/whatever, decrements each tick and lowers flesh_damage + var/flesh_healing = 0 + + // Infestation vars (only for severe and critical) + /// How quickly infection breeds on this burn if we don't have disinfectant + var/infestation_rate = 0 + /// Our current level of infection + var/infestation = 0 + /// Our current level of sanitization/anti-infection, from disinfectants/alcohol/UV lights. While positive, totally pauses and slowly reverses infestation effects each tick + var/sanitization = 0 + + /// Once we reach infestation beyond WOUND_INFESTATION_SEPSIS, we get this many warnings before the limb is completely paralyzed (you'd have to ignore a really bad burn for a really long time for this to happen) + var/strikes_to_lose_limb = 3 + + /// The current bandage we have for this wound (maybe move bandages to the limb?) + var/obj/item/stack/current_bandage + +/datum/wound/burn/handle_process() + . = ..() + if(strikes_to_lose_limb == 0) + victim.adjustToxLoss(0.5) + if(prob(1)) + victim.visible_message("The infection on the remnants of [victim]'s [limb.name] shift and bubble nauseatingly!", "You can feel the infection on the remnants of your [limb.name] coursing through your veins!") + return + + if(victim.reagents) + if(victim.reagents.has_reagent(/datum/reagent/medicine/spaceacillin)) + sanitization += 0.9 + if(victim.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine/)) + sanitization += 0.9 + if(victim.reagents.has_reagent(/datum/reagent/medicine/mine_salve)) + sanitization += 0.3 + flesh_healing += 0.5 + + if(current_bandage) + current_bandage.absorption_capacity -= WOUND_BURN_SANITIZATION_RATE + if(current_bandage.absorption_capacity <= 0) + victim.visible_message("Pus soaks through \the [current_bandage] on [victim]'s [limb.name].", "Pus soaks through \the [current_bandage] on your [limb.name].", vision_distance=COMBAT_MESSAGE_RANGE) + QDEL_NULL(current_bandage) + treat_priority = TRUE + + if(flesh_healing > 0) + var/bandage_factor = (current_bandage ? current_bandage.splint_factor : 1) + flesh_damage = max(0, flesh_damage - 1) + flesh_healing = max(0, flesh_healing - bandage_factor) // good bandages multiply the length of flesh healing + + // here's the check to see if we're cleared up + if((flesh_damage <= 0) && (infestation <= 1)) + to_chat(victim, "The burns on your [limb.name] have cleared up!") + qdel(src) + return + + // sanitization is checked after the clearing check but before the rest, because we freeze the effects of infection while we have sanitization + if(sanitization > 0) + var/bandage_factor = (current_bandage ? current_bandage.splint_factor : 1) + infestation = max(0, infestation - WOUND_BURN_SANITIZATION_RATE) + sanitization = max(0, sanitization - (WOUND_BURN_SANITIZATION_RATE * bandage_factor)) + return + + infestation += infestation_rate + + switch(infestation) + if(0 to WOUND_INFECTION_MODERATE) + if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE) + if(prob(30)) + victim.adjustToxLoss(0.2) + if(prob(6)) + to_chat(victim, "The blisters on your [limb.name] ooze a strange pus...") + if(WOUND_INFECTION_SEVERE to WOUND_INFECTION_CRITICAL) + if(!disabling && prob(2)) + to_chat(victim, "Your [limb.name] completely locks up, as you struggle for control against the infection!") + disabling = TRUE + else if(disabling && prob(8)) + to_chat(victim, "You regain sensation in your [limb.name], but it's still in terrible shape!") + disabling = FALSE + else if(prob(20)) + victim.adjustToxLoss(0.5) + if(WOUND_INFECTION_CRITICAL to WOUND_INFECTION_SEPTIC) + if(!disabling && prob(3)) + to_chat(victim, "You suddenly lose all sensation of the festering infection in your [limb.name]!") + disabling = TRUE + else if(disabling && prob(3)) + to_chat(victim, "You can barely feel your [limb.name] again, and you have to strain to retain motor control!") + disabling = FALSE + else if(prob(1)) + to_chat(victim, "You contemplate life without your [limb.name]...") + victim.adjustToxLoss(0.75) + else if(prob(4)) + victim.adjustToxLoss(1) + if(WOUND_INFECTION_SEPTIC to INFINITY) + if(prob(infestation)) + switch(strikes_to_lose_limb) + if(3 to INFINITY) + to_chat(victim, "The skin on your [limb.name] is literally dripping off, you feel awful!") + if(2) + to_chat(victim, "The infection in your [limb.name] is literally dripping off, you feel horrible!") + if(1) + to_chat(victim, "Infection has just about completely claimed your [limb.name]!") + if(0) + to_chat(victim, "The last of the nerve endings in your [limb.name] wither away, as the infection completely paralyzes your joint connector.") + threshold_penalty = 120 // piss easy to destroy + var/datum/brain_trauma/severe/paralysis/sepsis = new (limb.body_zone) + victim.gain_trauma(sepsis) + strikes_to_lose_limb-- + +/datum/wound/burn/get_examine_description(mob/user) + if(strikes_to_lose_limb <= 0) + return "[victim.p_their(TRUE)] [limb.name] is completely dead and unrecognizable as organic." + + var/condition = "" + if(current_bandage) + var/bandage_condition + switch(current_bandage.absorption_capacity) + if(0 to 1.25) + bandage_condition = "nearly ruined " + if(1.25 to 2.75) + bandage_condition = "badly worn " + if(2.75 to 4) + bandage_condition = "slightly pus-stained " + if(4 to INFINITY) + bandage_condition = "clean " + + condition += " underneath a dressing of [bandage_condition] [current_bandage.name]" + else + switch(infestation) + if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE) + condition += ", with small spots of discoloration along the nearby veins!" + if(WOUND_INFECTION_SEVERE to WOUND_INFECTION_CRITICAL) + condition += ", with dark clouds spreading outwards under the skin!" + if(WOUND_INFECTION_CRITICAL to WOUND_INFECTION_SEPTIC) + condition += ", with streaks of rotten infection pulsating outward!" + if(WOUND_INFECTION_SEPTIC to INFINITY) + return "[victim.p_their(TRUE)] [limb.name] is a mess of char and rot, skin literally dripping off the bone with infection!" + else + condition += "!" + + return "[victim.p_their(TRUE)] [limb.name] [examine_desc][condition]" + +/datum/wound/burn/get_scanner_description(mob/user) + if(strikes_to_lose_limb == 0) + var/oopsie = "Type: [name]\nSeverity: [severity_text()]" + oopsie += "
Infection Level: The infection is total. The bodypart is lost. Amputate or augment limb immediately.
" + return oopsie + + . = ..() + . += "
" + + if(infestation <= sanitization && flesh_damage <= flesh_healing) + . += "No further treatment required: Burns will heal shortly." + else + switch(infestation) + if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE) + . += "Infection Level: Moderate\n" + if(WOUND_INFECTION_SEVERE to WOUND_INFECTION_CRITICAL) + . += "Infection Level: Severe\n" + if(WOUND_INFECTION_CRITICAL to WOUND_INFECTION_SEPTIC) + . += "Infection Level: CRITICAL\n" + if(WOUND_INFECTION_SEPTIC to INFINITY) + . += "Infection Level: LOSS IMMINENT\n" + if(infestation > sanitization) + . += "\tSurgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n" + + if(flesh_damage > 0) + . += "Flesh damage detected: Please apply ointment or regenerative mesh to allow recovery.\n" + . += "
" + +/* + new burn common procs +*/ + +/// if someone is using ointment on our burns +/datum/wound/burn/proc/ointment(obj/item/stack/medical/ointment/I, mob/user) + user.visible_message("[user] begins applying [I] to [victim]'s [limb.name]...", "You begin applying [I] to [user == victim ? "your" : "[victim]'s"] [limb.name]...") + if(!do_after(user, (user == victim ? I.self_delay : I.other_delay), extra_checks = CALLBACK(src, .proc/still_exists))) + return + + limb.heal_damage(I.heal_brute, I.heal_burn) + user.visible_message("[user] applies [I] to [victim].", "You apply [I] to [user == victim ? "your" : "[victim]'s"] [limb.name].") + I.use(1) + sanitization += I.sanitization + flesh_healing += I.flesh_regeneration + + if((infestation <= 0 || sanitization >= infestation) && (flesh_damage <= 0 || flesh_healing > flesh_damage)) + to_chat(user, "You've done all you can with [I], now you must wait for the flesh on [victim]'s [limb.name] to recover.") + else + try_treating(I, user) + +/// for use in the burn dressing surgery since we don't want to make them do another do_after obviously +/datum/wound/burn/proc/force_bandage(obj/item/stack/medical/gauze/I, mob/user) + QDEL_NULL(current_bandage) + current_bandage = new I.type(limb) + current_bandage.amount = 1 + treat_priority = FALSE + sanitization += I.sanitization + I.use(1) + +/// if someone is wrapping gauze on our burns +/datum/wound/burn/proc/bandage(obj/item/stack/medical/gauze/I, mob/user) + if(current_bandage) + if(current_bandage.absorption_capacity > I.absorption_capacity + 1) + to_chat(user, "The [current_bandage] on [victim]'s [limb.name] is still in better condition than your [I.name]!") + return + user.visible_message("[user] begins to redress the burns on [victim]'s [limb.name] with [I]...", "You begin redressing the burns on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...") + else + user.visible_message("[user] begins to dress the burns on [victim]'s [limb.name] with [I]...", "You begin dressing the burns on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...") + + if(!do_after(user, (user == victim ? I.self_delay : I.other_delay), target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + + user.visible_message("[user] applies [I] to [victim].", "You apply [I] to [user == victim ? "your" : "[victim]'s"] [limb.name].") + QDEL_NULL(current_bandage) + current_bandage = new I.type(limb) + current_bandage.amount = 1 + treat_priority = FALSE + sanitization += I.sanitization + I.use(1) + +/// if someone is using mesh on our burns +/datum/wound/burn/proc/mesh(obj/item/stack/medical/mesh/I, mob/user) + user.visible_message("[user] begins wrapping [victim]'s [limb.name] with [I]...", "You begin wrapping [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...") + if(!do_after(user, (user == victim ? I.self_delay : I.other_delay), target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + + limb.heal_damage(I.heal_brute, I.heal_burn) + user.visible_message("[user] applies [I] to [victim].", "You apply [I] to [user == victim ? "your" : "[victim]'s"] [limb.name].") + I.use(1) + sanitization += I.sanitization + flesh_healing += I.flesh_regeneration + + if(sanitization >= infestation && flesh_healing > flesh_damage) + to_chat(user, "You've done all you can with [I], now you must wait for the flesh on [victim]'s [limb.name] to recover.") + else + try_treating(I, user) + +/// Paramedic UV penlights +/datum/wound/burn/proc/uv(obj/item/flashlight/pen/paramedic/I, mob/user) + if(I.uv_cooldown > world.time) + to_chat(user, "[I] is still recharging!") + return + if(infestation <= 0 || infestation < sanitization) + to_chat(user, "There's no infection to treat on [victim]'s [limb.name]!") + return + + user.visible_message("[user] flashes the burns on [victim]'s [limb] with [I].", "You flash the burns on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I].", vision_distance=COMBAT_MESSAGE_RANGE) + sanitization += I.uv_power + I.uv_cooldown = world.time + I.uv_cooldown_length + +/datum/wound/burn/treat(obj/item/I, mob/user) + if(istype(I, /obj/item/stack/medical/gauze)) + bandage(I, user) + else if(istype(I, /obj/item/stack/medical/ointment)) + ointment(I, user) + else if(istype(I, /obj/item/stack/medical/mesh)) + mesh(I, user) + else if(istype(I, /obj/item/flashlight/pen/paramedic)) + uv(I, user) + +/// basic support for instabitaluri/synthflesh healing flesh damage, more chem support in the future +/datum/wound/burn/proc/regenerate_flesh(amount) + flesh_healing += amount * 0.5 // 20u patch will heal 10 flesh standard + +// we don't even care about first degree burns, straight to second +/datum/wound/burn/moderate + name = "Second Degree Burns" + desc = "Patient is suffering considerable burns with mild skin penetration, weakening limb integrity and increased burning sensations." + treat_text = "Recommended application of topical ointment or regenerative mesh to affected region." + examine_desc = "is badly burned and breaking out in blisters" + occur_text = "breaks out with violent red burns" + severity = WOUND_SEVERITY_MODERATE + damage_mulitplier_penalty = 1.1 + threshold_minimum = 40 + threshold_penalty = 30 // burns cause significant decrease in limb integrity compared to other wounds + status_effect_type = /datum/status_effect/wound/burn/moderate + flesh_damage = 5 + scarring_descriptions = list("small amoeba-shaped skinmarks", "a faded streak of depressed skin") + +/datum/wound/burn/severe + name = "Third Degree Burns" + desc = "Patient is suffering extreme burns with full skin penetration, creating serious risk of infection and greatly reduced limb integrity." + treat_text = "Recommended immediate disinfection and excision of any infected skin, followed by bandaging and ointment." + examine_desc = "appears seriously charred, with aggressive red splotches" + occur_text = "chars rapidly, exposing ruined tissue and spreading angry red burns" + severity = WOUND_SEVERITY_SEVERE + damage_mulitplier_penalty = 1.2 + threshold_minimum = 80 + threshold_penalty = 40 + status_effect_type = /datum/status_effect/wound/burn/severe + treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/gauze, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh) + infestation_rate = 0.05 // appx 13 minutes to reach sepsis without any treatment + flesh_damage = 12.5 + scarring_descriptions = list("a large, jagged patch of faded skin", "random spots of shiny, smooth skin", "spots of taut, leathery skin") + +/datum/wound/burn/critical + name = "Catastrophic Burns" + desc = "Patient is suffering near complete loss of tissue and significantly charred muscle and bone, creating life-threatening risk of infection and negligible limb integrity." + treat_text = "Immediate surgical debriding of any infected skin, followed by potent tissue regeneration formula and bandaging." + examine_desc = "is a ruined mess of blanched bone, melted fat, and charred tissue" + occur_text = "vaporizes as flesh, bone, and fat melt together in a horrifying mess" + severity = WOUND_SEVERITY_CRITICAL + damage_mulitplier_penalty = 1.3 + sound_effect = 'sound/effects/sizzle2.ogg' + threshold_minimum = 140 + threshold_penalty = 80 + status_effect_type = /datum/status_effect/wound/burn/critical + treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/gauze, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh) + infestation_rate = 0.15 // appx 4.33 minutes to reach sepsis without any treatment + flesh_damage = 20 + scarring_descriptions = list("massive, disfiguring keloid scars", "several long streaks of badly discolored and malformed skin", "unmistakeable splotches of dead tissue from serious burns") diff --git a/code/datums/wounds/cuts.dm b/code/datums/wounds/cuts.dm new file mode 100644 index 00000000000..61a4b8a1ea0 --- /dev/null +++ b/code/datums/wounds/cuts.dm @@ -0,0 +1,309 @@ + +/* + Cuts +*/ + +/datum/wound/brute/cut + sound_effect = 'sound/weapons/slice.ogg' + processes = TRUE + wound_type = WOUND_LIST_CUT + treatable_by = list(/obj/item/stack/medical/suture, /obj/item/stack/medical/gauze) + treatable_by_grabbed = list(/obj/item/gun/energy/laser) + treatable_tool = TOOL_CAUTERY + treat_priority = TRUE + base_treat_time = 3 SECONDS + + /// How much blood we start losing when this wound is first applied + var/initial_flow + /// When we have less than this amount of flow, either from treatment or clotting, we demote to a lower cut or are healed of the wound + var/minimum_flow + /// How fast our blood flow will naturally decrease per tick, not only do larger cuts bleed more faster, they clot slower + var/clot_rate + + /// Once the blood flow drops below minimum_flow, we demote it to this type of wound. If there's none, we're all better + var/demotes_to + + /// How much staunching per type (cautery, suturing, bandaging) you can have before that type is no longer effective for this cut NOT IMPLEMENTED + var/max_per_type + /// The maximum flow we've had so far + var/highest_flow + /// How much flow we've already cauterized + var/cauterized + /// How much flow we've already sutured + var/sutured + + /// The current bandage we have for this wound (maybe move bandages to the limb?) + var/obj/item/stack/current_bandage + /// A bad system I'm using to track the worst scar we earned (since we can demote, we want the biggest our wound has been, not what it was when it was cured (probably moderate)) + var/datum/scar/highest_scar + +/datum/wound/brute/cut/wound_injury(datum/wound/brute/cut/old_wound = null) + blood_flow = initial_flow + if(old_wound) + blood_flow = max(old_wound.blood_flow, initial_flow) + if(old_wound.severity > severity && old_wound.highest_scar) + highest_scar = old_wound.highest_scar + old_wound.highest_scar = null + if(old_wound.current_bandage) + current_bandage = old_wound.current_bandage + old_wound.current_bandage = null + + if(!highest_scar) + highest_scar = new + highest_scar.generate(limb, src, add_to_scars=FALSE) + +/datum/wound/brute/cut/remove_wound(ignore_limb, replaced) + if(!replaced && highest_scar) + already_scarred = TRUE + highest_scar.lazy_attach(limb) + return ..() + +/datum/wound/brute/cut/get_examine_description(mob/user) + if(!current_bandage) + return ..() + + var/bandage_condition = "" + // how much life we have left in these bandages + switch(current_bandage.absorption_capacity) + if(0 to 1.25) + bandage_condition = "nearly ruined " + if(1.25 to 2.75) + bandage_condition = "badly worn " + if(2.75 to 4) + bandage_condition = "slightly bloodied " + if(4 to INFINITY) + bandage_condition = "clean " + return "The cuts on [victim.p_their()] [limb.name] are wrapped with [bandage_condition] [current_bandage.name]!" + +/datum/wound/brute/cut/receive_damage(wounding_type, wounding_dmg, wound_bonus) + if(victim.stat != DEAD && wounding_type == WOUND_SHARP) // can't stab dead bodies to make it bleed faster this way + blood_flow += 0.05 * wounding_dmg + +/datum/wound/brute/cut/handle_process() + blood_flow = min(blood_flow, WOUND_CUT_MAX_BLOODFLOW) + + if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/toxin/heparin)) + blood_flow += 0.5 // old herapin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first + else if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/medicine/coagulant)) + blood_flow -= 0.25 + + if(current_bandage) + if(clot_rate > 0) + blood_flow -= clot_rate + blood_flow -= current_bandage.absorption_rate + current_bandage.absorption_capacity -= current_bandage.absorption_rate + if(current_bandage.absorption_capacity < 0) + victim.visible_message("Blood soaks through \the [current_bandage] on [victim]'s [limb.name].", "Blood soaks through \the [current_bandage] on your [limb.name].", vision_distance=COMBAT_MESSAGE_RANGE) + QDEL_NULL(current_bandage) + treat_priority = TRUE + else + blood_flow -= clot_rate + + if(blood_flow > highest_flow) + highest_flow = blood_flow + + if(blood_flow < minimum_flow) + if(demotes_to) + replace_wound(demotes_to) + else + to_chat(victim, "The cut on your [limb.name] has stopped bleeding!") + qdel(src) + +/* BEWARE, THE BELOW NONSENSE IS MADNESS. bones.dm looks more like what I have in mind and is sufficiently clean, don't pay attention to this messiness */ + +/datum/wound/brute/cut/check_grab_treatments(obj/item/I, mob/user) + if(istype(I, /obj/item/gun/energy/laser)) + return TRUE + +/datum/wound/brute/cut/treat(obj/item/I, mob/user) + if(istype(I, /obj/item/gun/energy/laser)) + las_cauterize(I, user) + else if(I.tool_behaviour == TOOL_CAUTERY || I.get_temperature() > 300) + tool_cauterize(I, user) + else if(istype(I, /obj/item/stack/medical/gauze)) + bandage(I, user) + else if(istype(I, /obj/item/stack/medical/suture)) + suture(I, user) + +/datum/wound/brute/cut/try_handling(mob/living/carbon/human/user) + if(user.pulling != victim || user.zone_selected != limb.body_zone || user.a_intent == INTENT_GRAB) + return FALSE + + if(!isfelinid(user)) + return FALSE + + lick_wounds(user) + return TRUE + +/// if a felinid is licking this cut to reduce bleeding +/datum/wound/brute/cut/proc/lick_wounds(mob/living/carbon/human/user) + if(INTERACTING_WITH(user, victim)) + to_chat(user, "You're already interacting with [victim]!") + return + + user.visible_message("[user] begins licking the wounds on [victim]'s [limb.name].", "You begin licking the wounds on [victim]'s [limb.name]...", ignored_mobs=victim) + to_chat(victim, "[user] begins to lick the wounds on your [limb.name].[user] licks the wounds on [victim]'s [limb.name].", "You lick some of the wounds on [victim]'s [limb.name]", ignored_mobs=victim) + to_chat(victim, "[user] licks the wounds on your [limb.name]! minimum_flow) + try_handling(user) + else if(demotes_to) + to_chat(user, "You successfully lower the severity of [victim]'s cuts.") + +/datum/wound/brute/cut/on_xadone(power) + . = ..() + blood_flow -= 0.03 * power // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort + +/// If someone's putting a laser gun up to our cut to cauterize it +/datum/wound/brute/cut/proc/las_cauterize(obj/item/gun/energy/laser/lasgun, mob/user) + var/self_penalty_mult = (user == victim ? 1.25 : 1) + user.visible_message("[user] begins aiming [lasgun] directly at [victim]'s [limb.name]...", "You begin aiming [lasgun] directly at [user == victim ? "your" : "[victim]'s"] [limb.name]...") + if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + var/damage = lasgun.chambered.BB.damage + lasgun.chambered.BB.wound_bonus -= 30 + lasgun.chambered.BB.damage *= self_penalty_mult + if(!lasgun.process_fire(victim, victim, TRUE, null, limb.body_zone)) + return + victim.emote("scream") + blood_flow -= damage / (5 * self_penalty_mult) // 20 / 5 = 4 bloodflow removed, p good + cauterized += damage / (5 * self_penalty_mult) + victim.visible_message("The cuts on [victim]'s [limb.name] scar over!") + +/// If someone is using either a cautery tool or something with heat to cauterize this cut +/datum/wound/brute/cut/proc/tool_cauterize(obj/item/I, mob/user) + var/self_penalty_mult = (user == victim ? 1.5 : 1) + user.visible_message("[user] begins cauterizing [victim]'s [limb.name] with [I]...", "You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...") + var/time_mod = user.mind?.get_skill_modifier(/datum/skill/healing, SKILL_SPEED_MODIFIER) || 1 + if(!do_after(user, base_treat_time * time_mod * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + + user.visible_message("[user] cauterizes some of the bleeding on [victim].", "You cauterize some of the bleeding on [victim].") + limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND) + if(prob(30)) + victim.emote("scream") + var/blood_cauterized = (0.6 / self_penalty_mult) + blood_flow -= blood_cauterized + cauterized += blood_cauterized + + if(blood_flow > minimum_flow) + try_treating(I, user) + else if(demotes_to) + to_chat(user, "You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts.") + +/// If someone is using a suture to close this cut +/datum/wound/brute/cut/proc/suture(obj/item/stack/medical/suture/I, mob/user) + var/self_penalty_mult = (user == victim ? 1.4 : 1) + user.visible_message("[user] begins stitching [victim]'s [limb.name] with [I]...", "You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...") + var/time_mod = user.mind?.get_skill_modifier(/datum/skill/healing, SKILL_SPEED_MODIFIER) || 1 + if(!do_after(user, base_treat_time * time_mod * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + user.visible_message("[user] stitches up some of the bleeding on [victim].", "You stitch up some of the bleeding on [user == victim ? "yourself" : "[victim]"].") + var/blood_sutured = I.stop_bleeding / self_penalty_mult + blood_flow -= blood_sutured + sutured += blood_sutured + limb.heal_damage(I.heal_brute, I.heal_burn) + + if(blood_flow > minimum_flow) + try_treating(I, user) + else if(demotes_to) + to_chat(user, "You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts.") + +/// If someone is using gauze on this cut +/datum/wound/brute/cut/proc/bandage(obj/item/stack/I, mob/user) + if(current_bandage) + if(current_bandage.absorption_capacity > I.absorption_capacity + 1) + to_chat(user, "The [current_bandage] on [victim]'s [limb.name] is still in better condition than your [I.name]!") + return + else + user.visible_message("[user] begins rewrapping the cuts on [victim]'s [limb.name] with [I]...", "You begin rewrapping the cuts on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...") + else + user.visible_message("[user] begins wrapping the cuts on [victim]'s [limb.name] with [I]...", "You begin wrapping the cuts on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...") + var/time_mod = user.mind?.get_skill_modifier(/datum/skill/healing, SKILL_SPEED_MODIFIER) || 1 + if(!do_after(user, base_treat_time * time_mod, target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + + user.visible_message("[user] applies [I] to [victim]'s [limb.name].", "You bandage some of the bleeding on [user == victim ? "yourself" : "[victim]"].") + QDEL_NULL(current_bandage) + current_bandage = new I.type(limb) + current_bandage.amount = 1 + treat_priority = FALSE + I.use(1) + + +/datum/wound/brute/cut/moderate + name = "Rough Abrasion" + desc = "Patient's skin has been badly scraped, generating moderate blood loss." + treat_text = "Application of clean bandages or first-aid grade sutures, followed by food and rest." + examine_desc = "has an open cut" + occur_text = "is cut open, slowly leaking blood" + sound_effect = 'sound/effects/blood1.ogg' + severity = WOUND_SEVERITY_MODERATE + initial_flow = 2 + minimum_flow = 0.5 + max_per_type = 3 + clot_rate = 0.15 + threshold_minimum = 20 + threshold_penalty = 10 + status_effect_type = /datum/status_effect/wound/cut/moderate + scarring_descriptions = list("light, faded lines", "minor cut marks", "a small faded slit", "a series of small scars") + +/datum/wound/brute/cut/severe + name = "Open Laceration" + desc = "Patient's skin is ripped clean open, allowing significant blood loss." + treat_text = "Speedy application of first-aid grade sutures and clean bandages, followed by vitals monitoring to ensure recovery." + examine_desc = "has a severe cut" + occur_text = "is ripped open, veins spurting blood" + sound_effect = 'sound/effects/blood2.ogg' + severity = WOUND_SEVERITY_SEVERE + initial_flow = 3.25 + minimum_flow = 2.75 + clot_rate = 0.07 + max_per_type = 4 + threshold_minimum = 50 + threshold_penalty = 25 + demotes_to = /datum/wound/brute/cut/moderate + status_effect_type = /datum/status_effect/wound/cut/severe + scarring_descriptions = list("a twisted line of faded gashes", "a gnarled sickle-shaped slice scar", "a long-faded puncture wound") + +/datum/wound/brute/cut/critical + name = "Weeping Avulsion" + desc = "Patient's skin is completely torn open, along with significant loss of tissue. Extreme blood loss will lead to quick death without intervention." + treat_text = "Immediate bandaging and either suturing or cauterization, followed by supervised resanguination." + examine_desc = "is spurting blood at an alarming rate" + occur_text = "is torn open, spraying blood wildly" + sound_effect = 'sound/effects/blood3.ogg' + severity = WOUND_SEVERITY_CRITICAL + initial_flow = 4.25 + minimum_flow = 4 + clot_rate = -0.05 // critical cuts actively get worse instead of better + max_per_type = 5 + threshold_minimum = 80 + threshold_penalty = 40 + demotes_to = /datum/wound/brute/cut/severe + status_effect_type = /datum/status_effect/wound/cut/critical + scarring_descriptions = list("a winding path of very badly healed scar tissue", "a series of peaks and valleys along a gruesome line of cut scar tissue", "a grotesque snake of indentations and stitching scars") + +// TODO: see about moving dismemberment over to this, i'll have to add judging dismembering power/wound potential wrt item size i guess +/datum/wound/brute/cut/loss + name = "Dismembered" + desc = "oof ouch!!" + occur_text = "is violently dismembered!" + sound_effect = 'sound/effects/dismember.ogg' + viable_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + severity = WOUND_SEVERITY_LOSS + threshold_minimum = 180 + status_effect_type = null + +/datum/wound/brute/cut/loss/apply_wound(obj/item/bodypart/L, silent, datum/wound/brute/cut/old_wound, smited = FALSE) + if(!L.dismemberable) + qdel(src) + return + + L.dismember() + qdel(src) diff --git a/code/datums/wounds/scars/_scars.dm b/code/datums/wounds/scars/_scars.dm new file mode 100644 index 00000000000..bfbaab835e6 --- /dev/null +++ b/code/datums/wounds/scars/_scars.dm @@ -0,0 +1,134 @@ +/** + * scars are cosmetic datums that are assigned to bodyparts once they recover from wounds. Each wound type and severity have their own descriptions for what the scars + * look like, and then each body part has a list of "specific locations" like your elbow or wrist or wherever the scar can appear, to make it more interesting than "right arm" + * + * + * Arguments: + * * + */ +/datum/scar + var/obj/item/bodypart/limb + var/mob/living/carbon/victim + var/severity + var/description + var/precise_location + + /// Scars from the longtimer quirk are "fake" and won't be saved with persistent scarring, since it makes you spawn with a lot by default + var/fake=FALSE + + /// How many tiles away someone can see this scar, goes up with severity. Clothes covering this limb will decrease visibility by 1 each, except for the head/face which is a binary "is mask obscuring face" check + var/visibility = 2 + /// Whether this scar can actually be covered up by clothing + var/coverable = TRUE + /// What zones this scar can be applied to + var/list/applicable_zones = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_ARM, BODY_ZONE_R_LEG) + +/datum/scar/Destroy(force, ...) + if(limb) + LAZYREMOVE(limb.scars, src) + if(victim) + LAZYREMOVE(victim.all_scars, src) + . = ..() + +/** + * generate() is used to actually fill out the info for a scar, according to the limb and wound it is provided. + * + * After creating a scar, call this on it while targeting the scarred bodypart with a given wound to apply the scar. + * + * Arguments: + * * BP- The bodypart being targeted + * * W- The wound being used to generate the severity and description info + * * add_to_scars- Should always be TRUE unless you're just storing a scar for later usage, like how cuts want to store a scar for the highest severity of cut, rather than the severity when the wound is fully healed (probably demoted to moderate) + */ +/datum/scar/proc/generate(obj/item/bodypart/BP, datum/wound/W, add_to_scars=TRUE) + if(!(BP.body_zone in applicable_zones)) + qdel(src) + return + limb = BP + severity = W.severity + if(limb.owner) + victim = limb.owner + if(add_to_scars) + LAZYADD(limb.scars, src) + if(victim) + LAZYADD(victim.all_scars, src) + + description = pick(W.scarring_descriptions) + precise_location = pick(limb.specific_locations) + switch(W.severity) + if(WOUND_SEVERITY_MODERATE) + visibility = 2 + if(WOUND_SEVERITY_SEVERE) + visibility = 3 + if(WOUND_SEVERITY_CRITICAL) + visibility = 5 + +/// Used when we finalize a scar from a healing cut +/datum/scar/proc/lazy_attach(obj/item/bodypart/BP, datum/wound/W) + LAZYADD(BP.scars, src) + if(BP.owner) + victim = BP.owner + LAZYADD(victim.all_scars, src) + +/// Used to "load" a persistent scar +/datum/scar/proc/load(obj/item/bodypart/BP, description, specific_location, severity=WOUND_SEVERITY_SEVERE) + if(!(BP.body_zone in applicable_zones)) + qdel(src) + return + limb = BP + src.severity = severity + LAZYADD(limb.scars, src) + if(BP.owner) + victim = BP.owner + LAZYADD(victim.all_scars, src) + src.description = description + precise_location = specific_location + switch(severity) + if(WOUND_SEVERITY_MODERATE) + visibility = 2 + if(WOUND_SEVERITY_SEVERE) + visibility = 3 + if(WOUND_SEVERITY_CRITICAL) + visibility = 5 + return TRUE + +/// What will show up in examine_more() if this scar is visible +/datum/scar/proc/get_examine_description(mob/viewer) + if(!victim || !is_visible(viewer)) + return + + var/msg = "[victim.p_they(TRUE)] [victim.p_have()] [description] on [victim.p_their()] [precise_location]." + switch(severity) + if(WOUND_SEVERITY_MODERATE) + msg = "[msg]" + if(WOUND_SEVERITY_SEVERE) + msg = "[msg]" + if(WOUND_SEVERITY_CRITICAL) + msg = "[msg]" + return "\t[msg]" + +/// Whether a scar can currently be seen by the viewer +/datum/scar/proc/is_visible(mob/viewer) + if(!victim || !viewer) + return + if(get_dist(viewer, victim) > visibility) + return + + if(!ishuman(victim) || isobserver(viewer) || victim == viewer) + return TRUE + + var/mob/living/carbon/human/H = victim + if(istype(limb, /obj/item/bodypart/head)) + if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE))) + return FALSE + else if(limb.scars_covered_by_clothes) + var/num_covers = LAZYLEN(H.clothingonpart(limb)) + if(num_covers + get_dist(viewer, victim) >= visibility) + return FALSE + + return TRUE + +/// Used to format a scar to safe in preferences for persistent scars +/datum/scar/proc/format() + if(!fake) + return "[limb.body_zone]|[description]|[precise_location]|[severity]" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index b2624057960..e47da358723 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -540,6 +540,19 @@ . += "It's empty." SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) +/** + * Called when a mob examines (shift click or verb) this atom twice (or more) within EXAMINE_MORE_TIME (default 1.5 seconds) + * + * This is where you can put extra information on something that may be superfluous or not important in critical gameplay + * moments, while allowing people to manually double-examine to take a closer look + * + * Produces a signal [COMSIG_PARENT_EXAMINE_MORE] + */ +/atom/proc/examine_more(mob/user) + . = list() + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE_MORE, user, .) + if(!LAZYLEN(.)) // lol ..length + return list("You examine [src] closer, but find nothing of interest...") /// Updates the icon of the atom /atom/proc/update_icon() @@ -1241,6 +1254,37 @@ var/reverse_message = "has been [what_done] by [ssource][postfix]" target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE) +/** + * log_wound() is for when someone is *attacked* and suffers a wound. Note that this only captures wounds from damage, so smites/forced wounds aren't logged, as well as demotions like cuts scabbing over + * + * Note that this has no info on the attack that dealt the wound: information about where damage came from isn't passed to the bodypart's damaged proc. When in doubt, check the attack log for attacks at that same time + * TODO later: Add logging for healed wounds, though that will require some rewriting of healing code to prevent admin heals from spamming the logs. Not high priority + * + * Arguments: + * * victim- The guy who got wounded + * * suffered_wound- The wound, already applied, that we're logging. It has to already be attached so we can get the limb from it + * * dealt_damage- How much damage is associated with the attack that dealt with this wound. + * * dealt_wound_bonus- The wound_bonus, if one was specified, of the wounding attack + * * dealt_bare_wound_bonus- The bare_wound_bonus, if one was specified *and applied*, of the wounding attack. Not shown if armor was present + * * base_roll- Base wounding ability of an attack is a random number from 1 to (dealt_damage ** WOUND_DAMAGE_EXPONENT). This is the number that was rolled in there, before mods + */ +/proc/log_wound(atom/victim, datum/wound/suffered_wound, dealt_damage, dealt_wound_bonus, dealt_bare_wound_bonus, base_roll) + var/message = "has suffered: [suffered_wound] to [suffered_wound.limb.name]" // maybe indicate if it's a promote/demote? + + if(dealt_damage) + message += " | Damage: [dealt_damage]" + // The base roll is useful since it can show how lucky someone got with the given attack. For example, dealing a cut + if(base_roll) + message += "(rolled [base_roll]/[dealt_damage ** WOUND_DAMAGE_EXPONENT])" + + if(dealt_wound_bonus) + message += " | WB: [dealt_wound_bonus]" + + if(dealt_bare_wound_bonus) + message += " | BWB: [dealt_bare_wound_bonus]" + + victim.log_message(message, LOG_ATTACK, color="blue") + /atom/movable/proc/add_filter(name,priority,list/params) LAZYINITLIST(filter_data) var/list/p = params.Copy() diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index acb0ba691d5..fbee034949d 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -348,6 +348,10 @@ /obj/machinery/door/proc/crush() for(var/mob/living/L in get_turf(src)) L.visible_message("[src] closes on [L], crushing [L.p_them()]!", "[src] closes on you and crushes you!") + if(iscarbon(L)) + var/mob/living/carbon/C = L + for(var/datum/wound/W in C.all_wounds) + W.crush(DOOR_CRUSH_DAMAGE) if(isalien(L)) //For xenos L.adjustBruteLoss(DOOR_CRUSH_DAMAGE * 1.5) //Xenos go into crit after aproximately the same amount of crushes as humans. L.emote("roar") diff --git a/code/game/machinery/medical_kiosk.dm b/code/game/machinery/medical_kiosk.dm index ba33ab23ad5..203b8c627b2 100644 --- a/code/game/machinery/medical_kiosk.dm +++ b/code/game/machinery/medical_kiosk.dm @@ -207,7 +207,7 @@ sickness_data = "\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]" if(altPatient.has_dna()) //Blood levels Information - if(altPatient.bleed_rate) + if(altPatient.is_bleeding()) bleed_status = "Patient is currently bleeding!" if(blood_percent <= 80) blood_warning = " Patient has low blood levels. Seek a large meal, or iron supplements." diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index eb190a75df4..7130eb705ce 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -179,9 +179,21 @@ var/T = get_turf(target) if(locate(/mob/living) in T) new /obj/effect/temp_visual/medical_holosign(T,user) //produce a holographic glow - holo_cooldown = world.time + 100 + holo_cooldown = world.time + 10 SECONDS return +// see: [/datum/wound/burn/proc/uv()] +/obj/item/flashlight/pen/paramedic + name = "paramedic penlight" + desc = "A high-powered UV penlight intended to help stave off infection in the field on serious burned patients. Probably really bad to look into." + icon_state = "penlight_surgical" + /// Our current UV cooldown + var/uv_cooldown = 0 + /// How long between UV fryings + var/uv_cooldown_length = 1 MINUTES + /// How much sanitization to apply to the burn wound + var/uv_power = 1 + /obj/effect/temp_visual/medical_holosign name = "medical holosign" desc = "A small holographic glow that indicates a medic is coming to treat a patient." diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index c83dfcd48f9..c7dc1066601 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -11,9 +11,10 @@ GENE SCANNER */ -// Describes the two modes of scanning available for health analyzers +// Describes the three modes of scanning available for health analyzers #define SCANMODE_HEALTH 0 #define SCANMODE_CHEMICAL 1 +#define SCANMODE_WOUND 2 #define SCANNER_CONDENSED 0 #define SCANNER_VERBOSE 1 @@ -104,8 +105,14 @@ GENE SCANNER return BRUTELOSS /obj/item/healthanalyzer/attack_self(mob/user) - scanmode = !scanmode - to_chat(user, "You switch the health analyzer to [scanmode ? "scan chemical contents" : "check physical health"].") + scanmode = (scanmode + 1) % 3 + switch(scanmode) + if(SCANMODE_HEALTH) + to_chat(user, "You switch the health analyzer to check physical health.") + if(SCANMODE_CHEMICAL) + to_chat(user, "You switch the health analyzer to scan chemical contents.") + if(SCANMODE_WOUND) + to_chat(user, "You switch the health analyzer to report extra info on wounds.") /obj/item/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user) flick("[icon_state]-scan", src) //makes it so that it plays the scan animation upon scanning, including clumsy scanning @@ -125,8 +132,10 @@ GENE SCANNER if(scanmode == SCANMODE_HEALTH) healthscan(user, M, mode, advanced) - else + else if(scanmode == SCANMODE_CHEMICAL) chemscan(user, M) + else + woundscan(user, M, src) add_fingerprint(user) @@ -187,6 +196,8 @@ GENE SCANNER trauma_desc += "severe " if(TRAUMA_RESILIENCE_LOBOTOMY) trauma_desc += "deep-rooted " + if(TRAUMA_RESILIENCE_WOUND) + trauma_desc += "fracture-derived " if(TRAUMA_RESILIENCE_MAGIC, TRAUMA_RESILIENCE_ABSOLUTE) trauma_desc += "permanent " trauma_desc += B.scan_desc @@ -324,6 +335,18 @@ GENE SCANNER var/tdelta = round(world.time - M.timeofdeath) render_list += "Subject died [DisplayTimeText(tdelta)] ago.\n" + // Wounds + if(iscarbon(M)) + var/mob/living/carbon/C = M + var/list/wounded_parts = C.get_wounded_bodyparts() + for(var/i in wounded_parts) + var/obj/item/bodypart/wounded_part = i + render_list += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]" + for(var/k in wounded_part.wounds) + var/datum/wound/W = k + render_list += "
Type: [W.name]\nSeverity: [W.severity_text()]\nRecommended Treatment: [W.treat_text]
\n" // less lines than in woundscan() so we don't overload people trying to get basic med info + render_list += "
" + for(var/thing in M.diseases) var/datum/disease/D = thing if(!(D.visibility_flags & HIDDEN_SCANNER)) @@ -338,7 +361,7 @@ GENE SCANNER if(blood_id) if(ishuman(C)) var/mob/living/carbon/human/H = C - if(H.bleed_rate) + if(H.is_bleeding()) render_list += "Subject is bleeding!\n" var/blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100) var/blood_type = C.dna.blood_type @@ -397,6 +420,63 @@ GENE SCANNER desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy." advanced = TRUE +/// Displays wounds with extended information on their status vs medscanners +/proc/woundscan(mob/user, mob/living/carbon/patient, obj/item/healthanalyzer/wound/scanner) + if(!istype(patient)) + return + + var/render_list = "" + for(var/i in patient.get_wounded_bodyparts()) + var/obj/item/bodypart/wounded_part = i + render_list += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]" + for(var/k in wounded_part.wounds) + var/datum/wound/W = k + render_list += "
[W.get_scanner_description()]
\n" + render_list += "
" + + if(render_list == "") + playsound(scanner, 'sound/machines/ping.ogg', 50, FALSE) + to_chat(user, "\The [scanner] makes a happy ping and briefly displays a smiley face with several exclamation points! It's really excited to report that [patient] has no wounds!") + else + to_chat(user, jointext(render_list, "")) + +/obj/item/healthanalyzer/wound + name = "first aid analyzer" + icon_state = "adv_spectrometer" + desc = "A prototype MeLo-Tech medical scanner used to diagnose injuries and recommend treatment for serious wounds, but offers no further insight into the patient's health. You hope the final version is less annoying to read!" + var/next_encouragement + var/greedy + +/obj/item/healthanalyzer/wound/attack_self(mob/user) + if(next_encouragement < world.time) + playsound(src, 'sound/machines/ping.ogg', 50, FALSE) + var/list/encouragements = list("briefly displays a happy face, gazing emptily at you", "briefly displays a spinning cartoon heart", "displays an encouraging message about eating healthy and exercising", \ + "reminds you that everyone is doing their best", "displays a message wishing you well", "displays a sincere thank-you for your interest in first-aid", "formally absolves you of all your sins") + to_chat(user, "\The [src] makes a happy ping and [pick(encouragements)]!") + next_encouragement = world.time + 10 SECONDS + greedy = FALSE + else if(!greedy) + to_chat(user, "\The [src] displays an eerily high-definition frowny face, chastizing you for asking it for too much encouragement.") + greedy = TRUE + else + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + if(isliving(user)) + var/mob/living/L = user + to_chat(L, "\The [src] makes a disappointed buzz and pricks your finger for being greedy. Ow!") + L.adjustBruteLoss(4) + L.dropItemToGround(src) + +/obj/item/healthanalyzer/wound/attack(mob/living/carbon/patient, mob/living/carbon/human/user) + add_fingerprint(user) + user.visible_message("[user] scans [patient] for serious injuries.", "You scan [patient] for serious injuries.") + + if(!istype(patient)) + playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) + to_chat(user, "\The [src] makes a sad buzz and briefly displays a frowny face, indicating it can't scan [patient].") + return + + woundscan(user, patient, src) + /obj/item/analyzer desc = "A hand-held environmental scanner which reports current gas levels. Alt-Click to use the built in barometer function." name = "analyzer" @@ -802,5 +882,6 @@ GENE SCANNER #undef SCANMODE_HEALTH #undef SCANMODE_CHEMICAL +#undef SCANMODE_WOUND #undef SCANNER_CONDENSED #undef SCANNER_VERBOSE diff --git a/code/game/objects/items/dualsaber.dm b/code/game/objects/items/dualsaber.dm index e8c99f98f40..1b5d6d5d300 100644 --- a/code/game/objects/items/dualsaber.dm +++ b/code/game/objects/items/dualsaber.dm @@ -23,6 +23,8 @@ max_integrity = 200 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) resistance_flags = FIRE_PROOF + wound_bonus = -110 + bare_wound_bonus = 20 var/two_hand_force = 34 var/hacked = FALSE var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD diff --git a/code/game/objects/items/fireaxe.dm b/code/game/objects/items/fireaxe.dm index 512ca1f4b0e..b0ecff19839 100644 --- a/code/game/objects/items/fireaxe.dm +++ b/code/game/objects/items/fireaxe.dm @@ -17,6 +17,7 @@ max_integrity = 200 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) resistance_flags = FIRE_PROOF + wound_bonus = -20 var/wielded = FALSE // track wielded status on item /obj/item/fireaxe/Initialize() diff --git a/code/game/objects/items/grenades/flashbang.dm b/code/game/objects/items/grenades/flashbang.dm index 2a42bce4ad2..b44a735e1da 100644 --- a/code/game/objects/items/grenades/flashbang.dm +++ b/code/game/objects/items/grenades/flashbang.dm @@ -57,6 +57,14 @@ shrapnel_type = /obj/projectile/bullet/pellet/stingball/mega shrapnel_radius = 12 +/obj/item/grenade/stingbang/breaker + name = "breakbang" + shrapnel_type = /obj/projectile/bullet/pellet/stingball/breaker + +/obj/item/grenade/stingbang/shred + name = "shredbang" + shrapnel_type = /obj/projectile/bullet/pellet/stingball/shred + /obj/item/grenade/stingbang/prime(mob/living/lanced_by) if(iscarbon(loc)) var/mob/living/carbon/C = loc diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 5f233bc9eca..169f805fef9 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -201,6 +201,7 @@ throwforce = 10 w_class = WEIGHT_CLASS_TINY obj_flags = UNIQUE_RENAME + wound_bonus = -10 var/reskinned = FALSE var/chaplain_spawnable = TRUE @@ -602,6 +603,8 @@ item_flags = ABSTRACT w_class = WEIGHT_CLASS_HUGE sharpness = IS_SHARP + wound_bonus = -20 + bare_wound_bonus = 25 /obj/item/nullrod/armblade/Initialize() . = ..() diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 7219fe980c6..87fceeff6f2 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -89,6 +89,8 @@ item_flags = EYE_STAB var/bayonet = FALSE //Can this be attached to a gun? custom_price = 250 + wound_bonus = -5 + bare_wound_bonus = 10 /obj/item/kitchen/knife/ComponentInitialize() . = ..() diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm index 2eb1ba8cb8b..55e57bcdee1 100644 --- a/code/game/objects/items/manuals.dm +++ b/code/game/objects/items/manuals.dm @@ -432,7 +432,9 @@ if(prob(50)) step(W, pick(GLOB.alldirs)) ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC) - H.bleed_rate = 5 + for(var/i in H.bodyparts) + var/obj/item/bodypart/BP = i + BP.generic_bleedstacks += 5 H.gib_animation() sleep(3) H.adjustBruteLoss(1000) //to make the body super-bloody diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 98dd8794274..20b53c0788c 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -20,6 +20,8 @@ slot_flags = ITEM_SLOT_BELT force = 10 throwforce = 7 + wound_bonus = 15 + bare_wound_bonus = 10 w_class = WEIGHT_CLASS_NORMAL attack_verb = list("flogged", "whipped", "lashed", "disciplined") hitsound = 'sound/weapons/chainhit.ogg' @@ -193,6 +195,8 @@ var/force_off // Damage when off - not stunning var/weight_class_on // What is the new size class when turned on + wound_bonus = 15 + // Description for trying to stun when still on cooldown. /obj/item/melee/classic_baton/proc/get_wait_description() return @@ -340,6 +344,7 @@ force_on = 10 force_off = 0 weight_class_on = WEIGHT_CLASS_BULKY + bare_wound_bonus = 5 /obj/item/melee/classic_baton/telescopic/suicide_act(mob/user) var/mob/living/carbon/human/H = user diff --git a/code/game/objects/items/melee/transforming.dm b/code/game/objects/items/melee/transforming.dm index a2e10426784..15feb3e78a6 100644 --- a/code/game/objects/items/melee/transforming.dm +++ b/code/game/objects/items/melee/transforming.dm @@ -13,6 +13,8 @@ var/list/nemesis_factions //Any mob with a faction that exists in this list will take bonus damage/effects var/w_class_on = WEIGHT_CLASS_BULKY var/clumsy_check = TRUE + wound_bonus = -30 + bare_wound_bonus = 40 /obj/item/melee/transforming/Initialize() . = ..() diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index 516bbb5f1b8..ff62775bd90 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -93,7 +93,7 @@ target.visible_message("[user]'s powerfist lets out a weak hiss as [user.p_they()] punch[user.p_es()] [target.name]!", \ "[user]'s punch strikes with force!") return - target.apply_damage(force * fisto_setting, BRUTE) + target.apply_damage(force * fisto_setting, BRUTE, wound_bonus = -25*fisto_setting**2) target.visible_message("[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!", \ "You cry out in pain as [user]'s punch flings you backwards!") new /obj/effect/temp_visual/kinetic_blast(target.loc) diff --git a/code/game/objects/items/shrapnel.dm b/code/game/objects/items/shrapnel.dm index cd3436846e6..9ac91317cd1 100644 --- a/code/game/objects/items/shrapnel.dm +++ b/code/game/objects/items/shrapnel.dm @@ -7,11 +7,13 @@ icon_state = "large" w_class = WEIGHT_CLASS_TINY item_flags = DROPDEL + sharpness = TRUE /obj/item/shrapnel/stingball // stingbang grenades name = "stingball" embedding = list(embed_chance=90, fall_chance=3, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.7, pain_mult=5, jostle_pain_mult=6, rip_time=15, embed_chance_turf_mod=-100) icon_state = "tiny" + sharpness = FALSE /obj/item/shrapnel/bullet // bullets name = "bullet" @@ -28,7 +30,7 @@ /obj/projectile/bullet/shrapnel name = "flying shrapnel shard" - damage = 9 + damage = 8 range = 10 armour_penetration = -30 dismemberment = 5 @@ -37,6 +39,8 @@ shrapnel_type = /obj/item/shrapnel ricochet_incidence_leeway = 60 hit_stunned_targets = TRUE + sharpness = TRUE + wound_bonus = 30 /obj/projectile/bullet/shrapnel/mega name = "flying shrapnel hunk" @@ -64,5 +68,17 @@ ricochets_max = 6 ricochet_chance = 110 +/obj/projectile/bullet/pellet/stingball/breaker + name = "breakbang pellet" + damage = 10 + wound_bonus = 40 + sharpness = FALSE + +/obj/projectile/bullet/pellet/stingball/shred + name = "shredbang pellet" + damage = 10 + wound_bonus = 30 + sharpness = TRUE + /obj/projectile/bullet/pellet/stingball/on_ricochet(atom/A) hit_stunned_targets = TRUE // ducking will save you from the first wave, but not the rebounds diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index f9d9e294fb7..4e25c4e931d 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -20,6 +20,8 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) var/war_cry = "AAAAARGH!!!" var/icon_prefix = "spearglass" + wound_bonus = -25 + bare_wound_bonus = 15 /obj/item/spear/ComponentInitialize() . = ..() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index ca543f4a05d..a2448fe0b27 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -16,6 +16,16 @@ var/other_delay = 0 var/repeating = FALSE var/experience_given = 1 + /// How much brute we heal per application + var/heal_brute + /// How much burn we heal per application + var/heal_burn + /// How much we reduce bleeding per application on cut wounds + var/stop_bleeding + /// How much sanitization to apply to burns on application + var/sanitization + /// How much we add to flesh_healing for burn wounds on application + var/flesh_regeneration /obj/item/stack/medical/attack(mob/living/M, mob/user) . = ..() @@ -75,8 +85,9 @@ icon_state = "brutepack" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - var/heal_brute = 40 - self_delay = 20 + heal_brute = 40 + self_delay = 40 + other_delay = 20 grind_results = list(/datum/reagent/medicine/C2/libital = 10) /obj/item/stack/medical/bruise_pack/heal(mob/living/M, mob/user) @@ -95,8 +106,8 @@ M.heal_bodypart_damage((heal_brute/2)) return TRUE if(iscarbon(M)) - return heal_carbon(M, user, heal_brute, 0) - to_chat(user, "You can't heal [M] with the \the [src]!") + return heal_carbon(M, user, heal_brute, heal_burn) + to_chat(user, "You can't heal [M] with \the [src]!") /obj/item/stack/medical/bruise_pack/suicide_act(mob/user) user.visible_message("[user] is bludgeoning [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -104,28 +115,32 @@ /obj/item/stack/medical/gauze name = "medical gauze" - desc = "A roll of elastic cloth that is extremely effective at stopping bleeding, but does not heal wounds." + desc = "A roll of elastic cloth, perfect for stabilizing all kinds of wounds, from cuts and burns, to broken bones. " gender = PLURAL singular_name = "medical gauze" icon_state = "gauze" - var/stop_bleeding = 1800 - self_delay = 20 + self_delay = 50 + other_delay = 20 max_amount = 12 + amount = 6 grind_results = list(/datum/reagent/cellulose = 2) custom_price = 100 + absorption_rate = 0.25 + absorption_capacity = 5 + splint_factor = 0.35 + +// gauze is only relevant for wounds, which are handled in the wounds themselves +/obj/item/stack/medical/gauze/try_heal(mob/living/M, mob/user, silent) + var/obj/item/bodypart/limb = M.get_bodypart(check_zone(user.zone_selected)) + if(limb) + if(limb.brute_dam > 40) + to_chat(user, "The bleeding on [user==M ? "your" : "[M]'s"] [limb.name] is from bruising, and cannot be treated with [src]!") + else + to_chat(user, "There's no bleeding on [user==M ? "your" : "[M]'s"] [limb.name]") /obj/item/stack/medical/gauze/twelve amount = 12 -/obj/item/stack/medical/gauze/heal(mob/living/M, mob/user) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!H.bleedsuppress && H.bleed_rate) //so you can't stack bleed suppression - H.suppress_bloodloss(stop_bleeding) - to_chat(user, "You stop the bleeding of [M]!") - return TRUE - to_chat(user, "You can not use \the [src] on [M]!") - /obj/item/stack/medical/gauze/attackby(obj/item/I, mob/user, params) if(I.tool_behaviour == TOOL_WIRECUTTER || I.get_sharpness()) if(get_amount() < 2) @@ -146,57 +161,45 @@ /obj/item/stack/medical/gauze/improvised name = "improvised gauze" singular_name = "improvised gauze" - desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds." - stop_bleeding = 900 + desc = "A roll of cloth roughly cut from something that does a decent job of stabilizing wounds, but less efficiently so than real medical gauze." + self_delay = 60 + other_delay = 30 + absorption_rate = 0.15 + absorption_capacity = 4 /obj/item/stack/medical/gauze/cyborg custom_materials = null is_cyborg = 1 cost = 250 -/obj/item/stack/medical/ointment - name = "ointment" - desc = "Used to treat those nasty burn wounds." - gender = PLURAL - singular_name = "ointment" - icon_state = "ointment" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - var/heal_burn = 40 - self_delay = 20 - grind_results = list(/datum/reagent/medicine/C2/lenturi = 10) - -/obj/item/stack/medical/ointment/heal(mob/living/M, mob/user) - if(M.stat == DEAD) - to_chat(user, "[M] is dead! You can not help [M.p_them()].") - return - if(iscarbon(M)) - return heal_carbon(M, user, 0, heal_burn) - to_chat(user, "You can't heal [M] with the \the [src]!") - -/obj/item/stack/medical/ointment/suicide_act(mob/living/user) - user.visible_message("[user] is squeezing \the [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?") - return TOXLOSS - /obj/item/stack/medical/suture name = "suture" - desc = "Sterile sutures used to seal up cuts and lacerations." + desc = "Basic sterile sutures used to seal up cuts and lacerations and stop bleeding." gender = PLURAL singular_name = "suture" icon_state = "suture" self_delay = 30 other_delay = 10 - amount = 15 - max_amount = 15 + amount = 10 + max_amount = 10 repeating = TRUE - var/heal_brute = 10 + heal_brute = 10 + stop_bleeding = 0.6 grind_results = list(/datum/reagent/medicine/spaceacillin = 2) +/obj/item/stack/medical/suture/emergency + name = "emergency suture" + desc = "A value pack of cheap sutures, not very good at repairing damage, but still decent at stopping bleeding." + heal_brute = 5 + amount = 5 + max_amount = 5 + /obj/item/stack/medical/suture/medicated name = "medicated suture" icon_state = "suture_purp" desc = "A suture infused with drugs that speed up wound healing of the treated laceration." heal_brute = 15 + stop_bleeding = 0.75 grind_results = list(/datum/reagent/medicine/polypyr = 2) /obj/item/stack/medical/suture/heal(mob/living/M, mob/user) @@ -205,7 +208,7 @@ to_chat(user, "[M] is dead! You can not help [M.p_them()].") return if(iscarbon(M)) - return heal_carbon(M, user, heal_brute, 0) + return heal_carbon(M, user, heal_brute, heal_burn) if(isanimal(M)) var/mob/living/simple_animal/critter = M if (!(critter.healable)) @@ -218,7 +221,37 @@ M.heal_bodypart_damage(heal_brute) return TRUE - to_chat(user, "You can't heal [M] with the \the [src]!") + to_chat(user, "You can't heal [M] with \the [src]!") + +/obj/item/stack/medical/ointment + name = "ointment" + desc = "Basic burn ointment, rated effective for second degree burns with proper bandaging, though it's still an effective stabilizer for worse burns. Not terribly good at outright healing burns though." + gender = PLURAL + singular_name = "ointment" + icon_state = "ointment" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + amount = 10 + max_amount = 10 + self_delay = 40 + other_delay = 20 + + heal_burn = 5 + flesh_regeneration = 2.5 + sanitization = 0.3 + grind_results = list(/datum/reagent/medicine/C2/lenturi = 10) + +/obj/item/stack/medical/ointment/heal(mob/living/M, mob/user) + if(M.stat == DEAD) + to_chat(user, "[M] is dead! You can not help [M.p_them()].") + return + if(iscarbon(M)) + return heal_carbon(M, user, heal_brute, heal_burn) + to_chat(user, "You can't heal [M] with \the [src]!") + +/obj/item/stack/medical/ointment/suicide_act(mob/living/user) + user.visible_message("[user] is squeezing \the [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?") + return TOXLOSS /obj/item/stack/medical/mesh name = "regenerative mesh" @@ -229,9 +262,12 @@ self_delay = 30 other_delay = 10 amount = 15 + heal_burn = 10 max_amount = 15 repeating = TRUE - var/heal_burn = 10 + sanitization = 0.75 + flesh_regeneration = 3 + var/is_open = TRUE ///This var determines if the sterile packaging of the mesh has been opened. grind_results = list(/datum/reagent/medicine/spaceacillin = 2) @@ -253,8 +289,8 @@ to_chat(user, "[M] is dead! You can not help [M.p_them()].") return if(iscarbon(M)) - return heal_carbon(M, user, 0, heal_burn) - to_chat(user, "You can't heal [M] with the \the [src]!") + return heal_carbon(M, user, heal_brute, heal_burn) + to_chat(user, "You can't heal [M] with \the [src]!") /obj/item/stack/medical/mesh/try_heal(mob/living/M, mob/user, silent = FALSE) @@ -292,6 +328,8 @@ singular_name = "advanced regenerative mesh" icon_state = "aloe_mesh" heal_burn = 15 + sanitization = 1.25 + flesh_regeneration = 3.5 grind_results = list(/datum/reagent/consumable/aloejuice = 1) /obj/item/stack/medical/mesh/advanced/update_icon_state() @@ -334,7 +372,6 @@ to_chat(user, "You can't heal [M] with the \the [src]!") - /* The idea is for these medical devices to work like a hybrid of the old brute packs and tend wounds, they heal a little at a time, have reduced healing density and does not allow for rapid healing while in combat. @@ -342,3 +379,49 @@ The interesting limb targeting mechanic is retained and i still believe they will be a viable choice, especially when healing others in the field. */ + +/obj/item/stack/medical/bone_gel + name = "bone gel" + singular_name = "bone gel" + desc = "A potent medical gel that, when applied to a damaged bone in a proper surgical setting, triggers an intense melding reaction to repair the wound. Can be directly applied alongside surgical sticky tape to a broken bone in dire circumstances, though this is very harmful to the patient and not recommended." + + icon = 'icons/obj/surgery.dmi' + icon_state = "bone-gel" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + + amount = 4 + self_delay = 20 + grind_results = list(/datum/reagent/medicine/C2/libital = 10) + novariants = TRUE + +/obj/item/stack/medical/bone_gel/attack(mob/living/M, mob/user) + to_chat(user, "Bone gel can only be used on fractured limbs!") + return + +/obj/item/stack/medical/bone_gel/suicide_act(mob/user) + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.visible_message("[C] is squirting all of \the [src] into [C.p_their()] mouth! That's not proper procedure! It looks like [C.p_theyre()] trying to commit suicide!") + if(do_after(C, 2 SECONDS)) + C.emote("scream") + for(var/i in C.bodyparts) + var/obj/item/bodypart/bone = i + var/datum/wound/brute/bone/severe/oof_ouch = new + oof_ouch.apply_wound(bone) + var/datum/wound/brute/bone/critical/oof_OUCH = new + oof_OUCH.apply_wound(bone) + + for(var/i in C.bodyparts) + var/obj/item/bodypart/bone = i + bone.receive_damage(brute=60) + use(1) + return (BRUTELOSS) + else + C.visible_message("[C] screws up like an idiot and still dies anyway!") + return (BRUTELOSS) + +/obj/item/stack/medical/bone_gel/cyborg + custom_materials = null + is_cyborg = 1 + cost = 250 diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 1df89067b4a..0ea8b83e065 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -14,6 +14,7 @@ icon = 'icons/obj/stack_objects.dmi' gender = PLURAL material_modifier = 0.01 + max_integrity = 100 var/list/datum/stack_recipe/recipes var/singular_name var/amount = 1 @@ -30,6 +31,15 @@ //NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind() var/obj/structure/table/tableVariant // we tables now (stores table variant to be built from this stack) + // The following are all for medical treatment, they're here instead of /stack/medical because sticky tape can be used as a makeshift bandage or splint + /// If set and this used as a splint for a broken bone wound, this is used as a multiplier for applicable slowdowns (lower = better) (also for speeding up burn recoveries) + var/splint_factor + /// How much blood flow this stack can absorb if used as a bandage on a cut wound, note that absorption is how much we lower the flow rate, not the raw amount of blood we suck up + var/absorption_capacity + /// How quickly we lower the blood flow on a cut wound we're bandaging. Expected lifetime of this bandage in ticks is thus absorption_capacity/absorption_rate, or until the cut heals, whichever comes first + var/absorption_rate + + /obj/item/stack/on_grind() for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists grind_results[grind_results[i]] *= get_amount() //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size diff --git a/code/game/objects/items/stacks/tape.dm b/code/game/objects/items/stacks/tape.dm index f7760622c2c..60ee47f0549 100644 --- a/code/game/objects/items/stacks/tape.dm +++ b/code/game/objects/items/stacks/tape.dm @@ -7,11 +7,14 @@ icon = 'icons/obj/tapes.dmi' icon_state = "tape_w" var/prefix = "sticky" + w_class = WEIGHT_CLASS_TINY + full_w_class = WEIGHT_CLASS_TINY item_flags = NOBLUDGEON amount = 5 max_amount = 5 resistance_flags = FLAMMABLE grind_results = list(/datum/reagent/cellulose = 5) + splint_factor = 0.8 var/list/conferred_embed = EMBED_HARMLESS var/overwrite_existing = FALSE @@ -51,6 +54,7 @@ icon_state = "tape_y" prefix = "super sticky" conferred_embed = EMBED_HARMLESS_SUPERIOR + splint_factor = 0.6 /obj/item/stack/sticky_tape/pointy name = "pointy tape" @@ -67,3 +71,13 @@ icon_state = "tape_spikes" prefix = "super pointy" conferred_embed = EMBED_POINTY_SUPERIOR + +/obj/item/stack/sticky_tape/surgical + name = "surgical tape" + singular_name = "surgical tape" + desc = "Made for patching broken bones back together alongside bone gel, not for playing pranks." + //icon_state = "tape_spikes" + prefix = "surgical" + conferred_embed = list("embed_chance" = 30, "pain_mult" = 0, "jostle_pain_mult" = 0, "ignore_throwspeed_threshold" = TRUE) + splint_factor = 0.4 + custom_price = 500 diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 38becaec6ce..1d39f887c87 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -373,6 +373,7 @@ new /obj/item/circular_saw(src) new /obj/item/surgicaldrill(src) new /obj/item/cautery(src) + new /obj/item/bonesetter(src) new /obj/item/surgical_drapes(src) new /obj/item/clothing/mask/surgical(src) new /obj/item/razor(src) @@ -392,6 +393,7 @@ new /obj/item/hemostat(src) new /obj/item/retractor(src) new /obj/item/circular_saw(src) + new /obj/item/bonesetter(src) new /obj/item/surgicaldrill(src) new /obj/item/cautery(src) new /obj/item/surgical_drapes(src) @@ -477,6 +479,7 @@ new /obj/item/hemostat(src) new /obj/item/retractor(src) new /obj/item/circular_saw(src) + new /obj/item/bonesetter(src) new /obj/item/surgicaldrill(src) new /obj/item/cautery(src) new /obj/item/surgical_drapes(src) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 07ca092e95a..a945e2a84ec 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -158,6 +158,7 @@ /obj/item/surgical_drapes, //for true paramedics /obj/item/scalpel, /obj/item/circular_saw, + /obj/item/bonesetter, /obj/item/surgicaldrill, /obj/item/retractor, /obj/item/cautery, @@ -179,7 +180,8 @@ /obj/item/construction/plumbing, /obj/item/plunger, /obj/item/reagent_containers/spray, - /obj/item/shears + /obj/item/shears, + /obj/item/stack/sticky_tape //surgical tape )) /obj/item/storage/belt/medical/paramedic/PopulateContents() @@ -187,9 +189,9 @@ new /obj/item/pinpointer/crew/prox(src) new /obj/item/stack/medical/gauze/twelve(src) new /obj/item/reagent_containers/syringe(src) - new /obj/item/reagent_containers/glass/bottle/epinephrine(src) + new /obj/item/stack/medical/bone_gel(src) + new /obj/item/stack/sticky_tape/surgical(src) new /obj/item/reagent_containers/glass/bottle/calomel(src) - new /obj/item/reagent_containers/glass/bottle/formaldehyde(src) update_icon() /obj/item/storage/belt/security diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 1aa0607bfff..21945f9f771 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -37,6 +37,23 @@ /obj/item/reagent_containers/hypospray/medipen = 1) generate_items_inside(items_inside,src) +/obj/item/storage/firstaid/emergency + icon_state = "medbriefcase" + name = "emergency first-aid kit" + desc = "A very simple first aid kit meant to secure and stabilize serious wounds for later treatment." + +/obj/item/storage/firstaid/emergency/PopulateContents() + if(empty) + return + var/static/items_inside = list( + /obj/item/healthanalyzer/wound = 1, + /obj/item/stack/medical/gauze = 1, + /obj/item/stack/medical/suture/emergency = 1, + /obj/item/stack/medical/ointment = 1, + /obj/item/reagent_containers/hypospray/medipen/ekit = 2, + /obj/item/storage/pill_bottle/iron = 1) + generate_items_inside(items_inside,src) + /obj/item/storage/firstaid/medical name = "medical aid kit" icon_state = "firstaid_surgery" @@ -76,6 +93,7 @@ /obj/item/surgical_drapes, //for true paramedics /obj/item/scalpel, /obj/item/circular_saw, + /obj/item/bonesetter, /obj/item/surgicaldrill, /obj/item/retractor, /obj/item/cautery, @@ -102,10 +120,10 @@ if(empty) return var/static/items_inside = list( - /obj/item/stack/medical/gauze = 1, + /obj/item/stack/medical/gauze/twelve = 1, /obj/item/stack/medical/suture = 2, /obj/item/stack/medical/mesh = 2, - /obj/item/reagent_containers/hypospray/medipen = 1, + /obj/item/reagent_containers/hypospray/medipen/ekit = 1, /obj/item/surgical_drapes = 1, /obj/item/scalpel = 1, /obj/item/hemostat = 1, diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 89bdef5b96f..a21c3a2e737 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -19,6 +19,7 @@ material_flags = MATERIAL_COLOR var/latches = "single_latch" var/has_latches = TRUE + wound_bonus = 5 /obj/item/storage/toolbox/Initialize() . = ..() diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 6eeecd43ff9..060d0a7f5ec 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -582,6 +582,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' force = 10 + wound_bonus = -10 throwforce = 12 attack_verb = list("beat", "smacked") custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 3.5) @@ -620,7 +621,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 homerun_ready = 0 return else if(!target.anchored) - target.throw_at(throw_target, rand(1,2), 7, user) + var/whack_speed = (prob(60) ? 1 : 4) + target.throw_at(throw_target, rand(1, 2), whack_speed, user) // sorry friends, 7 speed batting caused wounds to absolutely delete whoever you knocked your target into (and said target) /obj/item/melee/baseball_bat/ablative name = "metal baseball bat" diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index b063a8eda34..4fbad44290e 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -8,6 +8,11 @@ var/damtype = BRUTE var/force = 0 + /// How good a given object is at causing wounds on carbons. Higher values equal better shots at creating serious wounds. + var/wound_bonus = 0 + /// If this attacks a human with no wound armor on the affected body part, add this to the wound mod. Some attacks may be significantly worse at wounding if there's even a slight layer of armor to absorb some of it vs bare flesh + var/bare_wound_bonus = 0 + var/datum/armor/armor var/obj_integrity //defaults to max_integrity var/max_integrity = 500 diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index c5d0ec3eec8..16a69905947 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -26,7 +26,7 @@ if (prob(40)) new /obj/item/storage/toolbox/emergency(src) - switch (pickweight(list("small" = 40, "aid" = 25, "tank" = 20, "both" = 10, "nothing" = 4, "delete" = 1))) + switch (pickweight(list("small" = 35, "aid" = 30, "tank" = 20, "both" = 10, "nothing" = 4, "delete" = 1))) if ("small") new /obj/item/tank/internals/emergency_oxygen(src) new /obj/item/tank/internals/emergency_oxygen(src) @@ -35,7 +35,7 @@ if ("aid") new /obj/item/tank/internals/emergency_oxygen(src) - new /obj/item/storage/firstaid/o2(src) + new /obj/item/storage/firstaid/emergency(src) new /obj/item/clothing/mask/breath(src) if ("tank") diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 9f7ccff65ee..86a20291725 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -123,7 +123,7 @@ if (QDELETED(head)) return - playsound(src, 'sound/weapons/bladeslice.ogg', 100, TRUE) + playsound(src, 'sound/weapons/guillotine.ogg', 100, TRUE) if (blade_sharpness >= GUILLOTINE_DECAP_MIN_SHARP || head.brute_dam >= 100) head.dismember() log_combat(user, H, "beheaded", src) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index faf7bace013..6344caacca9 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -67,7 +67,7 @@ to_chat(user, "You need a better grip to do that!") return if(user.grab_state >= GRAB_NECK) - tableheadsmash(user, pushed_mob) + tablelimbsmash(user, pushed_mob) else tablepush(user, pushed_mob) if(user.a_intent == INTENT_HELP) @@ -136,18 +136,22 @@ log_combat(user, pushed_mob, "tabled", null, "onto [src]") SEND_SIGNAL(pushed_mob, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table) -/obj/structure/table/proc/tableheadsmash(mob/living/user, mob/living/pushed_mob) +/obj/structure/table/proc/tablelimbsmash(mob/living/user, mob/living/pushed_mob) pushed_mob.Knockdown(30) - pushed_mob.apply_damage(30, BRUTE, BODY_ZONE_HEAD) - pushed_mob.apply_damage(40, STAMINA) + var/obj/item/bodypart/banged_limb = pushed_mob.get_bodypart(user.zone_selected) || pushed_mob.get_bodypart(BODY_ZONE_HEAD) + var/extra_wound = 0 + if(HAS_TRAIT(user, TRAIT_HULK)) + extra_wound = 20 + banged_limb.receive_damage(30, wound_bonus = extra_wound) + pushed_mob.apply_damage(60, STAMINA) take_damage(50) if(user.mind?.martial_art.smashes_tables && user.mind?.martial_art.can_use(user)) deconstruct(FALSE) - playsound(pushed_mob, "sound/effects/tableheadsmash.ogg", 90, TRUE) - pushed_mob.visible_message("[user] smashes [pushed_mob]'s head against \the [src]!", - "[user] smashes your head against \the [src]") + playsound(pushed_mob, "sound/effects/tablelimbsmash.ogg", 90, TRUE) + pushed_mob.visible_message("[user] smashes [pushed_mob]'s [banged_limb.name] against \the [src]!", + "[user] smashes your [banged_limb.name] against \the [src]") log_combat(user, pushed_mob, "head slammed", null, "against [src]") - SEND_SIGNAL(pushed_mob, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table_headsmash) + SEND_SIGNAL(pushed_mob, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table_limbsmash, banged_limb) /obj/structure/table/attackby(obj/item/I, mob/user, params) if(!(flags_1 & NODECONSTRUCT_1) && user.a_intent != INTENT_HELP) @@ -183,7 +187,7 @@ switch(user.a_intent) if(INTENT_HARM) user.unbuckle_mob(carried_mob) - tableheadsmash(user, carried_mob) + tablelimbsmash(user, carried_mob) if(INTENT_HELP) var/tableplace_delay = 3.5 SECONDS var/skills_space = "" diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 270cd5fafc4..54aa46cd098 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1066,7 +1066,10 @@ Traitors and the like can also be revived with the previous role mostly intact. ADMIN_PUNISHMENT_IMMERSE, ADMIN_PUNISHMENT_FAT, ADMIN_PUNISHMENT_FAKEBWOINK, - ADMIN_PUNISHMENT_NUGGET + ADMIN_PUNISHMENT_NUGGET, + ADMIN_PUNISHMENT_CRACK, + ADMIN_PUNISHMENT_BLEED, + ADMIN_PUNISHMENT_SCARIFY ) var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in sortList(punishment_list) @@ -1150,7 +1153,33 @@ Traitors and the like can also be revived with the previous role mostly intact. addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, C, 'sound/effects/cartoon_pop.ogg', 70), timer) addtimer(CALLBACK(C, /mob/living/.proc/spin, 4, 1), timer - 0.4 SECONDS) timer += 2 SECONDS - + if(ADMIN_PUNISHMENT_CRACK) + if(!iscarbon(target)) + to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) + return + var/mob/living/carbon/C = target + for(var/obj/item/bodypart/squish_part in C.bodyparts) + var/type_wound = pick(list(/datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/moderate)) + squish_part.force_wound_upwards(type_wound, smited=TRUE) + if(ADMIN_PUNISHMENT_BLEED) + if(!iscarbon(target)) + to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) + return + var/mob/living/carbon/C = target + for(var/obj/item/bodypart/slice_part in C.bodyparts) + var/type_wound = pick(list(/datum/wound/brute/cut/severe, /datum/wound/brute/cut/moderate)) + slice_part.force_wound_upwards(type_wound, smited=TRUE) + type_wound = pick(list(/datum/wound/brute/cut/critical, /datum/wound/brute/cut/severe, /datum/wound/brute/cut/moderate)) + slice_part.force_wound_upwards(type_wound, smited=TRUE) + type_wound = pick(list(/datum/wound/brute/cut/critical, /datum/wound/brute/cut/severe)) + slice_part.force_wound_upwards(type_wound, smited=TRUE) + if(ADMIN_PUNISHMENT_SCARIFY) + if(!iscarbon(target)) + to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) + return + var/mob/living/carbon/C = target + C.generate_fake_scars(rand(1, 4)) + to_chat(C, "You feel your body grow jaded and torn...") punish_log(target, punishment) diff --git a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm index 97b974e28fd..f97e271e72a 100644 --- a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm +++ b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm @@ -36,6 +36,6 @@ M.adjust_fire_stacks(round(reac_volume/10)) M.IgniteMob() if(M) - M.apply_damage(0.8*reac_volume, BURN) + M.apply_damage(0.8*reac_volume, BURN, wound_bonus=CANT_WOUND) if(iscarbon(M)) M.emote("scream") diff --git a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm index b019146f0bc..1665724cbb3 100644 --- a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm +++ b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm @@ -22,7 +22,7 @@ M.reagents.add_reagent(/datum/reagent/consumable/frostoil, 0.3*reac_volume) M.reagents.add_reagent(/datum/reagent/consumable/ice, 0.3*reac_volume) M.reagents.add_reagent(/datum/reagent/blob/cryogenic_poison, 0.3*reac_volume) - M.apply_damage(0.2*reac_volume, BRUTE) + M.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND) /datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(0.3*REAGENTS_EFFECT_MULTIPLIER, 0) diff --git a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm index 6bea4db0162..1275473499a 100644 --- a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm +++ b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm @@ -34,4 +34,4 @@ if(prob(reac_volume*2)) M.emp_act(EMP_LIGHT) if(M) - M.apply_damage(reac_volume, BURN) + M.apply_damage(reac_volume, BURN, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm b/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm index f8fd2e2f0df..3d005ba9138 100644 --- a/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm +++ b/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm @@ -33,8 +33,8 @@ if(ROLE_BLOB in L.faction) //no friendly fire continue var/aoe_volume = ..(L, TOUCH, initial_volume, 0, L.get_permeability_protection(), O) - L.apply_damage(0.4*aoe_volume, BRUTE) + L.apply_damage(0.4*aoe_volume, BRUTE, wound_bonus=CANT_WOUND) if(M) - M.apply_damage(0.6*reac_volume, BRUTE) + M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND) else - M.apply_damage(0.6*reac_volume, BRUTE) + M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blobstrains/networked_fibers.dm b/code/modules/antagonists/blob/blobstrains/networked_fibers.dm index 67f47a4b806..6edc0e238a4 100644 --- a/code/modules/antagonists/blob/blobstrains/networked_fibers.dm +++ b/code/modules/antagonists/blob/blobstrains/networked_fibers.dm @@ -33,6 +33,6 @@ /datum/reagent/blob/networked_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - M.apply_damage(0.6*reac_volume, BRUTE) + M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND) if(!QDELETED(M)) - M.apply_damage(0.6*reac_volume, BURN) + M.apply_damage(0.6*reac_volume, BURN, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm b/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm index e5754329979..766794e1561 100644 --- a/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm +++ b/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm @@ -44,7 +44,7 @@ T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS) M.adjust_fire_stacks(-(reac_volume / 10)) M.ExtinguishMob() - M.apply_damage(0.4*reac_volume, BRUTE) + M.apply_damage(0.4*reac_volume, BRUTE, wound_bonus=CANT_WOUND) if(M) M.apply_damage(0.4*reac_volume, OXY) if(M) diff --git a/code/modules/antagonists/blob/blobstrains/replicating_foam.dm b/code/modules/antagonists/blob/blobstrains/replicating_foam.dm index 57868963472..70c5a21154f 100644 --- a/code/modules/antagonists/blob/blobstrains/replicating_foam.dm +++ b/code/modules/antagonists/blob/blobstrains/replicating_foam.dm @@ -32,4 +32,4 @@ /datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - M.apply_damage(0.7*reac_volume, BRUTE) + M.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm b/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm index d06357f8363..5041bc231c2 100644 --- a/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm +++ b/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm @@ -33,4 +33,4 @@ /datum/reagent/blob/shifting_fragments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - M.apply_damage(0.7*reac_volume, BRUTE) + M.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm b/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm index 7f500bbe291..8b84a4973c9 100644 --- a/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm +++ b/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm @@ -31,9 +31,9 @@ /datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - M.apply_damage(0.2*reac_volume, BRUTE) + M.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND) if(M && reac_volume) for(var/obj/structure/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.6*reac_volume if(M) B.blob_attack_animation(M) //show them they're getting a bad time - M.apply_damage(0.3*reac_volume, BRUTE) + M.apply_damage(0.3*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/changeling/powers/fleshmend.dm b/code/modules/antagonists/changeling/powers/fleshmend.dm index ff33afe856c..3acc565e4bf 100644 --- a/code/modules/antagonists/changeling/powers/fleshmend.dm +++ b/code/modules/antagonists/changeling/powers/fleshmend.dm @@ -1,6 +1,6 @@ /datum/action/changeling/fleshmend name = "Fleshmend" - desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath. Costs 20 chemicals." + desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath, as well as hiding all of our scars. Costs 20 chemicals." helptext = "If we are on fire, the healing effect will not function. Does not regrow limbs or restore lost blood. Functions while unconscious." button_icon_state = "fleshmend" chemical_cost = 20 diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index 2f2d853b141..59d82af85fe 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -162,6 +162,8 @@ hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = IS_SHARP + wound_bonus = -60 + bare_wound_bonus = 20 var/can_drop = FALSE var/fake = FALSE diff --git a/code/modules/antagonists/changeling/powers/regenerate.dm b/code/modules/antagonists/changeling/powers/regenerate.dm index 7f0e9e2f4c9..d65d1181bed 100644 --- a/code/modules/antagonists/changeling/powers/regenerate.dm +++ b/code/modules/antagonists/changeling/powers/regenerate.dm @@ -34,6 +34,9 @@ B.decoy_override = TRUE B.Insert(C) C.regenerate_organs() + for(var/i in C.all_wounds) + var/datum/wound/W = i + W.remove_wound() if(ishuman(user)) var/mob/living/carbon/human/H = user H.restore_blood() diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index e3dc9b5b5db..5d36564cb2e 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -19,6 +19,8 @@ w_class = WEIGHT_CLASS_SMALL force = 15 throwforce = 25 + wound_bonus = -30 + bare_wound_bonus = 30 armour_penetration = 35 actions_types = list(/datum/action/item_action/cult_dagger) var/drawing_rune = FALSE @@ -39,8 +41,10 @@ flags_1 = CONDUCT_1 sharpness = IS_SHARP w_class = WEIGHT_CLASS_BULKY - force = 30 + force = 30 // whoever balanced this got beat in the head by a bible too many times good lord throwforce = 10 + wound_bonus = -80 + bare_wound_bonus = 30 hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended") diff --git a/code/modules/antagonists/cult/ritual.dm b/code/modules/antagonists/cult/ritual.dm index 4c65d14522f..95df4de39ac 100644 --- a/code/modules/antagonists/cult/ritual.dm +++ b/code/modules/antagonists/cult/ritual.dm @@ -120,7 +120,7 @@ This file contains the cult dagger and rune list code user.visible_message("[user] [user.blood_volume ? "cuts open [user.p_their()] arm and begins writing in [user.p_their()] own blood":"begins sketching out a strange design"]!", \ "You [user.blood_volume ? "slice open your arm and ":""]begin drawing a sigil of the Geometer.") if(user.blood_volume) - user.apply_damage(initial(rune_to_scribe.scribe_damage), BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + user.apply_damage(initial(rune_to_scribe.scribe_damage), BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM), wound_bonus = CANT_WOUND) // *cuts arm* *bone explodes* ever have one of those days? var/scribe_mod = initial(rune_to_scribe.scribe_delay) if(istype(get_turf(user), /turf/open/floor/engine/cult) && !(ispath(rune_to_scribe, /obj/effect/rune/narsie))) scribe_mod *= 0.5 diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm index af51357f3dd..13fa3793cde 100644 --- a/code/modules/antagonists/slaughter/slaughter.dm +++ b/code/modules/antagonists/slaughter/slaughter.dm @@ -34,20 +34,35 @@ healable = 0 environment_smash = ENVIRONMENT_SMASH_STRUCTURES obj_damage = 50 - melee_damage_lower = 30 - melee_damage_upper = 30 + melee_damage_lower = 15 // reduced from 30 to 15 with wounds since they get big buffs to slicing wounds + melee_damage_upper = 15 + wound_bonus = -10 + bare_wound_bonus = 0 + sharpness = TRUE see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE var/playstyle_string = "You are a slaughter demon, a terrible creature from another realm. You have a single desire: To kill. \ You may use the \"Blood Crawl\" ability near blood pools to travel through them, appearing and disappearing from the station at will. \ Pulling a dead or unconscious mob while you enter a pool will pull them in with you, allowing you to feast and regain your health. \ - You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. " + You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. \ + You gain strength the more attacks you land on live humanoids, though this resets when you return to the blood zone. You can also \ + launch a devastating slam attack with ctrl+shift+click, capable of smashing bones in one strike." loot = list(/obj/effect/decal/cleanable/blood, \ /obj/effect/decal/cleanable/blood/innards, \ /obj/item/organ/heart/demon) del_on_death = 1 deathmessage = "screams in anger as it collapses into a puddle of viscera!" + /// How long it takes for the alt-click slam attack to come off cooldown + var/slam_cooldown_time = 45 SECONDS + /// The actual instance var for the cooldown + var/slam_cooldown = 0 + /// How many times we have hit humanoid targets since we last bloodcrawled, scaling wounding power + var/current_hitstreak = 0 + /// How much both our wound_bonus and bare_wound_bonus go up per hitstreak hit + var/wound_bonus_per_hit = 5 + /// How much our wound_bonus hitstreak bonus caps at (peak demonry) + var/wound_bonus_hitstreak_max = 12 /mob/living/simple_animal/slaughter/Initialize() ..() @@ -57,6 +72,33 @@ if(istype(loc, /obj/effect/dummy/phased_mob/slaughter)) bloodspell.phased = TRUE +/mob/living/simple_animal/slaughter/CtrlShiftClickOn(atom/A) + if(!isliving(A)) + return ..() + if(slam_cooldown + slam_cooldown_time > world.time) + to_chat(src, "Your slam ability is still on cooldown!") + return + + face_atom(A) + var/mob/living/victim = A + victim.take_bodypart_damage(brute=20, wound_bonus=wound_bonus) // don't worry, there's more punishment when they hit something + visible_message("[src] slams into [victim] with monstrous strength!", "You slam into [victim] with monstrous strength!", ignored_mobs=victim) + to_chat(victim, "[src] slams into you with monstrous strength, sending you flying like a ragdoll!") + var/turf/yeet_target = get_edge_target_turf(victim, dir) + victim.throw_at(yeet_target, 10, 5, src) + slam_cooldown = world.time + log_combat(src, victim, "slaughter slammed") + +/mob/living/simple_animal/slaughter/UnarmedAttack(atom/A, proximity) + if(iscarbon(A)) + var/mob/living/carbon/target = A + if(target.stat != DEAD && target.mind && current_hitstreak < wound_bonus_hitstreak_max) + current_hitstreak++ + wound_bonus += wound_bonus_per_hit + bare_wound_bonus += wound_bonus_per_hit + + return ..() + /obj/effect/decal/cleanable/blood/innards name = "pile of viscera" desc = "A repulsive pile of guts and gore." diff --git a/code/modules/antagonists/slaughter/slaughter_antag.dm b/code/modules/antagonists/slaughter/slaughter_antag.dm index 81f1e774674..b4b33814419 100644 --- a/code/modules/antagonists/slaughter/slaughter_antag.dm +++ b/code/modules/antagonists/slaughter/slaughter_antag.dm @@ -13,6 +13,7 @@ /datum/antagonist/slaughter/greet() . = ..() owner.announce_objectives() + to_chat(owner, "You have a powerful alt-attack that slams people backwards that you can activate by shift+ctrl+clicking your target!") /datum/antagonist/slaughter/proc/forge_objectives() if(summoner) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 7772825290f..75b656880ca 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -38,6 +38,8 @@ var/escape_in_progress = FALSE var/message_cooldown var/breakout_time = 300 + ///Cryo will continue to treat people with 0 damage but existing wounds, but will sound off when damage healing is done in case doctors want to directly treat the wounds instead + var/treating_wounds = FALSE fair_market_price = 10 payment_department = ACCOUNT_MED @@ -204,15 +206,27 @@ if(mob_occupant.stat == DEAD) // We don't bother with dead people. return if(mob_occupant.health >= mob_occupant.getMaxHealth()) // Don't bother with fully healed people. - on = FALSE - update_icon() - playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. - var/msg = "Patient fully restored." - if(autoeject) // Eject if configured. - msg += " Auto ejecting patient now." - open_machine() - radio.talk_into(src, msg, radio_channel) - return + if(iscarbon(mob_occupant)) + var/mob/living/carbon/C = mob_occupant + if(C.all_wounds) + if(!treating_wounds) // if we have wounds and haven't already alerted the doctors we're only dealing with the wounds, let them know + treating_wounds = TRUE + playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. + var/msg = "Patient vitals fully recovered, continuing automated wound treatment." + radio.talk_into(src, msg, radio_channel) + else // otherwise if we were only treating wounds and now we don't have any, turn off treating_wounds so we can boot 'em out + treating_wounds = FALSE + + if(!treating_wounds) + on = FALSE + update_icon() + playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. + var/msg = "Patient fully restored." + if(autoeject) // Eject if configured. + msg += " Auto ejecting patient now." + open_machine() + radio.talk_into(src, msg, radio_channel) + return var/datum/gas_mixture/air1 = airs[1] @@ -285,6 +299,7 @@ ..() /obj/machinery/atmospherics/components/unary/cryo_cell/close_machine(mob/living/carbon/user) + treating_wounds = FALSE if((isnull(user) || istype(user)) && state_open && !panel_open) flick("pod-close-anim", src) ..(user) diff --git a/code/modules/cargo/goodies.dm b/code/modules/cargo/goodies.dm index d9c46cf5f44..567df0bc0f1 100644 --- a/code/modules/cargo/goodies.dm +++ b/code/modules/cargo/goodies.dm @@ -41,11 +41,17 @@ contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat, /obj/item/storage/belt/bandolier) /datum/supply_pack/goody/energy_single - name = "Energy Guns Single-Pack" - desc = "Contains one Energy Gun, capable of firing both nonlethal and lethal blasts of light." + name = "Energy Gun Single-Pack" + desc = "Contains one energy gun, capable of firing both nonlethal and lethal blasts of light." cost = 1000 contains = list(/obj/item/gun/energy/e_gun) +/datum/supply_pack/goody/hell_single + name = "Hellgun Single-Pack" + desc = "Contains one hellgun, an old pattern of laser gun infamous for its ability to horribly disfigure targets with burns. Technically violates the Space Geneva Convention when used on humanoids." + cost = 1500 + contains = list(/obj/item/gun/energy/laser/hellgun) + /datum/supply_pack/goody/wt550_single name = "WT-550 Auto Rifle Single-Pack" desc = "Contains one high-powered, semiautomatic rifles chambered in 4.6x30mm." // "high-powered" lol yea right diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 6600246d049..e4e8d91ea0d 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -1221,6 +1221,8 @@ /obj/item/reagent_containers/blood/OMinus, /obj/item/storage/pill_bottle/mining, /obj/item/reagent_containers/pill/neurine, + /obj/item/stack/medical/bone_gel, + /obj/item/stack/medical/bone_gel, /obj/item/vending_refill/medical) crate_name = "medical supplies crate" diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 99caba8a9ac..0c3f7daeb69 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -142,6 +142,8 @@ /// Messages currently seen by this client var/list/seen_messages var/datum/viewData/view_size + ///A lazy list of atoms we've examined in the last EXAMINE_MORE_TIME (default 1.5) seconds, so that we will call [atom/proc/examine_more()] instead of [atom/proc/examine()] on them when examining + var/list/recent_examines var/list/parallax_layers var/list/parallax_layers_cached diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index d751c21807f..eea9fd73e05 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -128,6 +128,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) /// Agendered spessmen can choose whether to have a male or female bodytype var/body_type + /// If we have persistent scars enabled + var/persistent_scars = TRUE + /// We have 5 slots for persistent scars, if enabled we pick a random one to load (empty by default) and scars at the end of the shift if we survived as our original person + var/list/scars_list = list("1" = "", "2" = "", "3" = "", "4" = "", "5" = "") + /// Which of the 5 persistent scar slots we randomly roll to load for this round, if enabled. Actually rolled in [/datum/preferences/proc/load_character(slot)] + var/scars_index = 1 + /datum/preferences/New(client/C) parent = C @@ -289,6 +296,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
Jumpsuit Style:
[jumpsuit_style]" dat += "[(randomise[RANDOM_JUMPSUIT_STYLE]) ? "Lock" : "Unlock"]" + dat += "
Backpack:
[backpack]" + dat += "[(randomise[RANDOM_BACKPACK]) ? "Lock" : "Unlock"]" + + if(CAN_SCAR in pref_species.species_traits) + dat += "
Temporal Scarring:
[(persistent_scars) ? "Enabled" : "Disabled"]" + dat += "Clear scar slots" dat += "
Uplink Spawn Location:
[uplink_spawn_loc]
" if (user.client.get_exp_living(TRUE) >= PLAYTIME_VETERAN) @@ -1699,6 +1712,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) else randomise[random_type] = TRUE + if("persistent_scars") + persistent_scars = !persistent_scars + + if("clear_scars") + to_chat(user, "All scar slots cleared. Please save character to confirm.") + scars_list["1"] = "" + scars_list["2"] = "" + scars_list["3"] = "" + scars_list["4"] = "" + scars_list["5"] = "" + if("hear_midis") toggles ^= SOUND_MIDI diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index cf13cf51068..af31ec76454 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -330,6 +330,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(newtype) pref_species = new newtype + scars_index = rand(1,5) + if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000") WRITE_FILE(S["features["mcolor"]"] , "#FFF") @@ -368,6 +370,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["feature_lizard_legs"] >> features["legs"] S["feature_moth_wings"] >> features["moth_wings"] S["feature_moth_markings"] >> features["moth_markings"] + S["persistent_scars"] >> persistent_scars + S["scars1"] >> scars_list["1"] + S["scars2"] >> scars_list["2"] + S["scars3"] >> scars_list["3"] + S["scars4"] >> scars_list["4"] + S["scars5"] >> scars_list["5"] if(!CONFIG_GET(flag/join_with_mutant_humans)) features["tail_human"] = "none" features["ears"] = "none" @@ -458,6 +466,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car features["moth_wings"] = sanitize_inlist(features["moth_wings"], GLOB.moth_wings_list, "Plain") features["moth_markings"] = sanitize_inlist(features["moth_markings"], GLOB.moth_markings_list, "None") + persistent_scars = sanitize_integer(persistent_scars) + scars_list["1"] = sanitize_text(scars_list["1"]) + scars_list["2"] = sanitize_text(scars_list["2"]) + scars_list["3"] = sanitize_text(scars_list["3"]) + scars_list["4"] = sanitize_text(scars_list["4"]) + scars_list["5"] = sanitize_text(scars_list["5"]) + joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole)) //Validate job prefs for(var/j in job_preferences) @@ -513,6 +528,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["feature_lizard_legs"] , features["legs"]) WRITE_FILE(S["feature_moth_wings"] , features["moth_wings"]) WRITE_FILE(S["feature_moth_markings"] , features["moth_markings"]) + WRITE_FILE(S["persistent_scars"] , persistent_scars) + WRITE_FILE(S["scars1"] , scars_list["1"]) + WRITE_FILE(S["scars2"] , scars_list["2"]) + WRITE_FILE(S["scars3"] , scars_list["3"]) + WRITE_FILE(S["scars4"] , scars_list["4"]) + WRITE_FILE(S["scars5"] , scars_list["5"]) //Custom names diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 5ca03470b6c..edb112dc39b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -3,7 +3,8 @@ resistance_flags = FLAMMABLE max_integrity = 200 integrity_failure = 0.4 - var/damaged_clothes = 0 //similar to machine's BROKEN stat and structure's broken var + var/damaged_clothes = CLOTHING_PRISTINE //similar to machine's BROKEN stat and structure's broken var + ///What level of bright light protection item has. var/flash_protect = FLASH_PROTECTION_NONE var/tint = 0 //Sets the item's level of visual impairment tint, normally set to the same as flash_protect @@ -24,6 +25,9 @@ var/clothing_flags = NONE + /// What items can be consumed to repair this clothing (must by an /obj/item/stack) + var/repairable_by = /obj/item/stack/sheet/cloth + //Var modification - PLEASE be careful with this I know who you are and where you live var/list/user_vars_to_edit //VARNAME = VARVALUE eg: "name" = "butts" var/list/user_vars_remembered //Auto built by the above + dropped() + equipped() @@ -42,6 +46,13 @@ ///These are armor values that protect the clothing, taken from its armor datum. List updates on examine because it's currently only used to print armor ratings to chat in Topic(). var/list/durability_list = list() + /// How much clothing damage has been dealt to each of the limbs of the clothing, assuming it covers more than one limb + var/list/damage_by_parts + /// How much integrity is in a specific limb before that limb is disabled (for use in [/obj/item/clothing/proc/take_damage_zone], and only if we cover multiple zones.) Set to 0 to disable shredding. + var/limb_integrity = 0 + /// How many zones (body parts, not precise) we have disabled so far, for naming purposes + var/zones_disabled + /obj/item/clothing/Initialize() if((clothing_flags & VOICEBOX_TOGGLABLE)) actions_types += /datum/action/item_action/toggle_voice_box @@ -79,15 +90,105 @@ return ..() /obj/item/clothing/attackby(obj/item/W, mob/user, params) - if(damaged_clothes && istype(W, /obj/item/stack/sheet/cloth)) - var/obj/item/stack/sheet/cloth/C = W - C.use(1) - update_clothes_damaged_state(FALSE) - obj_integrity = max_integrity - to_chat(user, "You fix the damage on [src] with [C].") + if(damaged_clothes && istype(W, repairable_by)) + var/obj/item/stack/S = W + switch(damaged_clothes) + if(CLOTHING_DAMAGED) + S.use(1) + repair(user, params) + if(CLOTHING_SHREDDED) + if(S.amount < 3) + to_chat(user, "You require 3 [S.name] to repair [src].") + return + to_chat(user, "You begin fixing the damage to [src] with [S]...") + if(do_after(user, 6 SECONDS, TRUE, src)) + if(S.use(3)) + repair(user, params) return 1 return ..() +/// Set the clothing's integrity back to 100%, remove all damage to bodyparts, and generally fix it up +/obj/item/clothing/proc/repair(mob/user, params) + damaged_clothes = CLOTHING_PRISTINE + update_clothes_damaged_state() + obj_integrity = max_integrity + name = initial(name) // remove "tattered" or "shredded" if there's a prefix + body_parts_covered = initial(body_parts_covered) + slot_flags = initial(slot_flags) + damage_by_parts = null + if(user) + UnregisterSignal(user, COMSIG_MOVABLE_MOVED) + to_chat(user, "You fix the damage on [src].") + +/** + * take_damage_zone() is used for dealing damage to specific bodyparts on a worn piece of clothing, meant to be called from [/obj/item/bodypart/proc/check_woundings_mods()] + * + * This proc only matters when a bodypart that this clothing is covering is harmed by a direct attack (being on fire or in space need not apply), and only if this clothing covers + * more than one bodypart to begin with. No point in tracking damage by zone for a hat, and I'm not cruel enough to let you fully break them in a few shots. + * Also if limb_integrity is 0, then this clothing doesn't have bodypart damage enabled so skip it. + * + * Arguments: + * * def_zone: The bodypart zone in question + * * damage_amount: Incoming damage + * * damage_type: BRUTE or BURN + * * armour_penetration: If the attack had armour_penetration + */ +/obj/item/clothing/proc/take_damage_zone(def_zone, damage_amount, damage_type, armour_penetration) + if(!def_zone || !limb_integrity || (initial(body_parts_covered) in GLOB.bitflags)) // the second check sees if we only cover one bodypart anyway and don't need to bother with this + return + var/list/covered_limbs = body_parts_covered2organ_names(body_parts_covered) // what do we actually cover? + if(!(def_zone in covered_limbs)) + return + + var/damage_dealt = take_damage(damage_amount * 0.1, damage_type, armour_penetration, FALSE) * 10 // only deal 10% of the damage to the general integrity damage, then multiply it by 10 so we know how much to deal to limb + LAZYINITLIST(damage_by_parts) + damage_by_parts[def_zone] += damage_dealt + if(damage_by_parts[def_zone] > limb_integrity) + disable_zone(def_zone, damage_type) + +/** + * disable_zone() is used to disable a given bodypart's protection on our clothing item, mainly from [/obj/item/clothing/proc/take_damage_zone()] + * + * This proc disables all protection on the specified bodypart for this piece of clothing: it'll be as if it doesn't cover it at all anymore (because it won't!) + * If every possible bodypart has been disabled on the clothing, we put it out of commission entirely and mark it as shredded, whereby it will have to be repaired in + * order to equip it again. Also note we only consider it damaged if there's more than one bodypart disabled. + * + * Arguments: + * * def_zone: The bodypart zone we're disabling + * * damage_type: Only really relevant for the verb for describing the breaking, and maybe obj_destruction() + */ +/obj/item/clothing/proc/disable_zone(def_zone, damage_type) + var/list/covered_limbs = body_parts_covered2organ_names(body_parts_covered) + if(!(def_zone in covered_limbs)) + return + + var/zone_name = parse_zone(def_zone) + var/break_verb = ((damage_type == BRUTE) ? "torn" : "burned") + + if(iscarbon(loc)) + var/mob/living/carbon/C = loc + C.visible_message("The [zone_name] on [C]'s [src.name] is [break_verb] away!", "The [zone_name] on your [src.name] is [break_verb] away!", vision_distance = COMBAT_MESSAGE_RANGE) + RegisterSignal(C, COMSIG_MOVABLE_MOVED, .proc/bristle) + + zones_disabled++ + for(var/i in zone2body_parts_covered(def_zone)) + body_parts_covered &= ~i + + if(body_parts_covered == NONE) // if there are no more parts to break then the whole thing is kaput + obj_destruction((damage_type == BRUTE ? "melee" : "laser")) // melee/laser is good enough since this only procs from direct attacks anyway and not from fire/bombs + return + + damaged_clothes = CLOTHING_DAMAGED + switch(zones_disabled) + if(1) + name = "damaged [initial(name)]" + if(2) + name = "mangy [initial(name)]" + if(3 to INFINITY) // take better care of your shit, dude + name = "tattered [initial(name)]" + + update_clothes_damaged_state() + /obj/item/clothing/Destroy() user_vars_remembered = null //Oh god somebody put REFERENCES in here? not to worry, we'll clean it up return ..() @@ -96,6 +197,7 @@ ..() if(!istype(user)) return + UnregisterSignal(user, COMSIG_MOVABLE_MOVED) if(LAZYLEN(user_vars_remembered)) for(var/variable in user_vars_remembered) if(variable in user.vars) @@ -108,6 +210,8 @@ if (!istype(user)) return if(slot_flags & slot) //Was equipped to a valid slot for this item? + if(iscarbon(user) && LAZYLEN(zones_disabled)) + RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/bristle) if (LAZYLEN(user_vars_to_edit)) for(var/variable in user_vars_to_edit) if(variable in user.vars) @@ -116,6 +220,10 @@ /obj/item/clothing/examine(mob/user) . = ..() + if(damaged_clothes == CLOTHING_SHREDDED) + . += "It is completely shredded and requires mending before it can be worn again!" + return + switch (max_heat_protection_temperature) if (400 to 1000) . += "[src] offers the wearer limited protection from fire." @@ -123,8 +231,18 @@ . += "[src] offers the wearer some protection from fire." if (1601 to 35000) . += "[src] offers the wearer robust protection from fire." - if(damaged_clothes) - . += "It looks damaged!" + + for(var/zone in damage_by_parts) + var/pct_damage_part = damage_by_parts[zone] / limb_integrity * 100 + var/zone_name = parse_zone(zone) + switch(pct_damage_part) + if(100 to INFINITY) + . += "The [zone_name] is useless and requires mending!" + if(60 to 99) + . += "The [zone_name] is heavily shredded!" + if(30 to 59) + . += "The [zone_name] is partially shredded." + var/datum/component/storage/pockets = GetComponent(/datum/component/storage) if(pockets) var/list/how_cool_are_your_threads = list("") @@ -225,8 +343,8 @@ return . /obj/item/clothing/obj_break(damage_flag) - if(!damaged_clothes) - update_clothes_damaged_state(TRUE) + damaged_clothes = CLOTHING_DAMAGED + update_clothes_damaged_state() if(ismob(loc)) //It's not important enough to warrant a message if nobody's wearing it var/mob/M = loc to_chat(M, "Your [name] starts to fall apart!") @@ -351,12 +469,20 @@ BLIND // can't see anything if(adjusted) if(fitted != FEMALE_UNIFORM_TOP) fitted = NO_FEMALE_UNIFORM - if(!alt_covers_chest) // for the special snowflake suits that expose the chest when adjusted + if(!alt_covers_chest) // for the special snowflake suits that expose the chest when adjusted (and also the arms, realistically) body_parts_covered &= ~CHEST + body_parts_covered &= ~ARMS else fitted = initial(fitted) if(!alt_covers_chest) body_parts_covered |= CHEST + body_parts_covered |= ARMS + if(!LAZYLEN(damage_by_parts)) + return adjusted + for(var/zone in list(BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) // ugly check to make sure we don't reenable protection on a disabled part + if(damage_by_parts[zone] > limb_integrity) + for(var/part in zone2body_parts_covered(zone)) + body_parts_covered &= part return adjusted /obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc. @@ -402,13 +528,22 @@ BLIND // can't see anything return 1 return 0 - /obj/item/clothing/obj_destruction(damage_flag) - if(damage_flag == "bomb" || damage_flag == "melee") + if(damage_flag == "bomb") var/turf/T = get_turf(src) //so the shred survives potential turf change from the explosion. addtimer(CALLBACK_NEW(/obj/effect/decal/cleanable/shreds, list(T, name)), 1) deconstruct(FALSE) + else if(!(damage_flag in list("acid", "fire"))) + damaged_clothes = CLOTHING_SHREDDED + body_parts_covered = NONE + name = "shredded [initial(name)]" + slot_flags = NONE + update_clothes_damaged_state() + if(ismob(loc)) + var/mob/M = loc + M.visible_message("[M]'s [src.name] falls off, completely shredded!", "Your [src.name] falls off, completely shredded!", vision_distance = COMBAT_MESSAGE_RANGE) + M.dropItemToGround(src) else ..() /obj/item/clothing/proc/set_sensor_glob() @@ -422,3 +557,10 @@ BLIND // can't see anything GLOB.suit_sensors_list -= H else GLOB.suit_sensors_list -= H + +/// If we're a clothing with at least 1 shredded/disabled zone, give the wearer a periodic heads up letting them know their clothes are damaged +/obj/item/clothing/proc/bristle(mob/living/L) + if(!istype(L)) + return + if(prob(0.2)) + to_chat(L, "The damaged threads on your [src.name] chafe!") diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm index 64a6c48a2f4..965fd90e4bf 100644 --- a/code/modules/clothing/gloves/_gloves.dm +++ b/code/modules/clothing/gloves/_gloves.dm @@ -32,7 +32,7 @@ if(HAS_BLOOD_DNA(src)) . += mutable_appearance('icons/effects/blood.dmi', "bloodyhands") -/obj/item/clothing/gloves/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/gloves/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm index 8f7f9985596..bcee97c23d4 100644 --- a/code/modules/clothing/head/_head.dm +++ b/code/modules/clothing/head/_head.dm @@ -69,7 +69,7 @@ if(HAS_BLOOD_DNA(src)) . += mutable_appearance('icons/effects/blood.dmi', "helmetblood") -/obj/item/clothing/head/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/head/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm index c61c5d78cf6..ace9f5aacf2 100644 --- a/code/modules/clothing/masks/_masks.dm +++ b/code/modules/clothing/masks/_masks.dm @@ -37,7 +37,7 @@ if(HAS_BLOOD_DNA(src)) . += mutable_appearance('icons/effects/blood.dmi', "maskblood") -/obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/mask/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index fdcc5b3f7cc..ee52a5599c7 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -94,7 +94,7 @@ restore_offsets(user) . = ..() -/obj/item/clothing/shoes/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/shoes/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index f8f06fecd71..2ff9479d642 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -100,7 +100,7 @@ icon_state = "hardsuit-engineering" inhand_icon_state = "eng_hardsuit" max_integrity = 300 - armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75) + armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75, "wound" = 10) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser) siemens_coefficient = 0 var/obj/item/clothing/head/helmet/space/hardsuit/helmet @@ -205,7 +205,7 @@ desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." icon_state = "hardsuit0-engineering" inhand_icon_state = "eng_helm" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75, "wound" = 10) hardsuit_type = "engineering" resistance_flags = FIRE_PROOF @@ -214,7 +214,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding." icon_state = "hardsuit-engineering" inhand_icon_state = "eng_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75, "wound" = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine resistance_flags = FIRE_PROOF @@ -225,7 +225,7 @@ icon_state = "hardsuit0-atmospherics" inhand_icon_state = "atmo_helm" hardsuit_type = "atmospherics" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75, "wound" = 10) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -234,7 +234,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding." icon_state = "hardsuit-atmospherics" inhand_icon_state = "atmo_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75, "wound" = 10) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/atmos @@ -247,7 +247,7 @@ icon_state = "hardsuit0-white" inhand_icon_state = "ce_helm" hardsuit_type = "white" - armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90) + armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90, "wound" = 10) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -256,7 +256,7 @@ name = "advanced hardsuit" desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish." inhand_icon_state = "ce_hardsuit" - armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90) + armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90, "wound" = 10) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/elite @@ -273,7 +273,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF heat_protection = HEAD - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75, "wound" = 15) brightness_on = 7 allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator) @@ -288,7 +288,7 @@ inhand_icon_state = "mining_hardsuit" max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75, "wound" = 15) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/mining heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -305,7 +305,7 @@ icon_state = "hardsuit1-syndi" inhand_icon_state = "syndie_helm" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 40, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90) + armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 40, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90, "wound" = 25) on = TRUE var/obj/item/clothing/suit/space/hardsuit/syndi/linkedsuit = null actions_types = list(/datum/action/item_action/toggle_helmet_mode) @@ -384,7 +384,7 @@ inhand_icon_state = "syndie_hardsuit" hardsuit_type = "syndi" w_class = WEIGHT_CLASS_NORMAL - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 40, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90) + armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 40, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90, "wound" = 25) allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi jetpack = /obj/item/tank/jetpack/suit @@ -397,7 +397,7 @@ alt_desc = "An elite version of the syndicate helmet, with improved armour and fireproofing. It is in combat mode. Property of Gorlex Marauders." icon_state = "hardsuit0-syndielite" hardsuit_type = "syndielite" - armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 60, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100) + armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 60, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100, "wound" = 25) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -415,7 +415,7 @@ icon_state = "hardsuit0-syndielite" hardsuit_type = "syndielite" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite - armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 60, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100) + armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 60, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100, "wound" = 25) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -454,7 +454,7 @@ inhand_icon_state = "wiz_helm" hardsuit_type = "wiz" resistance_flags = FIRE_PROOF | ACID_PROOF //No longer shall our kind be foiled by lone chemists with spray bottles! - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -465,7 +465,7 @@ inhand_icon_state = "wiz_hardsuit" w_class = WEIGHT_CLASS_NORMAL resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) allowed = list(/obj/item/teleportation_scroll, /obj/item/tank/internals) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -485,7 +485,7 @@ inhand_icon_state = "medical_helm" hardsuit_type = "medical" flash_protect = FLASH_PROTECTION_NONE - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75, "wound" = 10) clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SCAN_REAGENTS | SNUG_FIT /obj/item/clothing/suit/space/hardsuit/medical @@ -494,7 +494,7 @@ icon_state = "hardsuit-medical" inhand_icon_state = "medical_hardsuit" allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/firstaid, /obj/item/healthanalyzer, /obj/item/stack/medical) - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75, "wound" = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/medical slowdown = 0.5 @@ -506,7 +506,7 @@ hardsuit_type = "rd" resistance_flags = ACID_PROOF | FIRE_PROOF max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80, "wound" = 15) var/explosion_detection_dist = 21 clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SCAN_REAGENTS | SNUG_FIT actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_research_scanner) @@ -545,7 +545,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT //Same as an emergency firesuit. Not ideal for extended exposure. allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/gun/energy/wormhole_projector, /obj/item/hand_tele, /obj/item/aicard) - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80, "wound" = 15) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/rd cell = /obj/item/stock_parts/cell/super @@ -556,7 +556,7 @@ icon_state = "hardsuit0-sec" inhand_icon_state = "sec_helm" hardsuit_type = "sec" - armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75) + armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75, "wound" = 20) /obj/item/clothing/suit/space/hardsuit/security @@ -564,7 +564,7 @@ name = "security hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." inhand_icon_state = "sec_hardsuit" - armor = list("melee" = 35, "bullet" = 15, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75) + armor = list("melee" = 35, "bullet" = 15, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75, "wound" = 20) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security /obj/item/clothing/suit/space/hardsuit/security/Initialize() @@ -577,14 +577,14 @@ desc = "A special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor." icon_state = "hardsuit0-hos" hardsuit_type = "hos" - armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95) + armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95, "wound" = 25) /obj/item/clothing/suit/space/hardsuit/security/hos icon_state = "hardsuit-hos" name = "head of security's hardsuit" desc = "A special bulky suit that protects against hazardous, low pressure environments. Has an additional layer of armor." - armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95) + armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95, "wound" = 25) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos jetpack = /obj/item/tank/jetpack/suit cell = /obj/item/stock_parts/cell/super @@ -595,7 +595,7 @@ icon_state = "swat2helm" inhand_icon_state = "swat2helm" desc = "A tactical SWAT helmet MK.II." - armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 60, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 60, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR //we want to see the mask //this makes the hardsuit not fireproof you genius heat_protection = HEAD @@ -609,7 +609,7 @@ desc = "A MK.II SWAT suit with streamlined joints and armor made out of superior materials, insulated against intense heat if worn with the complementary gas mask. The most advanced tactical armor available." icon_state = "swat2" inhand_icon_state = "swat2" - armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 60, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 60, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) resistance_flags = FIRE_PROOF | ACID_PROOF heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT //this needed to be added a long fucking time ago @@ -723,7 +723,7 @@ icon_state = "hardsuit-hos" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos allowed = null - armor = list("melee" = 30, "bullet" = 15, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 30, "bullet" = 15, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) resistance_flags = FIRE_PROOF | ACID_PROOF var/current_charges = 3 var/max_charges = 3 //How many charges total the shielding has @@ -842,7 +842,7 @@ icon_state = "hardsuit1-syndi" inhand_icon_state = "syndie_hardsuit" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 40, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 40, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi slowdown = 0 @@ -876,7 +876,7 @@ icon_state = "hardsuit1-syndi" inhand_icon_state = "syndie_helm" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 40, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 40, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) ///SWAT version /obj/item/clothing/suit/space/hardsuit/shielded/swat @@ -888,7 +888,7 @@ max_charges = 4 current_charges = 4 recharge_delay = 15 - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 60, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 60, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/swat @@ -900,7 +900,7 @@ icon_state = "deathsquad" inhand_icon_state = "deathsquad" hardsuit_type = "syndi" - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 60, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 60, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT actions_types = list() diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 09661d5e84a..8aa0481d1ee 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -10,6 +10,7 @@ var/blood_overlay_type = "suit" var/togglename = null var/suittoggled = FALSE + limb_integrity = 0 // disabled for most exo-suits /obj/item/clothing/suit/worn_overlays(isinhands = FALSE) @@ -27,7 +28,7 @@ if(A.above_suit) . += U.accessory_overlay -/obj/item/clothing/suit/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/suit/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index c7a7b004865..78514228098 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -9,7 +9,7 @@ equip_delay_other = 40 max_integrity = 250 resistance_flags = NONE - armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 15) /obj/item/clothing/suit/armor/Initialize() . = ..() @@ -49,7 +49,7 @@ icon_state = "hos" inhand_icon_state = "greatcoat" body_parts_covered = CHEST|GROIN|ARMS|LEGS - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90) + armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90, "wound" = 20) cold_protection = CHEST|GROIN|LEGS|ARMS heat_protection = CHEST|GROIN|LEGS|ARMS strip_delay = 80 @@ -95,7 +95,7 @@ icon_state = "capcarapace" inhand_icon_state = "armor" body_parts_covered = CHEST|GROIN - armor = list("melee" = 50, "bullet" = 40, "laser" = 50, "energy" = 50, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90) + armor = list("melee" = 50, "bullet" = 40, "laser" = 50, "energy" = 50, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90, "wound" = 10) dog_fashion = null resistance_flags = FIRE_PROOF @@ -118,7 +118,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80, "wound" = 30) clothing_flags = BLOCKS_SHOVE_KNOCKDOWN strip_delay = 80 equip_delay_other = 60 @@ -129,7 +129,7 @@ icon_state = "bonearmor" inhand_icon_state = "bonearmor" blood_overlay_type = "armor" - armor = list("melee" = 35, "bullet" = 25, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list("melee" = 35, "bullet" = 25, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS /obj/item/clothing/suit/armor/bulletproof @@ -138,7 +138,7 @@ icon_state = "bulletproof" inhand_icon_state = "armor" blood_overlay_type = "armor" - armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 20) strip_delay = 70 equip_delay_other = 50 @@ -258,7 +258,7 @@ icon_state = "knight_greyscale" inhand_icon_state = "knight_greyscale" material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS//Can change color and add prefix - armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40) + armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40, "wound" = 15) /obj/item/clothing/suit/armor/vest/durathread name = "durathread vest" @@ -276,7 +276,7 @@ desc = "A bulletproof vest with forest camo. Good thing there's plenty of forests to hide in around here, right?" icon_state = "rus_armor" inhand_icon_state = "rus_armor" - armor = list("melee" = 25, "bullet" = 30, "laser" = 0, "energy" = 10, "bomb" = 10, "bio" = 0, "rad" = 20, "fire" = 20, "acid" = 50) + armor = list("melee" = 25, "bullet" = 30, "laser" = 0, "energy" = 10, "bomb" = 10, "bio" = 0, "rad" = 20, "fire" = 20, "acid" = 50, "wound" = 10) /obj/item/clothing/suit/armor/vest/russian_coat name = "russian battle coat" @@ -286,4 +286,4 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50) + armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50, "wound" = 10) diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index 69b5b54d0cc..6d8d14eb453 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -67,7 +67,7 @@ gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 body_parts_covered = CHEST|GROIN|ARMS|LEGS - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) + armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 20) allowed = list(/obj/item/teleportation_scroll) flags_inv = HIDEJUMPSUIT strip_delay = 50 diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 7b1763a31ed..a6a8ad77ce8 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -5,10 +5,11 @@ body_parts_covered = CHEST|GROIN|LEGS|ARMS permeability_coefficient = 0.9 slot_flags = ITEM_SLOT_ICLOTHING - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) equip_sound = 'sound/items/equip/jumpsuit_equip.ogg' drop_sound = 'sound/items/handling/cloth_drop.ogg' pickup_sound = 'sound/items/handling/cloth_pickup.ogg' + limb_integrity = 30 var/fitted = FEMALE_UNIFORM_FULL // For use in alternate clothing styles for women var/has_sensor = HAS_SENSORS // For the crew computer var/random_sensor = TRUE @@ -41,7 +42,7 @@ if(!attach_accessory(I, user)) return ..() -/obj/item/clothing/under/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/under/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/under/jobs/cargo.dm b/code/modules/clothing/under/jobs/cargo.dm index 3ddf8f795ab..e3cd6e53725 100644 --- a/code/modules/clothing/under/jobs/cargo.dm +++ b/code/modules/clothing/under/jobs/cargo.dm @@ -41,7 +41,7 @@ name = "shaft miner's jumpsuit" icon_state = "miner" inhand_icon_state = "miner" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 0) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 0, "wound" = 10) resistance_flags = NONE /obj/item/clothing/under/rank/cargo/miner/lavaland diff --git a/code/modules/clothing/under/jobs/command.dm b/code/modules/clothing/under/jobs/command.dm index d4a225a17ed..d21c1a66900 100644 --- a/code/modules/clothing/under/jobs/command.dm +++ b/code/modules/clothing/under/jobs/command.dm @@ -7,6 +7,7 @@ random_sensor = FALSE icon = 'icons/obj/clothing/under/captain.dmi' worn_icon = 'icons/mob/clothing/under/captain.dmi' + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 15) /obj/item/clothing/under/rank/captain/skirt name = "captain's jumpskirt" diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index 864d68c667a..e0283d62b75 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -18,7 +18,7 @@ desc = "A tactical security jumpsuit for officers complete with Nanotrasen belt buckle." icon_state = "rsecurity" inhand_icon_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) strip_delay = 50 alt_covers_chest = TRUE sensor_mode = SENSOR_COORDS @@ -66,7 +66,7 @@ desc = "A formal security suit for officers complete with Nanotrasen belt buckle." icon_state = "rwarden" inhand_icon_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) strip_delay = 50 alt_covers_chest = TRUE sensor_mode = 3 @@ -102,7 +102,7 @@ desc = "Someone who wears this means business." icon_state = "detective" inhand_icon_state = "det" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) strip_delay = 50 alt_covers_chest = TRUE sensor_mode = 3 @@ -141,7 +141,7 @@ desc = "A security jumpsuit decorated for those few with the dedication to achieve the position of Head of Security." icon_state = "rhos" inhand_icon_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) strip_delay = 60 alt_covers_chest = TRUE sensor_mode = 3 diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index 6a618ef3fe0..65b2a581dc7 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -462,6 +462,7 @@ throwforce = 15 block_chance = 55 armour_penetration = 80 + wound_bonus = -70 attack_verb = list("slapped", "slathered") w_class = WEIGHT_CLASS_BULKY tastes = list("cherry" = 1, "crepe" = 1) diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 49b8d7d6621..9d99e5cba5d 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -308,6 +308,8 @@ em {font-style: normal; font-weight: bold;} .rose {color: #ff5050;} .info {color: #6685f5;} .notice {color: #6685f5;} +.tinynotice {color: #6685f5; font-style: italic; font-size: 85%;} +.smallnotice {color: #6685f5; font-style: italic; font-size: 90%;} .boldnotice {color: #6685f5; font-weight: bold;} .hear {color: #6685f5; font-style: italic;} .adminnotice {color: #6685f5;} diff --git a/code/modules/goonchat/browserassets/css/browserOutput_white.css b/code/modules/goonchat/browserassets/css/browserOutput_white.css index 4675926985e..0bddfb761af 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput_white.css +++ b/code/modules/goonchat/browserassets/css/browserOutput_white.css @@ -306,6 +306,8 @@ h1.alert, h2.alert {color: #000000;} .rose {color: #ff5050;} .info {color: #0000CC;} .notice {color: #000099;} +.tinynotice {color: #000099; font-style: italic; font-size: 85%;} +.smallnotice {color: #000099; font-style: italic; font-size: 90%;} .boldnotice {color: #000099; font-weight: bold;} .hear {color: #000099; font-style: italic;} .adminnotice {color: #0000ff;} diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index f12c66587a3..24d0b3017fd 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -92,6 +92,7 @@ desc = "The glowing nettle incites rage in you just from looking at it!" icon_state = "deathnettle" force = 30 + wound_bonus = CANT_WOUND throwforce = 15 /obj/item/reagent_containers/food/snacks/grown/nettle/death/add_juice() diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm index dd07aa00ff6..837424887b5 100644 --- a/code/modules/jobs/job_types/chief_medical_officer.dm +++ b/code/modules/jobs/job_types/chief_medical_officer.dm @@ -41,7 +41,7 @@ shoes = /obj/item/clothing/shoes/sneakers/brown suit = /obj/item/clothing/suit/toggle/labcoat/cmo l_hand = /obj/item/storage/firstaid/medical - suit_store = /obj/item/flashlight/pen + suit_store = /obj/item/flashlight/pen/paramedic backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1) backpack = /obj/item/storage/backpack/medic @@ -57,5 +57,5 @@ mask = /obj/item/clothing/mask/breath/medical suit = /obj/item/clothing/suit/space/hardsuit/medical suit_store = /obj/item/tank/internals/oxygen - r_pocket = /obj/item/flashlight/pen + r_pocket = /obj/item/flashlight/pen/paramedic diff --git a/code/modules/jobs/job_types/paramedic.dm b/code/modules/jobs/job_types/paramedic.dm index 77f65eeff2e..57ea23f7ed5 100644 --- a/code/modules/jobs/job_types/paramedic.dm +++ b/code/modules/jobs/job_types/paramedic.dm @@ -31,7 +31,7 @@ belt = /obj/item/storage/belt/medical/paramedic id = /obj/item/card/id l_pocket = /obj/item/pda/medical - suit_store = /obj/item/flashlight/pen + suit_store = /obj/item/flashlight/pen/paramedic backpack_contents = list(/obj/item/roller=1) pda_slot = ITEM_SLOT_LPOCKET diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index d658d2fc44c..5a0681ee499 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -22,7 +22,7 @@ flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 10, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) + armor = list("melee" = 30, "bullet" = 10, "laser" = 10, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50, "wound" = 10) resistance_flags = FIRE_PROOF /obj/item/clothing/suit/hooded/explorer/Initialize() @@ -41,7 +41,7 @@ visor_flags_inv = HIDEFACIALHAIR visor_flags_cover = MASKCOVERSMOUTH actions_types = list(/datum/action/item_action/adjust) - armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40) + armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40, "wound" = 5) resistance_flags = FIRE_PROOF /obj/item/clothing/mask/gas/explorer/attack_self(mob/user) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index b8b08c9e50e..bc2ef1eb7df 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -435,12 +435,25 @@ is_antag = TRUE client.prefs.copy_to(H, antagonist = is_antag, is_latejoiner = transfer_after) + var/cur_scar_index = client.prefs.scars_index + if(client.prefs.persistent_scars && client.prefs.scars_list["[cur_scar_index]"]) + var/scar_string = client.prefs.scars_list["[cur_scar_index]"] + var/valid_scars = "" + for(var/scar_line in splittext(scar_string, ";")) + if(H.load_scar(scar_line)) + valid_scars += "[scar_line];" + + client.prefs.scars_list["[cur_scar_index]"] = valid_scars + client.prefs.save_character() + + client.prefs.copy_to(H, antagonist = is_antag) H.dna.update_dna_identity() if(mind) if(transfer_after) mind.late_joiner = TRUE mind.active = 0 //we wish to transfer the key manually mind.transfer_to(H) //won't transfer key since the mind is not active + mind.original_character = H H.name = real_name diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index e0dfd3a01e8..b64cc63c672 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -37,7 +37,6 @@ return "r" return "l" - //Check we have an organ for this hand slot (Dismemberment), Only relevant for humans /mob/proc/has_hand_for_held_index(i) return TRUE diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 88aec66d164..9aa1b1c21b7 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -4,32 +4,27 @@ BLOOD SYSTEM ****************************************************/ -/mob/living/carbon/human/proc/suppress_bloodloss(amount) - if(bleedsuppress) - return - else - bleedsuppress = TRUE - addtimer(CALLBACK(src, .proc/resume_bleeding), amount) - -/mob/living/carbon/human/proc/resume_bleeding() - bleedsuppress = 0 - if(stat != DEAD && bleed_rate) - to_chat(src, "The blood soaks through your bandage.") - - /mob/living/carbon/monkey/handle_blood() - if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood. - //Blood regeneration if there is some space - if(blood_volume < BLOOD_VOLUME_NORMAL) - blood_volume += 0.1 // regenerate blood VERY slowly - if(blood_volume < BLOOD_VOLUME_OKAY) - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) + if(bodytemperature <= TCRYO || (HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood. + return + + var/temp_bleed = 0 + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + temp_bleed += BP.get_bleed_rate() + BP.generic_bleedstacks = max(0, BP.generic_bleedstacks - 1) + bleed(temp_bleed) + + //Blood regeneration if there is some space + if(blood_volume < BLOOD_VOLUME_NORMAL) + blood_volume += 0.1 // regenerate blood VERY slowly + if(blood_volume < BLOOD_VOLUME_OKAY) + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) // Takes care blood loss and regeneration /mob/living/carbon/human/handle_blood() - if(NOBLOOD in dna.species.species_traits) - bleed_rate = 0 + if(NOBLOOD in dna.species.species_traits || bleedsuppress || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) return if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood. @@ -85,21 +80,11 @@ //Bleeding out for(var/X in bodyparts) var/obj/item/bodypart/BP = X - var/brutedamage = BP.brute_dam + temp_bleed += BP.get_bleed_rate() + BP.generic_bleedstacks = max(0, BP.generic_bleedstacks - 1) - //We want an accurate reading of .len - listclearnulls(BP.embedded_objects) - for(var/obj/item/embeddies in BP.embedded_objects) - if(!embeddies.isEmbedHarmless()) - temp_bleed += 0.5 - - if(brutedamage >= 20) - temp_bleed += (brutedamage * 0.013) - - bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases - - if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH))) - bleed(bleed_rate) + if(temp_bleed) + bleed(temp_bleed) //Makes a blood drop, leaking amt units of blood from the mob /mob/living/carbon/proc/bleed(amt) @@ -122,9 +107,11 @@ /mob/living/proc/restore_blood() blood_volume = initial(blood_volume) -/mob/living/carbon/human/restore_blood() +/mob/living/carbon/restore_blood() blood_volume = BLOOD_VOLUME_NORMAL - bleed_rate = 0 + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + BP.generic_bleedstacks = 0 /**************************************************** BLOOD TRANSFERS diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 7ac10912e7e..77f104f71c3 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -264,6 +264,8 @@ max_traumas = TRAUMA_LIMIT_BASIC if(TRAUMA_RESILIENCE_SURGERY) max_traumas = TRAUMA_LIMIT_SURGERY + if(TRAUMA_RESILIENCE_WOUND) + max_traumas = TRAUMA_LIMIT_WOUND if(TRAUMA_RESILIENCE_LOBOTOMY) max_traumas = TRAUMA_LIMIT_LOBOTOMY if(TRAUMA_RESILIENCE_MAGIC) @@ -322,7 +324,7 @@ return var/trauma_type = pick(possible_traumas) - gain_trauma(trauma_type, resilience) + return gain_trauma(trauma_type, resilience) //Cure a random trauma of a certain resilience level /obj/item/organ/brain/proc/cure_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience = TRAUMA_RESILIENCE_BASIC) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 383b6663f6d..8a6f1ff684f 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -61,28 +61,50 @@ if((S.self_operable || user != src) && (user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM)) if(S.next_step(user,user.a_intent)) return 1 + + if(!all_wounds || !(user.a_intent == INTENT_HELP || user == src)) + return ..() + + // The following priority/nonpriority searching is so that if we have two wounds on a limb that use the same item for treatment (gauze can bandage cuts AND splint broken bones), + // we prefer whichever wound is not already treated (ignore the splinted broken bone for the open cut). If there's no priority wounds that this can treat, go through the + // non-priority ones randomly. + var/list/nonpriority_wounds = list() + for(var/datum/wound/W in shuffle(all_wounds)) + if(!W.treat_priority) + nonpriority_wounds += W + else if(W.treat_priority && W.try_treating(I, user)) + return 1 + + for(var/datum/wound/W in shuffle(nonpriority_wounds)) + if(W.try_treating(I, user)) + return 1 + return ..() /mob/living/carbon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() var/hurt = TRUE + var/extra_speed = 0 + if(throwingdatum.thrower != src) + extra_speed = min(max(0, throwingdatum.speed - initial(throw_speed)), 3) + if(istype(throwingdatum, /datum/thrownthing)) hurt = !throwingdatum.gentle if(hit_atom.density && isturf(hit_atom)) if(hurt) Paralyze(20) - take_bodypart_damage(10,check_armor = TRUE) + take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed) if(iscarbon(hit_atom) && hit_atom != src) var/mob/living/carbon/victim = hit_atom if(victim.movement_type & FLYING) return if(hurt) - victim.take_bodypart_damage(10,check_armor = TRUE) - take_bodypart_damage(10,check_armor = TRUE) + victim.take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5) + take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5) victim.Paralyze(20) Paralyze(20) - visible_message("[src] crashes into [victim], knocking them both over!",\ - "You violently crash into [victim]!") + visible_message("[src] crashes into [victim] [extra_speed ? "really hard" : ""], knocking them both over!",\ + "You violently crash into [victim] [extra_speed ? "extra hard" : ""]!") playsound(src,'sound/weapons/punch1.ogg',50,TRUE) @@ -135,16 +157,22 @@ thrown_thing = I.on_thrown(src, target) if(thrown_thing) + if(isliving(thrown_thing)) var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors var/turf/end_T = get_turf(target) if(start_T && end_T) log_combat(src, thrown_thing, "thrown", addition="grab from tile in [AREACOORD(start_T)] towards tile at [AREACOORD(end_T)]") - visible_message("[src] throws [thrown_thing].", \ - "You throw [thrown_thing].") - log_message("has thrown [thrown_thing]", LOG_ATTACK) + var/power_throw = 0 + if(HAS_TRAIT(src, TRAIT_HULK)) + power_throw++ + if(pulling && grab_state >= GRAB_NECK) + power_throw++ + visible_message("[src] throws [thrown_thing][power_throw ? " really hard!" : "."]", \ + "You throw [thrown_thing][power_throw ? " really hard!" : "."]") + log_message("has thrown [thrown_thing] [power_throw ? "really hard" : ""]", LOG_ATTACK) newtonian_move(get_dir(target, src)) - thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force) + thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed + power_throw, src, null, null, null, move_force) /mob/living/carbon/restrained(ignore_grab) . = (handcuffed || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE)) @@ -819,6 +847,9 @@ var/datum/disease/D = thing if(D.severity != DISEASE_SEVERITY_POSITIVE) D.cure(FALSE) + for(var/thing in all_wounds) + var/datum/wound/W = thing + W.remove_wound() if(admin_revive) suiciding = FALSE regenerate_limbs() @@ -935,6 +966,10 @@ if(SANITY_NEUTRAL to INFINITY) . *= 0.90 + for(var/i in status_effects) + var/datum/status_effect/S = i + . *= S.interact_speed_modifier() + /mob/living/carbon/proc/create_internal_organs() for(var/X in internal_organs) var/obj/item/organ/I = X @@ -1109,3 +1144,47 @@ if(shoes && !(HIDESHOES in obscured) && shoes.washed(washer)) update_inv_shoes() + +/// if any of our bodyparts are bleeding +/mob/living/carbon/proc/is_bleeding() + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + if(BP.get_bleed_rate()) + return TRUE + +/// get our total bleedrate +/mob/living/carbon/proc/get_total_bleed_rate() + var/total_bleed_rate = 0 + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + total_bleed_rate += BP.get_bleed_rate() + + return total_bleed_rate + +/** + * generate_fake_scars()- for when you want to scar someone, but you don't want to hurt them first. These scars don't count for temporal scarring (hence, fake) + * + * If you want a specific wound scar, pass that wound type as the second arg, otherwise you can pass a list like WOUND_LIST_CUT to generate a random cut scar. + * + * Arguments: + * * num_scars- A number for how many scars you want to add + * * forced_type- Which wound or category of wounds you want to choose from, WOUND_LIST_BONE, WOUND_LIST_CUT, or WOUND_LIST_BURN (or some combination). If passed a list, picks randomly from the listed wounds. Defaults to all 3 types + */ +/mob/living/carbon/proc/generate_fake_scars(num_scars, forced_type) + for(var/i in 1 to num_scars) + var/datum/scar/S = new + var/obj/item/bodypart/BP = pick(bodyparts) + + var/wound_type + if(forced_type) + if(islist(forced_type)) + wound_type = pick(forced_type) + else + wound_type = forced_type + else + wound_type = pick(WOUND_LIST_BONE + WOUND_LIST_CUT + WOUND_LIST_BURN) + + var/datum/wound/W = new wound_type + S.generate(BP, W) + S.fake = TRUE + QDEL_NULL(W) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index a741720b9b1..ac1ecbc0357 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -80,7 +80,7 @@ SEND_SIGNAL(I, COMSIG_ITEM_ATTACK_ZONE, src, user, affecting) send_item_attack_message(I, user, affecting.name) if(I.force) - apply_damage(I.force, I.damtype, affecting) + apply_damage(I.force, I.damtype, affecting, wound_bonus = I.wound_bonus, bare_wound_bonus = I.bare_wound_bonus, sharpness = I.get_sharpness()) if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC) if(prob(33)) I.add_mob_blood(src) @@ -128,6 +128,11 @@ if(user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM) if(S.next_step(user, user.a_intent)) return 1 + + for(var/datum/wound/W in all_wounds) + if(W.try_handling(user)) + return 1 + return 0 @@ -443,6 +448,10 @@ else if(getOxyLoss() <= 50) REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) +/mob/living/carbon/proc/get_interaction_efficiency(zone) + var/obj/item/bodypart/limb = get_bodypart(zone) + if(!limb) + return /mob/living/carbon/setOxyLoss(amount, updating_health = TRUE, forced = FALSE) . = ..() diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 0eeae528bad..274abd4ac0c 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -72,3 +72,8 @@ /// Timer id of any transformation var/transformation_timer + + /// All of the wounds a carbon has afflicted throughout their limbs + var/list/all_wounds + /// All of the scars a carbon has afflicted throughout their limbs + var/list/all_scars diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index a329c0c029c..c64dd449cfc 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -1,6 +1,6 @@ -/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE) +/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone) var/hit_percent = (100-blocked)/100 if(!damage || (!forced && hit_percent <= 0)) @@ -21,13 +21,13 @@ switch(damagetype) if(BRUTE) if(BP) - if(BP.receive_damage(damage_amount, 0)) + if(BP.receive_damage(damage_amount, 0, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) update_damage_overlays() else //no bodypart, we deal damage with a more general method. adjustBruteLoss(damage_amount, forced = forced) if(BURN) if(BP) - if(BP.receive_damage(0, damage_amount)) + if(BP.receive_damage(0, damage_amount, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) update_damage_overlays() else adjustFireLoss(damage_amount, forced = forced) @@ -174,6 +174,16 @@ parts += BP return parts + +///Returns a list of bodyparts with wounds (in case someone has a wound on an otherwise fully healed limb) +/mob/living/carbon/proc/get_wounded_bodyparts(brute = FALSE, burn = FALSE, stamina = FALSE, status) + var/list/obj/item/bodypart/parts = list() + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + if(LAZYLEN(BP.wounds)) + parts += BP + return parts + /** * Heals ONE bodypart randomly selected from damaged ones. * @@ -199,12 +209,12 @@ * * It automatically updates health status */ -/mob/living/carbon/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE) +/mob/living/carbon/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) var/list/obj/item/bodypart/parts = get_damageable_bodyparts(required_status) if(!parts.len) return var/obj/item/bodypart/picked = pick(parts) - if(picked.receive_damage(brute, burn, stamina,check_armor ? run_armor_check(picked, (brute ? "melee" : burn ? "fire" : stamina ? "bullet" : null)) : FALSE)) + if(picked.receive_damage(brute, burn, stamina,check_armor ? run_armor_check(picked, (brute ? "melee" : burn ? "fire" : stamina ? "bullet" : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) update_damage_overlays() ///Heal MANY bodyparts, in random order @@ -250,7 +260,7 @@ var/stamina_was = picked.stamina_dam - update |= picked.receive_damage(brute_per_part, burn_per_part, stamina_per_part, FALSE, required_status) + update |= picked.receive_damage(brute_per_part, burn_per_part, stamina_per_part, FALSE, required_status, wound_bonus = CANT_WOUND) // disabling wounds from these for now cuz your entire body snapping cause your heart stopped would suck brute = round(brute - (picked.brute_dam - brute_was), DAMAGE_PRECISION) burn = round(burn - (picked.burn_dam - burn_was), DAMAGE_PRECISION) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index f964a0180cf..0040bed767f 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -45,6 +45,8 @@ msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!\n" else msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!\n" + for(var/datum/wound/W in BP.wounds) + msg += "[W.get_examine_description(user)]\n" for(var/X in disabled) var/obj/item/bodypart/BP = X @@ -101,6 +103,22 @@ if(pulledby && pulledby.grab_state) msg += "[t_He] [t_is] restrained by [pulledby]'s grip.\n" + var/scar_severity = 0 + for(var/i in all_scars) + var/datum/scar/S = i + if(S.is_visible(user)) + scar_severity += S.severity + + switch(scar_severity) + if(1 to 2) + msg += "[t_He] [t_has] visible scarring, you can look again to take a closer look...\n" + if(3 to 4) + msg += "[t_He] [t_has] several bad scars, you can look again to take a closer look...\n" + if(5 to 6) + msg += "[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...\n" + if(7 to INFINITY) + msg += "[t_He] [t_is] just absolutely fucked up, you can look again to take a closer look...\n" + msg += "" . += msg.Join("") @@ -133,3 +151,25 @@ . += "*---------*
" SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) + +/mob/living/carbon/examine_more(mob/user) + if(!all_scars) + return ..() + + var/list/visible_scars + for(var/i in all_scars) + var/datum/scar/S = i + if(S.is_visible(user)) + LAZYADD(visible_scars, S) + + if(!visible_scars) + return ..() + + var/msg = list("You examine [src] closer, and note the following...") + for(var/i in visible_scars) + var/datum/scar/S = i + var/scar_text = S.get_examine_description(user) + if(scar_text) + msg += "[scar_text]" + + return msg diff --git a/code/modules/mob/living/carbon/human/damage_procs.dm b/code/modules/mob/living/carbon/human/damage_procs.dm index 466747fc075..231f85097b0 100644 --- a/code/modules/mob/living/carbon/human/damage_procs.dm +++ b/code/modules/mob/living/carbon/human/damage_procs.dm @@ -1,4 +1,4 @@ /// depending on the species, it will run the corresponding apply_damage code there -/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE) - return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage) +/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) + return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage, wound_bonus, bare_wound_bonus, sharpness) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index bcde5bd579d..cadd508f013 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -151,14 +151,18 @@ else msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!\n" + for(var/datum/wound/W in BP.wounds) + msg += "[W.get_examine_description(user)]\n" + for(var/X in disabled) var/obj/item/bodypart/BP = X var/damage_text - if(!(BP.get_damage(include_stamina = FALSE) >= BP.max_damage)) //Stamina is disabling the limb - damage_text = "limp and lifeless" - else - damage_text = (BP.brute_dam >= BP.burn_dam) ? BP.heavy_brute_msg : BP.heavy_burn_msg - msg += "[capitalize(t_his)] [BP.name] is [damage_text]!\n" + if(BP.is_disabled() != BODYPART_DISABLED_WOUND) // skip if it's disabled by a wound (cuz we'll be able to see the bone sticking out!) + if(!(BP.get_damage(include_stamina = FALSE) >= BP.max_damage)) //we don't care if it's stamcritted + damage_text = "limp and lifeless" + else + damage_text = (BP.brute_dam >= BP.burn_dam) ? BP.heavy_brute_msg : BP.heavy_burn_msg + msg += "[capitalize(t_his)] [BP.name] is [damage_text]!\n" //stores missing limbs var/l_limbs_missing = 0 @@ -233,16 +237,42 @@ if(DISGUST_LEVEL_DISGUSTED to INFINITY) msg += "[t_He] look[p_s()] extremely disgusted.\n" - if(blood_volume < BLOOD_VOLUME_SAFE || skin_tone == "albino") - msg += "[t_He] [t_has] pale skin.\n" + var/apparent_blood_volume = blood_volume + if(skin_tone == "albino") + apparent_blood_volume -= 150 // enough to knock you down one tier + switch(apparent_blood_volume) + if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) + msg += "[t_He] [t_has] pale skin.\n" + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) + msg += "[t_He] look[p_s()] like pale death.\n" + if(-INFINITY to BLOOD_VOLUME_BAD) + msg += "[t_He] resemble[p_s()] a crushed, empty juice pouch.\n" if(bleedsuppress) - msg += "[t_He] [t_is] bandaged with something.\n" - else if(bleed_rate) + msg += "[t_He] [t_is] embued with a power that defies bleeding.\n" // only statues and highlander sword can cause this so whatever + else if(is_bleeding()) + var/list/obj/item/bodypart/bleeding_limbs = list() + + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + if(BP.get_bleed_rate()) + bleeding_limbs += BP + + var/num_bleeds = LAZYLEN(bleeding_limbs) + var/bleed_text = "[t_He] [t_is] bleeding from [t_his]" + switch(num_bleeds) + if(1 to 2) + bleed_text += " [bleeding_limbs[1].name][num_bleeds == 2 ? " and [bleeding_limbs[2].name]" : ""]" + if(3 to INFINITY) + for(var/i in 1 to (num_bleeds - 1)) + var/obj/item/bodypart/BP = bleeding_limbs[i] + bleed_text += " [BP.name]," + bleed_text += " and [bleeding_limbs[num_bleeds].name]" if(reagents.has_reagent(/datum/reagent/toxin/heparin, needs_metabolizing = TRUE)) - msg += "[t_He] [t_is] bleeding uncontrollably!\n" - else - msg += "[t_He] [t_is] bleeding!\n" + bleed_text += " incredibly quickly" + + bleed_text += "!\n" + msg += bleed_text if(reagents.has_reagent(/datum/reagent/teslium, needs_metabolizing = TRUE)) msg += "[t_He] [t_is] emitting a gentle blue glow!\n" @@ -311,6 +341,23 @@ else if(!client) msg += "[t_He] [t_has] a blank, absent-minded stare and appears completely unresponsive to anything. [t_He] may snap out of it soon.\n" + var/scar_severity = 0 + for(var/i in all_scars) + var/datum/scar/S = i + if(S.is_visible(user)) + scar_severity += S.severity + + switch(scar_severity) + if(1 to 2) + msg += "[t_He] [t_has] visible scarring, you can look again to take a closer look...\n" + if(3 to 4) + msg += "[t_He] [t_has] several bad scars, you can look again to take a closer look...\n" + if(5 to 6) + msg += "[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...\n" + if(7 to INFINITY) + msg += "[t_He] [t_is] just absolutely fucked up, you can look again to take a closer look...\n" + + if (length(msg)) . += "[msg.Join("")]" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 2557b6ddc2d..532e3464def 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1127,6 +1127,16 @@ return FALSE return ..() +/mob/living/carbon/human/is_bleeding() + if(NOBLOOD in dna.species.species_traits || bleedsuppress) + return FALSE + return ..() + +/mob/living/carbon/human/get_total_bleed_rate() + if(NOBLOOD in dna.species.species_traits) + return FALSE + return ..() + /mob/living/carbon/human/species var/race = null diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 6d7097dcfd2..d357848124c 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -35,6 +35,19 @@ protection += physiology.armor.getRating(d_type) return protection +///Get all the clothing on a specific body part +/mob/living/carbon/human/proc/clothingonpart(obj/item/bodypart/def_zone) + var/list/covering_part = list() + var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor) + for(var/bp in body_parts) + if(!bp) + continue + if(bp && istype(bp , /obj/item/clothing)) + var/obj/item/clothing/C = bp + if(C.body_parts_covered & def_zone.body_part) + covering_part += C + return covering_part + /mob/living/carbon/human/on_hit(obj/projectile/P) if(dna && dna.species) dna.species.on_hit(P, src) @@ -183,7 +196,7 @@ visible_message("[user] [hulk_verb]ed [src]!", \ "[user] [hulk_verb]ed [src]!", "You hear a sickening sound of flesh hitting flesh!", null, user) to_chat(user, "You [hulk_verb] [src]!") - adjustBruteLoss(15) + apply_damage(15, BRUTE, wound_bonus=10) /mob/living/carbon/human/attack_hand(mob/user) if(..()) //to allow surgery to return properly. @@ -311,14 +324,16 @@ if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration) - apply_damage(damage, M.melee_damage_type, affecting, armor) + apply_damage(damage, M.melee_damage_type, affecting, armor, wound_bonus = M.wound_bonus, bare_wound_bonus = M.bare_wound_bonus, sharpness = M.sharpness) /mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M) if(..()) //successful slime attack var/damage = rand(5, 25) + var/wound_mod = -45 // 25^1.4=90, 90-45=45 if(M.is_adult) damage = rand(10, 35) + wound_mod = -90 // 35^1.4=145, 145-90=55 if(check_shields(M, damage, "the [M.name]")) return 0 @@ -331,7 +346,7 @@ if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) var/armor_block = run_armor_check(affecting, "melee") - apply_damage(damage, BRUTE, affecting, armor_block) + apply_damage(damage, BRUTE, affecting, armor_block, wound_bonus=wound_mod) /mob/living/carbon/human/mech_melee_attack(obj/mecha/M) @@ -738,6 +753,20 @@ isdisabled += " and " to_chat(src, "\t Your [LB.name][isdisabled][self_aware ? " has " : " is "][status].") + for(var/thing in LB.wounds) + var/datum/wound/W = thing + var/msg + switch(W.severity) + if(WOUND_SEVERITY_TRIVIAL) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]." + if(WOUND_SEVERITY_MODERATE) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + if(WOUND_SEVERITY_SEVERE) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + if(WOUND_SEVERITY_CRITICAL) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!" + to_chat(src, msg) + for(var/obj/item/I in LB.embedded_objects) if(I.isEmbedHarmless()) to_chat(src, "\t There is \a [I] stuck to your [LB.name]!") @@ -747,8 +776,26 @@ for(var/t in missing) to_chat(src, "Your [parse_zone(t)] is missing!") - if(bleed_rate) - to_chat(src, "You are bleeding!") + if(is_bleeding()) + var/list/obj/item/bodypart/bleeding_limbs = list() + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + if(BP.get_bleed_rate()) + bleeding_limbs += BP + + var/num_bleeds = LAZYLEN(bleeding_limbs) + var/bleed_text = "You are bleeding from your" + switch(num_bleeds) + if(1 to 2) + bleed_text += " [bleeding_limbs[1].name][num_bleeds == 2 ? " and [bleeding_limbs[2].name]" : ""]" + if(3 to INFINITY) + for(var/i in 1 to (num_bleeds - 1)) + var/obj/item/bodypart/BP = bleeding_limbs[i] + bleed_text += " [BP.name]," + bleed_text += " and [bleeding_limbs[num_bleeds].name]" + bleed_text += "!" + to_chat(src, bleed_text) + if(getStaminaLoss()) if(getStaminaLoss() > 30) to_chat(src, "You're completely exhausted.") diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index dac12e45b2d..985c25888fe 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -48,7 +48,6 @@ var/special_voice = "" // For changing our voice. Used by a symptom. - var/bleed_rate = 0 //how much are we bleeding var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding var/name_override //For temporary visible name changes diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 12a9567bc16..c7f4738487c 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -175,3 +175,22 @@ return TRUE if(isclothing(wear_mask) && (wear_mask.clothing_flags & SCAN_REAGENTS)) return TRUE + +/// For use formatting all of the scars this human has for saving for persistent scarring +/mob/living/carbon/human/proc/format_scars() + if(!all_scars) + return + var/scars = "" + for(var/i in all_scars) + var/datum/scar/S = i + scars += "[S.format()];" + return scars + +/// Takes a single scar from the persistent scar loader and recreates it from the saved data +/mob/living/carbon/human/proc/load_scar(scar_line) + var/list/scar_data = splittext(scar_line, "|") + if(LAZYLEN(scar_data) != 4) + return // invalid, should delete + var/obj/item/bodypart/BP = get_bodypart("[scar_data[SCAR_SAVE_ZONE]]") + var/datum/scar/S = new + return S.load(BP, scar_data[SCAR_SAVE_DESC], scar_data[SCAR_SAVE_PRECISE_LOCATION], text2num(scar_data[SCAR_SAVE_SEVERITY])) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 64eb3b42fc3..ed904fa60a2 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1555,9 +1555,14 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/armor_block = H.run_armor_check(affecting, "melee", "Your armor has protected your [hit_area]!", "Your armor has softened a hit to your [hit_area]!",I.armour_penetration) armor_block = min(90,armor_block) //cap damage reduction at 90% var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) + var/Iwound_bonus = I.wound_bonus + + // this way, you can't wound with a surgical tool on help intent if they have a surgery active and are laying down, so a misclick with a circular saw on the wrong limb doesn't bleed them dry (they still get hit tho) + if((I.item_flags & SURGICAL_TOOL) && user.a_intent == INTENT_HELP && (H.mobility_flags & ~MOBILITY_STAND) && (LAZYLEN(H.surgeries) > 0)) + Iwound_bonus = CANT_WOUND var/weakness = H.check_weakness(I, user) - apply_damage(I.force * weakness, I.damtype, def_zone, armor_block, H) + apply_damage(I.force * weakness, I.damtype, def_zone, armor_block, H, wound_bonus = Iwound_bonus, bare_wound_bonus = I.bare_wound_bonus, sharpness = I.get_sharpness()) H.send_item_attack_message(I, user, hit_area) @@ -1633,8 +1638,8 @@ GLOBAL_LIST_EMPTY(roundstart_races) H.forcesay(GLOB.hit_appends) //forcesay checks stat already. return TRUE -/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE) - SEND_SIGNAL(H, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone) +/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) + SEND_SIGNAL(H, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone, wound_bonus, bare_wound_bonus, sharpness) // make sure putting wound_bonus here doesn't screw up other signals or uses for this signal var/hit_percent = (100-(blocked+armor))/100 hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100 if(!damage || (!forced && hit_percent <= 0)) @@ -1656,7 +1661,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) H.damageoverlaytemp = 20 var/damage_amount = forced ? damage : damage * hit_percent * brutemod * H.physiology.brute_mod if(BP) - if(BP.receive_damage(damage_amount, 0)) + if(BP.receive_damage(damage_amount, 0, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) H.update_damage_overlays() else//no bodypart, we deal damage with a more general method. H.adjustBruteLoss(damage_amount) @@ -1664,7 +1669,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) H.damageoverlaytemp = 20 var/damage_amount = forced ? damage : damage * hit_percent * burnmod * H.physiology.burn_mod if(BP) - if(BP.receive_damage(0, damage_amount)) + if(BP.receive_damage(0, damage_amount, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) H.update_damage_overlays() else H.adjustFireLoss(damage_amount) diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index 8f546a7d216..b91d704fcfd 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -2,7 +2,7 @@ name = "Human" id = "human" default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS) + species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,CAN_SCAR) default_features = list("mcolor" = "FFF", "wings" = "None") use_skintones = 1 skinned_type = /obj/item/stack/sheet/animalhide/human diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 9ac5c88d3ed..6cca6ff9a36 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -4,7 +4,7 @@ id = "lizard" say_mod = "hisses" default_color = "00FF00" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,CAN_SCAR) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs") mutanttongue = /obj/item/organ/tongue/lizard @@ -84,6 +84,6 @@ name = "Ash Walker" id = "ashlizard" limbs_id = "lizard" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE,CAN_SCAR) inherent_traits = list(TRAIT_CHUNKYFINGERS,TRAIT_NOBREATH) species_language_holder = /datum/language_holder/lizard/ash diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index 9b6d92d3246..70e8dff4afe 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -3,7 +3,7 @@ id = "moth" say_mod = "flutters" default_color = "00FF00" - species_traits = list(LIPS, NOEYESPRITES) + species_traits = list(LIPS, NOEYESPRITES, CAN_SCAR) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG mutant_bodyparts = list("moth_wings", "moth_markings") default_features = list("moth_wings" = "Plain", "moth_markings" = "None") diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index 63a5362042c..cbf79aecc95 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -173,6 +173,8 @@ item_flags = ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE sharpness = IS_SHARP + wound_bonus = -60 + bare_wound_bonus = 20 /obj/item/light_eater/Initialize() . = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 2fafbcbcfbe..9c98ff66547 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -46,7 +46,7 @@ /datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount) . = min(20, amount) -/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE) +/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) . = ..() if(.) regen_cooldown = world.time + REGENERATION_DELAY @@ -63,6 +63,10 @@ heal_amt *= 2 C.heal_overall_damage(heal_amt,heal_amt) C.adjustToxLoss(-heal_amt) + for(var/i in C.all_wounds) + var/datum/wound/W = i + if(prob(4-W.severity)) + W.remove_wound() if(!C.InCritical() && prob(4)) playsound(C, pick(spooks), 50, TRUE, 10) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index addc277890c..fcd11ea2aea 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -362,6 +362,12 @@ if(stat != DEAD || D.process_dead) D.stage_act() +/mob/living/carbon/handle_wounds() + for(var/thing in all_wounds) + var/datum/wound/W = thing + if(W.processes) // meh + W.handle_process() + //todo generalize this and move hud out /mob/living/carbon/proc/handle_changeling() if(mind && hud_used && hud_used.lingchemdisplay) diff --git a/code/modules/mob/living/carbon/monkey/punpun.dm b/code/modules/mob/living/carbon/monkey/punpun.dm index bfc889bc7b6..618dcd7a12e 100644 --- a/code/modules/mob/living/carbon/monkey/punpun.dm +++ b/code/modules/mob/living/carbon/monkey/punpun.dm @@ -26,6 +26,8 @@ //These have to be after the parent new to ensure that the monkey //bodyparts are actually created before we try to equip things to //those slots + if(ancestor_chain > 1) + generate_fake_scars(rand(ancestor_chain, ancestor_chain * 4)) if(relic_hat) equip_to_slot_or_del(new relic_hat, ITEM_SLOT_HEAD) if(relic_mask) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index c6720838a99..d282a0f1c5d 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -14,7 +14,7 @@ * * Returns TRUE if damage applied */ -/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE) +/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone) var/hit_percent = (100-blocked)/100 if(!damage || (!forced && hit_percent <= 0)) @@ -262,7 +262,7 @@ update_stamina() /// damage ONE external organ, organ gets randomly selected from damaged ones. -/mob/living/proc/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE) +/mob/living/proc/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) adjustBruteLoss(brute, FALSE) //zero as argument for no instant health update adjustFireLoss(burn, FALSE) adjustStaminaLoss(stamina, FALSE) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 9ab7eaa4fb7..8de7082926d 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -45,6 +45,8 @@ handle_diseases()// DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not. + handle_wounds() + if (QDELETED(src)) // diseases can qdel the mob via transformations return @@ -81,6 +83,9 @@ /mob/living/proc/handle_diseases() return +/mob/living/proc/handle_wounds() + return + /mob/living/proc/handle_random_events() return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 791b407ee0f..90c64d1cb0b 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -702,7 +702,7 @@ TH.transfer_mob_blood_dna(src) /mob/living/carbon/human/makeTrail(turf/T) - if((NOBLOOD in dna.species.species_traits) || !bleed_rate || bleedsuppress) + if((NOBLOOD in dna.species.species_traits) || !is_bleeding() || bleedsuppress) return ..() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index cd140faac95..4104f4b4c7a 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -51,7 +51,7 @@ var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration) var/on_hit_state = P.on_hit(src, armor) if(!P.nodamage && on_hit_state != BULLET_ACT_BLOCK) - apply_damage(P.damage, P.damage_type, def_zone, armor) + apply_damage(P.damage, P.damage_type, def_zone, armor, wound_bonus=P.wound_bonus, bare_wound_bonus=P.bare_wound_bonus, sharpness=P.sharpness) apply_effects(P.stun, P.knockdown, P.unconscious, P.irradiate, P.slur, P.stutter, P.eyeblur, P.drowsy, armor, P.stamina, P.jitter, P.paralyze, P.immobilize) if(P.dismemberment) check_projectile_dismemberment(P, def_zone) @@ -85,7 +85,7 @@ if(!I.throwforce) return var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration) - apply_damage(I.throwforce, dtype, zone, armor) + apply_damage(I.throwforce, dtype, zone, armor, sharpness=I.sharpness) if(I.thrownby) log_combat(I.thrownby, src, "threw and hit", I) else diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm index 53e32fc3b49..ce0910e0b31 100644 --- a/code/modules/mob/living/silicon/damage_procs.dm +++ b/code/modules/mob/living/silicon/damage_procs.dm @@ -1,5 +1,5 @@ -/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE) +/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) var/hit_percent = (100-blocked)/100 if((!damage || (!forced && hit_percent <= 0))) return 0 diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 808903d268a..79ba044b204 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -282,10 +282,12 @@ /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/circular_saw, + /obj/item/bonesetter, /obj/item/extinguisher/mini, /obj/item/roller/robo, /obj/item/borg/cyborghug/medical, /obj/item/stack/medical/gauze/cyborg, + /obj/item/stack/medical/bone_gel/cyborg, /obj/item/organ_storage, /obj/item/borg/lollipop) radio_channels = list(RADIO_CHANNEL_MEDICAL) diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 938cdf137f6..00f93474267 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -25,8 +25,11 @@ speed = 0 obj_damage = 60 - melee_damage_lower = 20 - melee_damage_upper = 30 + melee_damage_lower = 15 // i know it's like half what it used to be, but bears cause bleeding like crazy now so it works out + melee_damage_upper = 15 + wound_bonus = -5 + bare_wound_bonus = 10 // BEAR wound bonus am i right + sharpness = TRUE attack_verb_continuous = "claws" attack_verb_simple = "claw" attack_sound = 'sound/weapons/bladeslice.ogg' @@ -91,8 +94,9 @@ icon_dead = "combatbear_dead" faction = list("russian") butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1, /obj/item/bear_armor = 1) - melee_damage_lower = 25 - melee_damage_upper = 35 + melee_damage_lower = 18 + melee_damage_upper = 20 + wound_bonus = 0 armour_penetration = 20 health = 120 maxHealth = 120 @@ -117,8 +121,9 @@ A.maxHealth += 60 A.health += 60 A.armour_penetration += 20 - A.melee_damage_lower += 5 + A.melee_damage_lower += 3 A.melee_damage_upper += 5 + A.wound_bonus += 5 A.update_icons() to_chat(user, "You strap the armor plating to [A] and sharpen [A.p_their()] claws with the nail filer. This was a great idea.") qdel(src) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 514a911fa8c..7d0a40810dd 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -679,7 +679,7 @@ Difficulty: Hard to_chat(L, "You're struck by a [name]!") var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)) var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", FALSE, 50, "Your armor was penetrated by [src]!") - L.apply_damage(damage, BURN, limb_to_hit, armor) + L.apply_damage(damage, BURN, limb_to_hit, armor, wound_bonus=CANT_WOUND) if(ishostile(L)) var/mob/living/simple_animal/hostile/H = L //mobs find and damage you... if(H.stat == CONSCIOUS && !H.target && H.AIStatus != AI_OFF && !H.client) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 1d35a7f6c81..ea180d631f2 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -257,6 +257,8 @@ force = 25 damtype = BURN hitsound = 'sound/weapons/sear.ogg' + wound_bonus = -40 + bare_wound_bonus = 20 var/storm_type = /datum/weather/ash_storm var/storm_nextuse = 0 var/staff_cooldown = 20 SECONDS // The minimum time between uses. diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm index 9760ce72860..249a25757ca 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm @@ -150,7 +150,7 @@ Difficulty: Hard to_chat(L, "[src]'s ground slam shockwave sends you flying!") var/turf/thrownat = get_ranged_target_turf_direct(src, L, 8, rand(-10, 10)) L.throw_at(thrownat, 8, 2, src, TRUE, force = MOVE_FORCE_OVERPOWERING, gentle = TRUE) - L.apply_damage(20, BRUTE) + L.apply_damage(20, BRUTE, wound_bonus=CANT_WOUND) shake_camera(L, 2, 1) all_turfs -= T sleep(delay) diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 0155b62f03a..fbb97bb90cf 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -294,6 +294,9 @@ maxHealth = 25 melee_damage_lower = 15 melee_damage_upper = 15 + wound_bonus = -10 + bare_wound_bonus = 20 + sharpness = TRUE obj_damage = 0 environment_smash = ENVIRONMENT_SMASH_NONE attack_verb_continuous = "cuts" diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 4880727a2c7..41bd46f9643 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -145,6 +145,13 @@ ///What kind of footstep this mob should have. Null if it shouldn't have any. var/footstep_type + ///How much wounding power it has + var/wound_bonus = CANT_WOUND + ///How much bare wounding power it has + var/bare_wound_bonus = 0 + ///If the attacks from this are sharp + var/sharpness = FALSE + /mob/living/simple_animal/Initialize() . = ..() GLOB.simple_animals[AIStatus] += src diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index d43e0ca34e9..382c9712207 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -418,10 +418,26 @@ return face_atom(A) - var/list/result = A.examine(src) + var/list/result + if(client) + LAZYINITLIST(client.recent_examines) + if(isnull(client.recent_examines[A]) || client.recent_examines[A] < world.time) // originally this wasn't an assoc list, but sometimes the timer failed and atoms stayed in a client's recent_examines, so we check here manually + client.recent_examines[A] = world.time + EXAMINE_MORE_TIME + result = A.examine(src) + addtimer(CALLBACK(src, .proc/clear_from_recent_examines, A), EXAMINE_MORE_TIME) + else + result = A.examine_more(src) + else + result = A.examine(src) // if a tree is examined but no client is there to see it, did the tree ever really exist? + to_chat(src, result.Join("\n")) SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, A) +/mob/proc/clear_from_recent_examines(atom/A) + if(QDELETED(A) || !client) + return + LAZYREMOVE(client.recent_examines, A) + /** * Point at an atom * diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm index 3d4ec81d5bc..58d979f88bc 100644 --- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm +++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm @@ -8,6 +8,18 @@ custom_materials = list(/datum/material/iron=4000) projectile_type = /obj/projectile/bullet/shotgun_slug +/obj/item/ammo_casing/shotgun/executioner + name = "executioner slug" + desc = "A 12 gauge lead slug purpose built to annihilate flesh on impact." + icon_state = "stunshell" + projectile_type = /obj/projectile/bullet/shotgun_slug/executioner + +/obj/item/ammo_casing/shotgun/pulverizer + name = "pulverizer slug" + desc = "A 12 gauge lead slug purpose built to annihilate bones on impact." + icon_state = "stunshell" + projectile_type = /obj/projectile/bullet/shotgun_slug/pulverizer + /obj/item/ammo_casing/shotgun/beanbag name = "beanbag slug" desc = "A weak beanbag slug for riot control." diff --git a/code/modules/projectiles/ammunition/energy/laser.dm b/code/modules/projectiles/ammunition/energy/laser.dm index 05b1f05eecd..5e398a99933 100644 --- a/code/modules/projectiles/ammunition/energy/laser.dm +++ b/code/modules/projectiles/ammunition/energy/laser.dm @@ -2,6 +2,11 @@ projectile_type = /obj/projectile/beam/laser select_name = "kill" +/obj/item/ammo_casing/energy/laser/hellfire + projectile_type = /obj/projectile/beam/laser/hellfire + e_cost = 130 + select_name = "maim" + /obj/item/ammo_casing/energy/lasergun projectile_type = /obj/projectile/beam/laser e_cost = 83 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 797406b8da4..a1f58f00d6f 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -196,6 +196,11 @@ return user.AddComponent(/datum/component/gunpoint, target, src) return + if(iscarbon(target)) + var/mob/living/carbon/C = target + for(var/datum/wound/W in C.all_wounds) + if(W.try_treating(src, user)) + return // another coward cured! if(istype(user))//Check if the user can use the gun, if the user isn't alive(turrets) assume it can. var/mob/living/L = user diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index e504b54cdc7..49e7d2932de 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -29,6 +29,12 @@ ammo_type = list(/obj/item/ammo_casing/energy/lasergun/old) ammo_x_offset = 3 +/obj/item/gun/energy/laser/hellgun + name ="hellfire laser gun" + desc = "A relic of a weapon, built before NT began installing regulators on its laser weaponry. This pattern of laser gun became infamous for the gruesome burn wounds it caused, and was quietly discontinued once it began to affect NT's reputation." + icon_state = "hellgun" + ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire) + /obj/item/gun/energy/laser/captain name = "antique laser gun" icon_state = "caplaser" @@ -101,6 +107,7 @@ damage += 7 transform *= 1 + ((damage/7) * 0.2)//20% larger per tile +///X-ray gun /obj/item/gun/energy/xray name = "\improper X-ray laser gun" desc = "A high-power laser gun capable of expelling concentrated X-ray blasts that pass through multiple soft targets and heavier materials." diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index dbf4ec9357b..f9c93be9750 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -129,6 +129,11 @@ ///If TRUE, hit mobs even if they're on the floor and not our target var/hit_stunned_targets = FALSE + wound_bonus = CANT_WOUND + /// For telling whether we want to roll for bone breaking or lacerations if we're bothering with wounds + var/sharpness = FALSE + + /obj/projectile/Initialize() . = ..() permutated = list() diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 4d09118ee41..751a5d08285 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -14,11 +14,26 @@ ricochets_max = 50 //Honk! ricochet_chance = 80 reflectable = REFLECT_NORMAL + wound_bonus = -20 + bare_wound_bonus = 10 /obj/projectile/beam/laser tracer_type = /obj/effect/projectile/tracer/laser muzzle_type = /obj/effect/projectile/muzzle/laser impact_type = /obj/effect/projectile/impact/laser + wound_bonus = -30 + bare_wound_bonus = 40 + +//overclocked laser, does a bit more damage but has much higher wound power (-0 vs -20) +/obj/projectile/beam/laser/hellfire + name = "hellfire laser" + wound_bonus = 0 + damage = 25 + speed = 0.6 // higher power = faster, that's how light works right + +/obj/projectile/beam/laser/hellfire/Initialize() + . = ..() + transform *= 2 /obj/projectile/beam/laser/heavylaser name = "heavy laser" @@ -90,6 +105,7 @@ tracer_type = /obj/effect/projectile/tracer/pulse muzzle_type = /obj/effect/projectile/muzzle/pulse impact_type = /obj/effect/projectile/impact/pulse + wound_bonus = 10 /obj/projectile/beam/pulse/on_hit(atom/target, blocked = FALSE) . = ..() @@ -119,6 +135,8 @@ damage = 30 impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser light_color = LIGHT_COLOR_GREEN + wound_bonus = -40 + bare_wound_bonus = 70 /obj/projectile/beam/emitter/singularity_pull() return //don't want the emitters to miss diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 999e4c0f9bc..0534b766dad 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -6,4 +6,5 @@ nodamage = FALSE flag = "bullet" hitsound_wall = "ricochet" + sharpness = TRUE impact_effect_type = /obj/effect/temp_visual/impact_effect diff --git a/code/modules/projectiles/projectile/bullets/revolver.dm b/code/modules/projectiles/projectile/bullets/revolver.dm index 21555c8554a..7a399287a56 100644 --- a/code/modules/projectiles/projectile/bullets/revolver.dm +++ b/code/modules/projectiles/projectile/bullets/revolver.dm @@ -19,6 +19,8 @@ ricochet_chance = 50 ricochet_auto_aim_angle = 10 ricochet_auto_aim_range = 3 + wound_bonus = -35 + sharpness = TRUE /obj/projectile/bullet/c38/match name = ".38 Match bullet" @@ -46,6 +48,7 @@ damage = 15 armour_penetration = -30 ricochets_max = 0 + wound_bonus = 0 shrapnel_type = /obj/item/shrapnel/bullet/c38/dumdum /obj/projectile/bullet/c38/trac diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm index 551e4ebc4f1..a6d42d11684 100644 --- a/code/modules/projectiles/projectile/bullets/shotgun.dm +++ b/code/modules/projectiles/projectile/bullets/shotgun.dm @@ -2,10 +2,22 @@ name = "12g shotgun slug" damage = 60 +/obj/projectile/bullet/shotgun_slug/executioner + name = "executioner slug" // admin only, can dismember limbs + sharpness = TRUE + wound_bonus = 0 + +/obj/projectile/bullet/shotgun_slug/pulverizer + name = "pulverizer slug" // admin only, can crush bones + sharpness = FALSE + wound_bonus = 0 + /obj/projectile/bullet/shotgun_beanbag name = "beanbag slug" - damage = 5 + damage = 10 stamina = 55 + wound_bonus = 20 + sharpness = FALSE /obj/projectile/bullet/incendiary/shotgun name = "incendiary slug" @@ -62,6 +74,7 @@ /obj/projectile/bullet/pellet/shotgun_buckshot name = "buckshot pellet" damage = 12.5 + wound_bonus = -10 /obj/projectile/bullet/pellet/shotgun_rubbershot name = "rubbershot pellet" diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index 0e98971bd4b..a30b3887004 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -420,6 +420,8 @@ if(method in list(PATCH, TOUCH, VAPOR)) var/harmies = min(carbies.getBruteLoss(),carbies.adjustBruteLoss(-1.25 * reac_volume)*-1) var/burnies = min(carbies.getFireLoss(),carbies.adjustFireLoss(-1.25 * reac_volume)*-1) + for(var/datum/wound/burn/burn_wound in carbies.all_wounds) + burn_wound.regenerate_flesh(reac_volume) carbies.adjustToxLoss((harmies+burnies)*0.66) if(show_message) to_chat(carbies, "You feel your burns and bruises healing! It stings like hell!") diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 7ebbb965811..00c41700ef4 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -148,6 +148,9 @@ M.adjustFireLoss(-power, 0) M.adjustToxLoss(-power, 0, TRUE) //heals TOXINLOVERs M.adjustCloneLoss(-power, 0) + for(var/i in M.all_wounds) + var/datum/wound/W = i + W.on_xadone(power) REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration . = 1 metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5) @@ -198,6 +201,9 @@ M.adjustFireLoss(-1.5 * power, 0) M.adjustToxLoss(-power, 0, TRUE) M.adjustCloneLoss(-power, 0) + for(var/i in M.all_wounds) + var/datum/wound/W = i + W.on_xadone(power) REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) . = 1 ..() @@ -234,7 +240,7 @@ /datum/reagent/medicine/spaceacillin name = "Spaceacillin" - description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with." + description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with. Also reduces infection in serious burns." color = "#E1F2E6" metabolization_rate = 0.1 * REAGENTS_METABOLISM @@ -305,7 +311,7 @@ /datum/reagent/medicine/mine_salve name = "Miner's Salve" - description = "A powerful painkiller. Restores bruising and burns in addition to making the patient believe they are fully healed." + description = "A powerful painkiller. Restores bruising and burns in addition to making the patient believe they are fully healed. Also great for treating severe burn wounds in a pinch." reagent_state = LIQUID color = "#6D6374" metabolization_rate = 0.4 * REAGENTS_METABOLISM @@ -330,7 +336,7 @@ S.speed_modifier = max(0.1, S.speed_modifier) if(show_message) - to_chat(M, "You feel your wounds fade away to nothing!" ) + to_chat(M, "You feel your injuries fade away to nothing!" ) ..() /datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M) @@ -1262,10 +1268,6 @@ /datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all. M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25) M.adjustBruteLoss(-0.35, 0) - if(prob(50)) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.bleed_rate = max(H.bleed_rate - 1, 0) ..() . = 1 @@ -1334,3 +1336,11 @@ L.remove_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown) L.Dizzy(0) L.Jitter(0) + +// handled in cut wounds process +/datum/reagent/medicine/coagulant + name = "Sanguirite" + description = "A coagulant used to help open cuts clot faster." + reagent_state = LIQUID + color = "#bb2424" + metabolization_rate = 0.25 * REAGENTS_METABOLISM diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index a6ec977db92..1f2dc2b62b9 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2285,3 +2285,36 @@ color = "#623301" taste_mult = 1.2 +/datum/reagent/determination + name = "Determination" + description = "For when you need to push on a little more. Do NOT allow near plants." + reagent_state = LIQUID + color = "#D2FFFA" + metabolization_rate = 0.75 * REAGENTS_METABOLISM // 5u (WOUND_DETERMINATION_CRITICAL) will last for ~17 ticks + /// Whether we've had at least WOUND_DETERMINATION_SEVERE (2.5u) of determination at any given time. No damage slowdown immunity or indication we're having a second wind if it's just a single moderate wound + var/significant = FALSE + +/datum/reagent/determination/on_mob_end_metabolize(mob/living/carbon/M) + if(significant) + var/stam_crash = 0 + for(var/thing in M.all_wounds) + var/datum/wound/W = thing + stam_crash += (W.severity + 1) * 3 // spike of 3 stam damage per wound severity (moderate = 6, severe = 9, critical = 12) when the determination wears off if it was a combat rush + M.adjustStaminaLoss(stam_crash) + M.remove_status_effect(STATUS_EFFECT_DETERMINED) + ..() + +/datum/reagent/determination/on_mob_life(mob/living/carbon/M) + if(!significant && volume >= WOUND_DETERMINATION_SEVERE) + significant = TRUE + M.apply_status_effect(STATUS_EFFECT_DETERMINED) // in addition to the slight healing, limping cooldowns are divided by 4 during the combat high + + volume = min(volume, WOUND_DETERMINATION_MAX) + + for(var/thing in M.all_wounds) + var/datum/wound/W = thing + var/obj/item/bodypart/wounded_part = W.limb + if(wounded_part) + wounded_part.heal_damage(0.25, 0.25) + M.adjustStaminaLoss(-0.25*REM) // the more wounds, the more stamina regen + ..() diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index fcd9331ff05..518cfc550e5 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -166,6 +166,11 @@ toxpwr = 2 taste_description = "fish" +/datum/reagent/toxin/carpotoxin/on_mob_life(mob/living/carbon/M) + . = ..() + for(var/i in M.all_scars) + qdel(i) + /datum/reagent/toxin/zombiepowder name = "Zombie Powder" description = "A strong neurotoxin that puts the subject into a death-like state." @@ -749,22 +754,13 @@ /datum/reagent/toxin/heparin //Based on a real-life anticoagulant. I'm not a doctor, so this won't be realistic. name = "Heparin" - description = "A powerful anticoagulant. Victims will bleed uncontrollably and suffer scaling bruising." + description = "A powerful anticoagulant. All open cut wounds on the victim will open up and bleed much faster" silent_toxin = TRUE reagent_state = LIQUID color = "#C8C8C8" //RGB: 200, 200, 200 metabolization_rate = 0.2 * REAGENTS_METABOLISM toxpwr = 0 -/datum/reagent/toxin/heparin/on_mob_life(mob/living/carbon/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.bleed_rate = min(H.bleed_rate + 2, 8) - H.adjustBruteLoss(1, 0) //Brute damage increases with the amount they're bleeding - . = 1 - return ..() || . - - /datum/reagent/toxin/rotatium //Rotatium. Fucks up your rotation and is hilarious name = "Rotatium" description = "A constantly swirling, oddly colourful fluid. Causes the consumer's sense of direction and hand-eye coordination to become wild." diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 436118265a4..61353a40c63 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -102,12 +102,12 @@ inhand_icon_state = "medipen" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - amount_per_transfer_from_this = 13 - volume = 13 + amount_per_transfer_from_this = 15 + volume = 15 ignore_flags = 1 //so you can medipen through hardsuits reagent_flags = DRAWABLE flags_1 = null - list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/toxin/formaldehyde = 3) + list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/toxin/formaldehyde = 3, /datum/reagent/medicine/coagulant = 2) custom_price = 150 custom_premium_price = 300 @@ -253,3 +253,10 @@ amount_per_transfer_from_this = 15 list_reagents = list(/datum/reagent/drug/pumpup = 15) icon_state = "maintenance" + +/obj/item/reagent_containers/hypospray/medipen/ekit + name = "emergency first-aid autoinjector" + desc = "An epinephrine medipen with trace amounts of coagulants and antibiotics to help stabilize bad cuts and burns." + volume = 15 + amount_per_transfer_from_this = 15 + list_reagents = list(/datum/reagent/medicine/epinephrine = 12, /datum/reagent/medicine/coagulant = 2.5, /datum/reagent/medicine/spaceacillin = 0.5) diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index d1b11fbac57..347334a1655 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -504,6 +504,15 @@ category = list("initial", "Medical", "Tool Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE +/datum/design/bonesetter + name = "Bonesetter" + id = "bonesetter" + build_type = AUTOLATHE | PROTOLATHE + materials = list(/datum/material/iron = 1000) + build_path = /obj/item/bonesetter + category = list("initial", "Medical", "Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + /datum/design/surgicaldrill name = "Surgical Drill" id = "surgicaldrill" @@ -1130,3 +1139,12 @@ materials = list(/datum/material/plastic = 500) build_path = /obj/item/stack/sticky_tape category = list("initial", "Misc") + +/datum/design/sticky_tape/surgical + name = "Surgical Tape" + id = "surgical_tape" + build_type = PROTOLATHE + materials = list(/datum/material/plastic = 500) + build_path = /obj/item/stack/sticky_tape/surgical + category = list("initial", "Medical") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 22924de15b8..606fbc7eb35 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -56,8 +56,8 @@ starting_node = TRUE display_name = "Basic Medical Equipment" description = "Basic medical tools and equipment." - design_ids = list("cybernetic_liver", "cybernetic_heart", "cybernetic_lungs", "scalpel", "circular_saw", "surgicaldrill", "retractor", "cautery", "hemostat", - "surgical_drapes", "syringe", "plumbing_rcd", "beaker", "large_beaker", "xlarge_beaker", "dropper", "defibmountdefault") + design_ids = list("cybernetic_liver", "cybernetic_heart", "cybernetic_lungs", "scalpel", "circular_saw", "bonesetter", "surgicaldrill", "retractor", "cautery", "hemostat", + "surgical_drapes", "syringe", "plumbing_rcd", "beaker", "large_beaker", "xlarge_beaker", "dropper", "defibmountdefault", "surgical_tape") /////////////////////////Biotech///////////////////////// /datum/techweb_node/biotech diff --git a/code/modules/research/xenobiology/crossbreeding/_misc.dm b/code/modules/research/xenobiology/crossbreeding/_misc.dm index 454531d8bc0..d038e75e218 100644 --- a/code/modules/research/xenobiology/crossbreeding/_misc.dm +++ b/code/modules/research/xenobiology/crossbreeding/_misc.dm @@ -38,7 +38,7 @@ Slimecrossing Items if(!already || already != saved_part.old_part) saved_part.old_part.replace_limb(src, TRUE) saved_part.old_part.heal_damage(INFINITY, INFINITY, INFINITY, null, FALSE) - saved_part.old_part.receive_damage(saved_part.brute_dam, saved_part.burn_dam, saved_part.stamina_dam) + saved_part.old_part.receive_damage(saved_part.brute_dam, saved_part.burn_dam, saved_part.stamina_dam, wound_bonus=CANT_WOUND) dont_chop[zone] = TRUE for(var/_part in bodyparts) var/obj/item/bodypart/part = _part diff --git a/code/modules/spells/spell_types/bloodcrawl.dm b/code/modules/spells/spell_types/bloodcrawl.dm index 55524788b79..0ac5f5dc58e 100644 --- a/code/modules/spells/spell_types/bloodcrawl.dm +++ b/code/modules/spells/spell_types/bloodcrawl.dm @@ -24,6 +24,11 @@ /obj/effect/proc_holder/spell/bloodcrawl/perform(obj/effect/decal/cleanable/target, recharge = 1, mob/living/user = usr) if(istype(user)) + if(istype(user, /mob/living/simple_animal/slaughter)) + var/mob/living/simple_animal/slaughter/slaught = user + slaught.current_hitstreak = 0 + slaught.wound_bonus = initial(slaught.wound_bonus) + slaught.bare_wound_bonus = initial(slaught.bare_wound_bonus) if(phased) if(user.phasein(target)) phased = FALSE diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm index 90055ec9482..658e78353e8 100644 --- a/code/modules/spells/spell_types/shapeshift.dm +++ b/code/modules/spells/spell_types/shapeshift.dm @@ -130,7 +130,7 @@ var/damage_percent = (stored.maxHealth - stored.health)/stored.maxHealth; var/damapply = damage_percent * shape.maxHealth; - shape.apply_damage(damapply, source.convert_damage_type, forced = TRUE); + shape.apply_damage(damapply, source.convert_damage_type, forced = TRUE, wound_bonus=CANT_WOUND); shape.blood_volume = stored.blood_volume; slink = soullink(/datum/soullink/shapeshift, stored , shape) @@ -186,7 +186,7 @@ var/damage_percent = (shape.maxHealth - shape.health)/shape.maxHealth; var/damapply = stored.maxHealth * damage_percent - stored.apply_damage(damapply, source.convert_damage_type, forced = TRUE) + stored.apply_damage(damapply, source.convert_damage_type, forced = TRUE, wound_bonus=CANT_WOUND) if(source.convert_damage) stored.blood_volume = shape.blood_volume; qdel(shape) diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm similarity index 63% rename from code/modules/surgery/bodyparts/bodyparts.dm rename to code/modules/surgery/bodyparts/_bodyparts.dm index 3bdf608c031..19eb27f5d53 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -66,6 +66,29 @@ var/medium_burn_msg = "blistered" var/heavy_burn_msg = "peeling away" + /// The wounds currently afflicting this body part + var/list/wounds + + /// The scars currently afflicting this body part + var/list/scars + /// Our current stored wound damage multiplier + var/wound_damage_multiplier = 1 + + /// This number is subtracted from all wound rolls on this bodypart, higher numbers mean more defense, negative means easier to wound + var/wound_resistance = 0 + /// When this bodypart hits max damage, this number is added to all wound rolls. Obviously only relevant for bodyparts that have damage caps. + var/disabled_wound_penalty = 15 + + /// A hat won't cover your face, but a shirt covering your chest will cover your... you know, chest + var/scars_covered_by_clothes = TRUE + /// Descriptions for the locations on the limb for scars to be assigned, just cosmetic + var/list/specific_locations = list("general area") + /// So we know if we need to scream if this limb hits max damage + var/last_maxed + /// How much generic bleedstacks we have on this bodypart + var/generic_bleedstacks + + /obj/item/bodypart/examine(mob/user) . = ..() if(brute_dam > DAMAGE_PRECISION) @@ -146,7 +169,7 @@ //Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all. //Damage will not exceed max_damage using this proc //Cannot apply negative damage -/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, blocked = 0, updating_health = TRUE, required_status = null) +/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, blocked = 0, updating_health = TRUE, required_status = null, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) // maybe separate BRUTE_SHARP and BRUTE_OTHER eventually somehow hmm var/hit_percent = (100-blocked)/100 if((!brute && !burn && !stamina) || hit_percent <= 0) return FALSE @@ -167,27 +190,42 @@ if(!brute && !burn && !stamina) return FALSE + brute *= wound_damage_multiplier + burn *= wound_damage_multiplier + switch(animal_origin) if(ALIEN_BODYPART,LARVA_BODYPART) //aliens take double burn //nothing can burn with so much snowflake code around burn *= 2 + var/wounding_type = (brute > burn ? WOUND_BRUTE : WOUND_BURN) + var/wounding_dmg = max(brute, burn) + if(wounding_type == WOUND_BRUTE && sharpness) + wounding_type = WOUND_SHARP + // i know this is effectively the same check as above but i don't know if those can null the damage by rounding and want to be safe + if(owner && wounding_dmg > 4 && wound_bonus != CANT_WOUND) + // if you want to make tox wounds or some other type, this will need to be expanded and made more modular + // handle all our wounding stuff + check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus) + var/can_inflict = max_damage - get_damage() - if(can_inflict <= 0) - return FALSE - var/total_damage = brute + burn - - if(total_damage > can_inflict) + if(total_damage > can_inflict && total_damage > 0) // TODO: the second part of this check should be removed once disabling is all done brute = round(brute * (can_inflict / total_damage),DAMAGE_PRECISION) burn = round(burn * (can_inflict / total_damage),DAMAGE_PRECISION) + if(can_inflict <= 0) + return FALSE + brute_dam += brute burn_dam += burn + for(var/i in wounds) + var/datum/wound/W = i + W.receive_damage(wounding_type, wounding_dmg, wound_bonus) + //We've dealt the physical damages, if there's room lets apply the stamina damage. stamina_dam += round(clamp(stamina, 0, max_stamina_damage - stamina_dam), DAMAGE_PRECISION) - if(owner && updating_health) owner.updatehealth() if(stamina > DAMAGE_PRECISION) @@ -198,6 +236,107 @@ update_disabled() return update_bodypart_damage_state() || . +/** + * check_wounding() is where we handle rolling for, selecting, and applying a wound if we meet the criteria + * + * We generate a "score" for how woundable the attack was based on the damage and other factors discussed in [check_wounding_mods()], then go down the list from most severe to least severe wounds in that category. + * We can promote a wound from a lesser to a higher severity this way, but we give up if we have a wound of the given type and fail to roll a higher severity, so no sidegrades/downgrades + * + * Arguments: + * * woundtype- Either WOUND_SHARP, WOUND_BRUTE, or WOUND_BURN based on the attack type. + * * damage- How much damage is tied to this attack, since wounding potential scales with damage in an attack (see: WOUND_DAMAGE_EXPONENT) + * * wound_bonus- The wound_bonus of an attack + * * bare_wound_bonus- The bare_wound_bonus of an attack + */ +/obj/item/bodypart/proc/check_wounding(woundtype, damage, wound_bonus, bare_wound_bonus) + // actually roll wounds if applicable + if(HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE)) + damage *= 1.5 + + var/base_roll = rand(1, round(damage ** WOUND_DAMAGE_EXPONENT)) + var/injury_roll = base_roll + injury_roll += check_woundings_mods(woundtype, damage, wound_bonus, bare_wound_bonus) + var/list/wounds_checking + + switch(woundtype) + if(WOUND_SHARP) + wounds_checking = WOUND_LIST_CUT + if(WOUND_BRUTE) + wounds_checking = WOUND_LIST_BONE + if(WOUND_BURN) + wounds_checking = WOUND_LIST_BURN + + //cycle through the wounds of the relevant category from the most severe down + for(var/PW in wounds_checking) + var/datum/wound/possible_wound = PW + var/datum/wound/replaced_wound + for(var/i in wounds) + var/datum/wound/existing_wound = i + if(existing_wound.type in wounds_checking) + if(existing_wound.severity >= initial(possible_wound.severity)) + return + else + replaced_wound = existing_wound + + if(initial(possible_wound.threshold_minimum) < injury_roll) + if(replaced_wound) + var/datum/wound/new_wound = replaced_wound.replace_wound(possible_wound) + log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll) + else + var/datum/wound/new_wound = new possible_wound + new_wound.apply_wound(src) + log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll) + return + +// try forcing a specific wound, but only if there isn't already a wound of that severity or greater for that type on this bodypart +/obj/item/bodypart/proc/force_wound_upwards(specific_woundtype, smited = FALSE) + var/datum/wound/potential_wound = specific_woundtype + for(var/i in wounds) + var/datum/wound/existing_wound = i + if(existing_wound.type in (initial(potential_wound.wound_type))) + if(existing_wound.severity < initial(potential_wound.severity)) // we only try if the existing one is inferior to the one we're trying to force + existing_wound.replace_wound(potential_wound, smited) + return + + var/datum/wound/new_wound = new potential_wound + new_wound.apply_wound(src, smited = smited) + +/obj/item/bodypart/proc/check_woundings_mods(wounding_type, damage, wound_bonus, bare_wound_bonus) + var/armor_ablation = 0 + var/injury_mod = 0 + + //var/bwb = 0 + + if(owner && ishuman(owner)) + var/mob/living/carbon/human/H = owner + var/list/clothing = H.clothingonpart(src) + for(var/c in clothing) + var/obj/item/clothing/C = c + // unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary + armor_ablation += C.armor.getRating("wound") + if(wounding_type == WOUND_SHARP) + C.take_damage_zone(body_zone, damage, BRUTE, armour_penetration) + else if(wounding_type == WOUND_BURN && damage >= 10) // lazy way to block freezing from shredding clothes without adding another var onto apply_damage() + C.take_damage_zone(body_zone, damage, BURN, armour_penetration) + + if(!armor_ablation) + injury_mod += bare_wound_bonus + + injury_mod -= armor_ablation + injury_mod += wound_bonus + + for(var/thing in wounds) + var/datum/wound/W = thing + injury_mod += W.threshold_penalty + + var/part_mod = -wound_resistance + if(is_disabled()) + part_mod += disabled_wound_penalty + + injury_mod += part_mod + + return injury_mod + //Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all. //Damage cannot go below zero. //Cannot remove negative damage (i.e. apply damage) @@ -225,24 +364,42 @@ //Checks disabled status thresholds /obj/item/bodypart/proc/update_disabled() + if(!owner) + return set_disabled(is_disabled()) /obj/item/bodypart/proc/is_disabled() + if(!owner) + return if(HAS_TRAIT(src, TRAIT_PARALYSIS)) return BODYPART_DISABLED_PARALYSIS + for(var/i in wounds) + var/datum/wound/W = i + if(W.disabling) + return BODYPART_DISABLED_WOUND if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NOLIMBDISABLE)) . = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled + + // TODO: figure if i'm keeping disabling to broken bones only if((get_damage(TRUE) >= max_damage) || (HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE) && (get_damage(TRUE) >= (max_damage * 0.6)))) //Easy limb disable disables the limb at 40% health instead of 0% - return BODYPART_DISABLED_DAMAGE - if(disabled && (get_damage(TRUE) <= (max_damage * 0.5))) + if(!last_maxed) + owner.emote("scream") + last_maxed = TRUE + if(!is_organic_limb()) + return BODYPART_DISABLED_DAMAGE + else if(disabled && (get_damage(TRUE) <= (max_damage * 0.8))) // reenabled at 80% now instead of 50% as of wounds update + last_maxed = FALSE return BODYPART_NOT_DISABLED else return BODYPART_NOT_DISABLED + return BODYPART_NOT_DISABLED /obj/item/bodypart/proc/set_disabled(new_disabled) - if(disabled == new_disabled) + if(disabled == new_disabled || !owner) return disabled = new_disabled + if(disabled && owner.get_item_for_held_index(held_index)) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) owner.update_health_hud() //update the healthdoll owner.update_body() owner.update_mobility() @@ -439,298 +596,46 @@ drop_organs() qdel(src) -/obj/item/bodypart/chest - name = BODY_ZONE_CHEST - desc = "It's impolite to stare at a person's chest." - icon_state = "default_human_chest" - max_damage = 200 - body_zone = BODY_ZONE_CHEST - body_part = CHEST - px_x = 0 - px_y = 0 - stam_damage_coeff = 1 - max_stamina_damage = 120 - var/obj/item/cavity_item - -/obj/item/bodypart/chest/can_dismember(obj/item/I) - if(!((owner.stat == DEAD) || owner.InFullCritical())) - return FALSE - return ..() - -/obj/item/bodypart/chest/Destroy() - QDEL_NULL(cavity_item) - return ..() - -/obj/item/bodypart/chest/drop_organs(mob/user, violent_removal) - if(cavity_item) - cavity_item.forceMove(drop_location()) - cavity_item = null - ..() - -/obj/item/bodypart/chest/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_chest" - animal_origin = MONKEY_BODYPART - -/obj/item/bodypart/chest/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_chest" - dismemberable = 0 - max_damage = 500 - animal_origin = ALIEN_BODYPART - -/obj/item/bodypart/chest/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART - -/obj/item/bodypart/chest/larva - icon = 'icons/mob/animal_parts.dmi' - icon_state = "larva_chest" - dismemberable = 0 - max_damage = 50 - animal_origin = LARVA_BODYPART - -/obj/item/bodypart/l_arm - name = "left arm" - desc = "Did you know that the word 'sinister' stems originally from the \ - Latin 'sinestra' (left hand), because the left hand was supposed to \ - be possessed by the devil? This arm appears to be possessed by no \ - one though." - icon_state = "default_human_l_arm" - attack_verb = list("slapped", "punched") - max_damage = 50 - max_stamina_damage = 50 - body_zone = BODY_ZONE_L_ARM - body_part = ARM_LEFT - aux_zone = BODY_ZONE_PRECISE_L_HAND - aux_layer = HANDS_PART_LAYER - body_damage_coeff = 0.75 - held_index = 1 - px_x = -6 - px_y = 0 - -/obj/item/bodypart/l_arm/is_disabled() - if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM)) - return BODYPART_DISABLED_PARALYSIS - return ..() - -/obj/item/bodypart/l_arm/set_disabled(new_disabled) - . = ..() - if(!.) +/// Get whatever wound of the given type is currently attached to this limb, if any +/obj/item/bodypart/proc/get_wound_type(checking_type) + if(isnull(wounds)) return - if(disabled == BODYPART_DISABLED_DAMAGE) - if(owner.stat < UNCONSCIOUS) - owner.emote("scream") - if(owner.stat < DEAD) - to_chat(owner, "Your [name] is too damaged to function!") - if(held_index) - owner.dropItemToGround(owner.get_item_for_held_index(held_index)) - else if(disabled == BODYPART_DISABLED_PARALYSIS) - if(owner.stat < DEAD) - to_chat(owner, "You can't feel your [name]!") - if(held_index) - owner.dropItemToGround(owner.get_item_for_held_index(held_index)) - if(owner.hud_used) - var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"] - if(L) - L.update_icon() -/obj/item/bodypart/l_arm/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_l_arm" - animal_origin = MONKEY_BODYPART - px_x = -5 - px_y = -3 + for(var/thing in wounds) + var/datum/wound/W = thing + if(istype(W, checking_type)) + return W -/obj/item/bodypart/l_arm/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_l_arm" - px_x = 0 - px_y = 0 - dismemberable = 0 - max_damage = 100 - animal_origin = ALIEN_BODYPART +/// very rough start for updating efficiency and other stats on a body part whenever a wound is gained/lost +/obj/item/bodypart/proc/update_wounds() + var/dam_mul = 1 //initial(wound_damage_multiplier) -/obj/item/bodypart/l_arm/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART + // we can only have one wound per type, but remember there's multiple types + for(var/datum/wound/W in wounds) + dam_mul *= W.damage_mulitplier_penalty -/obj/item/bodypart/r_arm - name = "right arm" - desc = "Over 87% of humans are right handed. That figure is much lower \ - among humans missing their right arm." - icon_state = "default_human_r_arm" - attack_verb = list("slapped", "punched") - max_damage = 50 - body_zone = BODY_ZONE_R_ARM - body_part = ARM_RIGHT - aux_zone = BODY_ZONE_PRECISE_R_HAND - aux_layer = HANDS_PART_LAYER - body_damage_coeff = 0.75 - held_index = 2 - px_x = 6 - px_y = 0 - max_stamina_damage = 50 + wound_damage_multiplier = dam_mul + update_disabled() -/obj/item/bodypart/r_arm/is_disabled() - if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM)) - return BODYPART_DISABLED_PARALYSIS - return ..() - -/obj/item/bodypart/r_arm/set_disabled(new_disabled) - . = ..() - if(!.) +/obj/item/bodypart/proc/get_bleed_rate() + if(status != BODYPART_ORGANIC) // maybe in the future we can bleed oil from aug parts, but not now return - if(disabled == BODYPART_DISABLED_DAMAGE) - if(owner.stat < UNCONSCIOUS) - owner.emote("scream") - if(owner.stat < DEAD) - to_chat(owner, "Your [name] is too damaged to function!") - if(held_index) - owner.dropItemToGround(owner.get_item_for_held_index(held_index)) - else if(disabled == BODYPART_DISABLED_PARALYSIS) - if(owner.stat < DEAD) - to_chat(owner, "You can't feel your [name]!") - if(held_index) - owner.dropItemToGround(owner.get_item_for_held_index(held_index)) - if(owner.hud_used) - var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"] - if(R) - R.update_icon() -/obj/item/bodypart/r_arm/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_r_arm" - animal_origin = MONKEY_BODYPART - px_x = 5 - px_y = -3 + var/bleed_rate = 0 + if(generic_bleedstacks > 0) + bleed_rate++ -/obj/item/bodypart/r_arm/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_r_arm" - px_x = 0 - px_y = 0 - dismemberable = 0 - max_damage = 100 - animal_origin = ALIEN_BODYPART + if(brute_dam >= 40) + bleed_rate += (brute_dam * 0.008) -/obj/item/bodypart/r_arm/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART + //We want an accurate reading of .len + listclearnulls(embedded_objects) + for(var/obj/item/embeddies in embedded_objects) + if(!embeddies.isEmbedHarmless()) + bleed_rate += 0.5 -/obj/item/bodypart/l_leg - name = "left leg" - desc = "Some athletes prefer to tie their left shoelaces first for good \ - luck. In this instance, it probably would not have helped." - icon_state = "default_human_l_leg" - attack_verb = list("kicked", "stomped") - max_damage = 50 - body_zone = BODY_ZONE_L_LEG - body_part = LEG_LEFT - body_damage_coeff = 0.75 - px_x = -2 - px_y = 12 - max_stamina_damage = 50 + for(var/thing in wounds) + var/datum/wound/W = thing + bleed_rate += W.blood_flow -/obj/item/bodypart/l_leg/is_disabled() - if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG)) - return BODYPART_DISABLED_PARALYSIS - return ..() - -/obj/item/bodypart/l_leg/set_disabled(new_disabled) - . = ..() - if(!.) - return - if(disabled == BODYPART_DISABLED_DAMAGE) - if(owner.stat < UNCONSCIOUS) - owner.emote("scream") - if(owner.stat < DEAD) - to_chat(owner, "Your [name] is too damaged to function!") - else if(disabled == BODYPART_DISABLED_PARALYSIS) - if(owner.stat < DEAD) - to_chat(owner, "You can't feel your [name]!") - -/obj/item/bodypart/l_leg/digitigrade - name = "left digitigrade leg" - use_digitigrade = FULL_DIGITIGRADE - -/obj/item/bodypart/l_leg/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_l_leg" - animal_origin = MONKEY_BODYPART - px_y = 4 - -/obj/item/bodypart/l_leg/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_l_leg" - px_x = 0 - px_y = 0 - dismemberable = 0 - max_damage = 100 - animal_origin = ALIEN_BODYPART - -/obj/item/bodypart/l_leg/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART - -/obj/item/bodypart/r_leg - name = "right leg" - desc = "You put your right leg in, your right leg out. In, out, in, out, \ - shake it all about. And apparently then it detaches.\n\ - The hokey pokey has certainly changed a lot since space colonisation." - // alternative spellings of 'pokey' are availible - icon_state = "default_human_r_leg" - attack_verb = list("kicked", "stomped") - max_damage = 50 - body_zone = BODY_ZONE_R_LEG - body_part = LEG_RIGHT - body_damage_coeff = 0.75 - px_x = 2 - px_y = 12 - max_stamina_damage = 50 - -/obj/item/bodypart/r_leg/is_disabled() - if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG)) - return BODYPART_DISABLED_PARALYSIS - return ..() - -/obj/item/bodypart/r_leg/set_disabled(new_disabled) - . = ..() - if(!.) - return - if(disabled == BODYPART_DISABLED_DAMAGE) - if(owner.stat < UNCONSCIOUS) - owner.emote("scream") - if(owner.stat < DEAD) - to_chat(owner, "Your [name] is too damaged to function!") - else if(disabled == BODYPART_DISABLED_PARALYSIS) - if(owner.stat < DEAD) - to_chat(owner, "You can't feel your [name]!") - -/obj/item/bodypart/r_leg/digitigrade - name = "right digitigrade leg" - use_digitigrade = FULL_DIGITIGRADE - -/obj/item/bodypart/r_leg/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_r_leg" - animal_origin = MONKEY_BODYPART - px_y = 4 - -/obj/item/bodypart/r_leg/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_r_leg" - px_x = 0 - px_y = 0 - dismemberable = 0 - max_damage = 100 - animal_origin = ALIEN_BODYPART - -/obj/item/bodypart/r_leg/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART + return bleed_rate diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 84f45cc88c3..48312107dad 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -16,9 +16,10 @@ return FALSE var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST) - affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50)) //Damage the chest based on limb's existing damage + affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50), wound_bonus=CANT_WOUND) //Damage the chest based on limb's existing damage C.visible_message("[C]'s [src.name] is violently dismembered!") C.emote("scream") + playsound(get_turf(C), 'sound/effects/dismember.ogg', 80, TRUE) SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered) drop_limb() @@ -81,11 +82,12 @@ //limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in. -/obj/item/bodypart/proc/drop_limb(special) +/obj/item/bodypart/proc/drop_limb(special, dismembered) if(!owner) return var/atom/Tsec = owner.drop_location() var/mob/living/carbon/C = owner + SEND_SIGNAL(C, COMSIG_CARBON_REMOVE_LIMB, src, dismembered) update_limb(1) C.bodyparts -= src @@ -96,6 +98,15 @@ C.dropItemToGround(owner.get_item_for_held_index(held_index), 1) C.hand_bodyparts[held_index] = null + for(var/thing in scars) + var/datum/scar/S = thing + S.victim = null + LAZYREMOVE(owner.all_scars, S) + + for(var/thing in wounds) + var/datum/wound/W = thing + W.remove_wound(TRUE) + owner = null for(var/X in C.surgeries) //if we had an ongoing surgery on that limb, we stop it. @@ -278,7 +289,7 @@ O.drop_limb(1) /obj/item/bodypart/proc/attach_limb(mob/living/carbon/C, special) - if(SEND_SIGNAL(C, COMSIG_LIVING_ATTACH_LIMB, src, special) & COMPONENT_NO_ATTACH) + if(SEND_SIGNAL(C, COMSIG_CARBON_ATTACH_LIMB, src, special) & COMPONENT_NO_ATTACH) return FALSE . = TRUE moveToNullspace() @@ -308,6 +319,15 @@ for(var/obj/item/organ/O in contents) O.Insert(C) + for(var/thing in scars) + var/datum/scar/S = thing + S.victim = C + LAZYADD(C.all_scars, thing) + + for(var/i in wounds) + var/datum/wound/W = i + W.apply_wound(src, TRUE) + update_bodypart_damage_state() C.updatehealth() diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 928216af50f..9abbf3441b6 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -13,6 +13,9 @@ px_y = -8 stam_damage_coeff = 1 max_stamina_damage = 100 + wound_resistance = 10 + specific_locations = list("left eyebrow", "cheekbone", "neck", "throat", "jawline", "entire face") + scars_covered_by_clothes = FALSE var/mob/living/brain/brainmob = null //The current occupant. var/obj/item/organ/brain/brain = null //The brain organ diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index a91837e9fe0..c2a96fbce0b 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -18,6 +18,15 @@ return FALSE +///Get the bodypart for whatever hand we have active, Only relevant for carbons +/mob/proc/get_active_hand() + return FALSE + +/mob/living/carbon/get_active_hand() + var/which_hand = BODY_ZONE_PRECISE_L_HAND + if(!(active_hand_index % 2)) + which_hand = BODY_ZONE_PRECISE_R_HAND + return get_bodypart(check_zone(which_hand)) /mob/proc/has_left_hand(check_disabled = TRUE) diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm new file mode 100644 index 00000000000..bd4abaa7650 --- /dev/null +++ b/code/modules/surgery/bodyparts/parts.dm @@ -0,0 +1,307 @@ + +/obj/item/bodypart/chest + name = BODY_ZONE_CHEST + desc = "It's impolite to stare at a person's chest." + icon_state = "default_human_chest" + max_damage = 200 + body_zone = BODY_ZONE_CHEST + body_part = CHEST + px_x = 0 + px_y = 0 + stam_damage_coeff = 1 + max_stamina_damage = 120 + var/obj/item/cavity_item + specific_locations = list("upper chest", "lower abdomen", "midsection", "collarbone", "lower back") + wound_resistance = 10 + +/obj/item/bodypart/chest/can_dismember(obj/item/I) + if(!((owner.stat == DEAD) || owner.InFullCritical())) + return FALSE + return ..() + +/obj/item/bodypart/chest/Destroy() + QDEL_NULL(cavity_item) + return ..() + +/obj/item/bodypart/chest/drop_organs(mob/user, violent_removal) + if(cavity_item) + cavity_item.forceMove(drop_location()) + cavity_item = null + ..() + +/obj/item/bodypart/chest/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_chest" + animal_origin = MONKEY_BODYPART + wound_resistance = -10 + +/obj/item/bodypart/chest/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_chest" + dismemberable = 0 + max_damage = 500 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/chest/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART + +/obj/item/bodypart/chest/larva + icon = 'icons/mob/animal_parts.dmi' + icon_state = "larva_chest" + dismemberable = 0 + max_damage = 50 + animal_origin = LARVA_BODYPART + +/obj/item/bodypart/l_arm + name = "left arm" + desc = "Did you know that the word 'sinister' stems originally from the \ + Latin 'sinestra' (left hand), because the left hand was supposed to \ + be possessed by the devil? This arm appears to be possessed by no \ + one though." + icon_state = "default_human_l_arm" + attack_verb = list("slapped", "punched") + max_damage = 50 + max_stamina_damage = 50 + body_zone = BODY_ZONE_L_ARM + body_part = ARM_LEFT + aux_zone = BODY_ZONE_PRECISE_L_HAND + aux_layer = HANDS_PART_LAYER + body_damage_coeff = 0.75 + held_index = 1 + px_x = -6 + px_y = 0 + specific_locations = list("outer left forearm", "inner left wrist", "left elbow", "left bicep", "left shoulder") + +/obj/item/bodypart/l_arm/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/l_arm/set_disabled(new_disabled) + . = ..() + if(!.) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat < UNCONSCIOUS) + owner.emote("scream") + if(owner.stat < DEAD) + to_chat(owner, "Your [name] is too damaged to function!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(owner.stat < DEAD) + to_chat(owner, "You can't feel your [name]!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + if(owner.hud_used) + var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"] + if(L) + L.update_icon() + +/obj/item/bodypart/l_arm/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_l_arm" + animal_origin = MONKEY_BODYPART + wound_resistance = -10 + px_x = -5 + px_y = -3 + +/obj/item/bodypart/l_arm/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_l_arm" + px_x = 0 + px_y = 0 + dismemberable = 0 + max_damage = 100 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/l_arm/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART + +/obj/item/bodypart/r_arm + name = "right arm" + desc = "Over 87% of humans are right handed. That figure is much lower \ + among humans missing their right arm." + icon_state = "default_human_r_arm" + attack_verb = list("slapped", "punched") + max_damage = 50 + body_zone = BODY_ZONE_R_ARM + body_part = ARM_RIGHT + aux_zone = BODY_ZONE_PRECISE_R_HAND + aux_layer = HANDS_PART_LAYER + body_damage_coeff = 0.75 + held_index = 2 + px_x = 6 + px_y = 0 + max_stamina_damage = 50 + specific_locations = list("outer right forearm", "inner right wrist", "right elbow", "right bicep", "right shoulder") + +/obj/item/bodypart/r_arm/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/r_arm/set_disabled(new_disabled) + . = ..() + if(!.) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat < UNCONSCIOUS) + owner.emote("scream") + if(owner.stat < DEAD) + to_chat(owner, "Your [name] is too damaged to function!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(owner.stat < DEAD) + to_chat(owner, "You can't feel your [name]!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + if(owner.hud_used) + var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"] + if(R) + R.update_icon() + +/obj/item/bodypart/r_arm/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_r_arm" + animal_origin = MONKEY_BODYPART + wound_resistance = -10 + px_x = 5 + px_y = -3 + +/obj/item/bodypart/r_arm/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_r_arm" + px_x = 0 + px_y = 0 + dismemberable = 0 + max_damage = 100 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/r_arm/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART + +/obj/item/bodypart/l_leg + name = "left leg" + desc = "Some athletes prefer to tie their left shoelaces first for good \ + luck. In this instance, it probably would not have helped." + icon_state = "default_human_l_leg" + attack_verb = list("kicked", "stomped") + max_damage = 50 + body_zone = BODY_ZONE_L_LEG + body_part = LEG_LEFT + body_damage_coeff = 0.75 + px_x = -2 + px_y = 12 + max_stamina_damage = 50 + specific_locations = list("inner left thigh", "outer left calf", "outer left hip", " left kneecap", "lower left shin") + +/obj/item/bodypart/l_leg/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/l_leg/set_disabled(new_disabled) + . = ..() + if(!.) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat < UNCONSCIOUS) + owner.emote("scream") + if(owner.stat < DEAD) + to_chat(owner, "Your [name] is too damaged to function!") + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(owner.stat < DEAD) + to_chat(owner, "You can't feel your [name]!") + +/obj/item/bodypart/l_leg/digitigrade + name = "left digitigrade leg" + use_digitigrade = FULL_DIGITIGRADE + +/obj/item/bodypart/l_leg/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_l_leg" + animal_origin = MONKEY_BODYPART + wound_resistance = -10 + px_y = 4 + +/obj/item/bodypart/l_leg/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_l_leg" + px_x = 0 + px_y = 0 + dismemberable = 0 + max_damage = 100 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/l_leg/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART + +/obj/item/bodypart/r_leg + name = "right leg" + desc = "You put your right leg in, your right leg out. In, out, in, out, \ + shake it all about. And apparently then it detaches.\n\ + The hokey pokey has certainly changed a lot since space colonisation." + // alternative spellings of 'pokey' are availible + icon_state = "default_human_r_leg" + attack_verb = list("kicked", "stomped") + max_damage = 50 + body_zone = BODY_ZONE_R_LEG + body_part = LEG_RIGHT + body_damage_coeff = 0.75 + px_x = 2 + px_y = 12 + max_stamina_damage = 50 + specific_locations = list("inner right thigh", "outer right calf", "outer right hip", "right kneecap", "lower right shin") + +/obj/item/bodypart/r_leg/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/r_leg/set_disabled(new_disabled) + . = ..() + if(!.) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat < UNCONSCIOUS) + owner.emote("scream") + if(owner.stat < DEAD) + to_chat(owner, "Your [name] is too damaged to function!") + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(owner.stat < DEAD) + to_chat(owner, "You can't feel your [name]!") + +/obj/item/bodypart/r_leg/digitigrade + name = "right digitigrade leg" + use_digitigrade = FULL_DIGITIGRADE + +/obj/item/bodypart/r_leg/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_r_leg" + animal_origin = MONKEY_BODYPART + wound_resistance = -10 + px_y = 4 + +/obj/item/bodypart/r_leg/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_r_leg" + px_x = 0 + px_y = 0 + dismemberable = 0 + max_damage = 100 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/r_leg/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART diff --git a/code/modules/surgery/bone_mending.dm b/code/modules/surgery/bone_mending.dm new file mode 100644 index 00000000000..6afe4941058 --- /dev/null +++ b/code/modules/surgery/bone_mending.dm @@ -0,0 +1,142 @@ + +/////BONE FIXING SURGERIES////// + +///// Repair Hairline Fracture (Severe) +/datum/surgery/repair_bone_hairline + name = "Repair bone fracture (hairline)" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/repair_bone_hairline, /datum/surgery_step/close) + target_mobtypes = list(/mob/living/carbon/human) + possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) + requires_real_bodypart = TRUE + targetable_wound = /datum/wound/brute/bone/severe + +/datum/surgery/repair_bone_hairline/can_start(mob/living/user, mob/living/carbon/target) + if(..()) + var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected) + return(targeted_bodypart.get_wound_type(targetable_wound)) + + +///// Repair Compound Fracture (Critical) +/datum/surgery/repair_bone_compound + name = "Repair Compound Fracture" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/reset_compound_fracture, /datum/surgery_step/repair_bone_compound, /datum/surgery_step/close) + target_mobtypes = list(/mob/living/carbon/human) + possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) + requires_real_bodypart = TRUE + targetable_wound = /datum/wound/brute/bone/critical + +/datum/surgery/repair_bone_compound/can_start(mob/living/user, mob/living/carbon/target) + if(..()) + var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected) + return(targeted_bodypart.get_wound_type(targetable_wound)) + + + +//SURGERY STEPS + +///// Repair Hairline Fracture (Severe) +/datum/surgery_step/repair_bone_hairline + name = "repair hairline fracture (bonesetter/bone gel/tape)" + implements = list(/obj/item/bonesetter = 100, /obj/item/stack/medical/bone_gel = 100, /obj/item/stack/sticky_tape/surgical = 100, /obj/item/stack/sticky_tape/super = 50, /obj/item/stack/sticky_tape = 30) + time = 40 + experience_given = MEDICAL_SKILL_MEDIUM + +/datum/surgery_step/repair_bone_hairline/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(surgery.operated_wound) + display_results(user, target, "You begin to repair the fracture in [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/repair_bone_hairline/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + if(surgery.operated_wound) + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + display_results(user, target, "You successfully repair the fracture in [target]'s [parse_zone(target_zone)].", + "[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)]!") + log_combat(user, target, "repaired a hairline fracture in", addition="INTENT: [uppertext(user.a_intent)]") + qdel(surgery.operated_wound) + else + to_chat(user, "[target] has no hairline fracture there!") + return ..() + +/datum/surgery_step/repair_bone_hairline/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + + + +///// Reset Compound Fracture (Crticial) +/datum/surgery_step/reset_compound_fracture + name = "reset bone" + implements = list(/obj/item/bonesetter = 100, /obj/item/stack/sticky_tape/surgical = 60, /obj/item/stack/sticky_tape/super = 40, /obj/item/stack/sticky_tape = 20) + time = 40 + experience_given = MEDICAL_SKILL_MEDIUM + +/datum/surgery_step/reset_compound_fracture/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(surgery.operated_wound) + display_results(user, target, "You begin to reset the bone in [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to reset the bone in [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to reset the bone in [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/reset_compound_fracture/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + if(surgery.operated_wound) + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + display_results(user, target, "You successfully reset the bone in [target]'s [parse_zone(target_zone)].", + "[user] successfully resets the bone in [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully resets the bone in [target]'s [parse_zone(target_zone)]!") + log_combat(user, target, "reset a compound fracture in", addition="INTENT: [uppertext(user.a_intent)]") + else + to_chat(user, "[target] has no compound fracture there!") + return ..() + +/datum/surgery_step/reset_compound_fracture/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + + +///// Repair Compound Fracture (Crticial) +/datum/surgery_step/repair_bone_compound + name = "repair compound fracture (bone gel/tape)" + implements = list(/obj/item/stack/medical/bone_gel = 100, /obj/item/stack/sticky_tape/surgical = 100, /obj/item/stack/sticky_tape/super = 50, /obj/item/stack/sticky_tape = 30) + time = 40 + experience_given = MEDICAL_SKILL_MEDIUM + +/datum/surgery_step/repair_bone_compound/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(surgery.operated_wound) + display_results(user, target, "You begin to repair the fracture in [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/repair_bone_compound/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + if(surgery.operated_wound) + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + display_results(user, target, "You successfully repair the fracture in [target]'s [parse_zone(target_zone)].", + "[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)]!") + log_combat(user, target, "repaired a compound fracture in", addition="INTENT: [uppertext(user.a_intent)]") + qdel(surgery.operated_wound) + else + to_chat(user, "[target] has no compound fracture there!") + return ..() + +/datum/surgery_step/repair_bone_compound/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) diff --git a/code/modules/surgery/burn_dressing.dm b/code/modules/surgery/burn_dressing.dm new file mode 100644 index 00000000000..1d64d29ff63 --- /dev/null +++ b/code/modules/surgery/burn_dressing.dm @@ -0,0 +1,108 @@ + +/////BURN FIXING SURGERIES////// + +///// Debride burnt flesh +/datum/surgery/debride + name = "Debride infected flesh" + steps = list(/datum/surgery_step/debride, /datum/surgery_step/dress) + target_mobtypes = list(/mob/living/carbon/human) + possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) + requires_real_bodypart = TRUE + targetable_wound = /datum/wound/burn + +/datum/surgery/debride/can_start(mob/living/user, mob/living/carbon/target) + if(..()) + var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected) + var/datum/wound/burn/burn_wound = targeted_bodypart.get_wound_type(targetable_wound) + return(burn_wound && burn_wound.infestation > 0) + +//SURGERY STEPS + +///// Debride +/datum/surgery_step/debride + name = "excise infection" + implements = list(TOOL_HEMOSTAT = 100, TOOL_SCALPEL = 85, TOOL_SAW = 60, TOOL_WIRECUTTER = 40) + time = 30 + repeatable = TRUE + experience_given = MEDICAL_SKILL_MEDIUM + +/datum/surgery_step/debride/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(surgery.operated_wound) + var/datum/wound/burn/burn_wound = surgery.operated_wound + if(burn_wound.infestation <= 0) + to_chat(user, "[target]'s [parse_zone(user.zone_selected)] has no infected flesh to remove!") + surgery.status++ + repeatable = FALSE + return + display_results(user, target, "You begin to excise infected flesh from [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to excise infected flesh from [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to excise infected flesh from [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/debride/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + var/datum/wound/burn/burn_wound = surgery.operated_wound + if(burn_wound) + display_results(user, target, "You successfully excise some of the infected flesh from [target]'s [parse_zone(target_zone)].", + "[user] successfully excises some of the infected flesh from [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully excises some of the infected flesh from [target]'s [parse_zone(target_zone)]!") + log_combat(user, target, "excised infected flesh in", addition="INTENT: [uppertext(user.a_intent)]") + surgery.operated_bodypart.receive_damage(brute=3, wound_bonus=CANT_WOUND) + burn_wound.infestation -= 0.5 + burn_wound.sanitization += 0.5 + if(burn_wound.infestation <= 0) + repeatable = FALSE + else + to_chat(user, "[target] has no infected flesh there!") + return ..() + +/datum/surgery_step/debride/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + display_results(user, target, "You carve away some of the healthy flesh from [target]'s [parse_zone(target_zone)].", + "[user] carves away some of the healthy flesh from [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] carves away some of the healthy flesh from [target]'s [parse_zone(target_zone)]!") + surgery.operated_bodypart.receive_damage(brute=rand(4,8), sharpness=TRUE) + +/datum/surgery_step/debride/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE) + if(!..()) + return + var/datum/wound/burn/burn_wound = surgery.operated_wound + while(burn_wound && burn_wound.infestation > 0.25) + if(!..()) + break + +///// Dressing burns +/datum/surgery_step/dress + name = "bandage burns" + implements = list(/obj/item/stack/medical/gauze = 100, /obj/item/stack/sticky_tape/surgical = 100) + time = 40 + experience_given = MEDICAL_SKILL_MEDIUM + +/datum/surgery_step/dress/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/datum/wound/burn/burn_wound = surgery.operated_wound + if(burn_wound) + display_results(user, target, "You begin to dress the burns on [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to dress the burns on [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to dress the burns on [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/dress/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + var/datum/wound/burn/burn_wound = surgery.operated_wound + if(burn_wound) + display_results(user, target, "You successfully wrap [target]'s [parse_zone(target_zone)] with [tool].", + "[user] successfully wraps [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully wraps [target]'s [parse_zone(target_zone)]!") + log_combat(user, target, "dressed burns in", addition="INTENT: [uppertext(user.a_intent)]") + burn_wound.sanitization += 3 + burn_wound.flesh_healing += 5 + burn_wound.force_bandage(tool) + else + to_chat(user, "[target] has no burns there!") + return ..() + +/datum/surgery_step/dress/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm index ebe735278ee..492620ad92a 100644 --- a/code/modules/surgery/coronary_bypass.dm +++ b/code/modules/surgery/coronary_bypass.dm @@ -31,7 +31,8 @@ display_results(user, target, "Blood pools around the incision in [H]'s heart.", "Blood pools around the incision in [H]'s heart.", "") - H.bleed_rate += 10 + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + BP.generic_bleedstacks += 10 H.adjustBruteLoss(10) return ..() @@ -41,7 +42,8 @@ display_results(user, target, "You screw up, cutting too deeply into the heart!", "[user] screws up, causing blood to spurt out of [H]'s chest!", "[user] screws up, causing blood to spurt out of [H]'s chest!") - H.bleed_rate += 20 + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + BP.generic_bleedstacks += 10 H.adjustOrganLoss(ORGAN_SLOT_HEART, 10) H.adjustBruteLoss(10) @@ -74,5 +76,6 @@ "[user] screws up, causing blood to spurt out of [H]'s chest profusely!", "[user] screws up, causing blood to spurt out of [H]'s chest profusely!") H.adjustOrganLoss(ORGAN_SLOT_HEART, 20) - H.bleed_rate += 30 + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + BP.generic_bleedstacks += 30 return FALSE diff --git a/code/modules/surgery/experimental_dissection.dm b/code/modules/surgery/experimental_dissection.dm index e8cc949722e..420b0303531 100644 --- a/code/modules/surgery/experimental_dissection.dm +++ b/code/modules/surgery/experimental_dissection.dm @@ -72,7 +72,7 @@ /datum/surgery_step/dissection/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) user.visible_message("[user] dissects [target], enhancing their medical knowledge!", "You dissect [target] and receive some healing experience!") var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST) - target.apply_damage(80, BRUTE, L) + target.apply_damage(80, BRUTE, L, wound_bonus=CANT_WOUND) ADD_TRAIT(target, TRAIT_DISSECTED, "[surgery.name]") repeatable = FALSE experience_given = check_value(target, surgery) @@ -81,7 +81,7 @@ /datum/surgery_step/dissection/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] dissects [target]!", "You attempt to dissect [target], but do not find anything particularly interesting.") var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST) - target.apply_damage(80, BRUTE, L) + target.apply_damage(80, BRUTE, L, wound_bonus=CANT_WOUND) return TRUE /datum/surgery/advanced/experimental_dissection/adv diff --git a/code/modules/surgery/healing.dm b/code/modules/surgery/healing.dm index 776c6389794..edf4327a951 100644 --- a/code/modules/surgery/healing.dm +++ b/code/modules/surgery/healing.dm @@ -90,7 +90,7 @@ urdamageamt_brute += round((target.getBruteLoss()/ (missinghpbonus*2)),0.1) urdamageamt_burn += round((target.getFireLoss()/ (missinghpbonus*2)),0.1) - target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn) + target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn, wound_bonus=CANT_WOUND) return FALSE /***************************BRUTE***************************/ diff --git a/code/modules/surgery/organic_steps.dm b/code/modules/surgery/organic_steps.dm index 3145669cf2a..1aa82c36832 100644 --- a/code/modules/surgery/organic_steps.dm +++ b/code/modules/surgery/organic_steps.dm @@ -24,7 +24,9 @@ display_results(user, target, "Blood pools around the incision in [H]'s [parse_zone(target_zone)].", "Blood pools around the incision in [H]'s [parse_zone(target_zone)].", "") - H.bleed_rate += 3 + var/obj/item/bodypart/BP = target.get_bodypart(target_zone) + if(BP) + BP.generic_bleedstacks += 10 return ..() /datum/surgery_step/incise/nobleed //silly friendly! @@ -55,7 +57,9 @@ target.heal_bodypart_damage(20,0) if (ishuman(target)) var/mob/living/carbon/human/H = target - H.bleed_rate = max( (H.bleed_rate - 3), 0) + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + if(BP) + BP.generic_bleedstacks -= 3 return ..() //retract skin @@ -94,7 +98,9 @@ target.heal_bodypart_damage(45,0) if (ishuman(target)) var/mob/living/carbon/human/H = target - H.bleed_rate = max( (H.bleed_rate - 3), 0) + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + if(BP) + BP.generic_bleedstacks -= 3 return ..() @@ -117,7 +123,7 @@ return TRUE /datum/surgery_step/saw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results) - target.apply_damage(50, BRUTE, "[target_zone]") + target.apply_damage(50, BRUTE, "[target_zone]", wound_bonus=CANT_WOUND) display_results(user, target, "You saw [target]'s [parse_zone(target_zone)] open.", "[user] saws [target]'s [parse_zone(target_zone)] open!", "[user] saws [target]'s [parse_zone(target_zone)] open!") diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index 4de3d105070..10db72a5ea2 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -312,13 +312,14 @@ cooldown = COOLDOWN_DAMAGE for(var/V in listeners) var/mob/living/L = V - L.apply_damage(15 * power_multiplier, def_zone = BODY_ZONE_CHEST) + L.apply_damage(15 * power_multiplier, def_zone = BODY_ZONE_CHEST, wound_bonus=CANT_WOUND) //BLEED else if((findtext(message, bleed_words))) cooldown = COOLDOWN_DAMAGE for(var/mob/living/carbon/human/H in listeners) - H.bleed_rate += (5 * power_multiplier) + var/obj/item/bodypart/BP = pick(H.bodyparts) + BP.generic_bleedstacks += 5 //FIRE else if((findtext(message, burn_words))) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index baa53690529..334d73649e8 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -12,6 +12,8 @@ var/ignore_clothes = FALSE //This surgery ignores clothes var/mob/living/carbon/target //Operation target mob var/obj/item/bodypart/operated_bodypart //Operable body part + var/datum/wound/operated_wound //The actual wound datum instance we're targeting + var/datum/wound/targetable_wound //The wound type this surgery targets var/requires_bodypart = TRUE //Surgery available only when a bodypart is present, or only when it is missing. var/speed_modifier = 0 //Step speed modifier var/requires_real_bodypart = FALSE //Some surgeries don't work on limbs that don't really exist @@ -29,8 +31,13 @@ location = surgery_location if(surgery_bodypart) operated_bodypart = surgery_bodypart + if(targetable_wound) + operated_wound = operated_bodypart.get_wound_type(targetable_wound) + operated_wound.attached_surgery = src /datum/surgery/Destroy() + if(operated_wound) + operated_wound.attached_surgery = null if(target) target.surgeries -= src target = null diff --git a/code/modules/surgery/surgery_helpers.dm b/code/modules/surgery/surgery_helpers.dm index 8e9e0436f7a..ace0b1bb6ac 100644 --- a/code/modules/surgery/surgery_helpers.dm +++ b/code/modules/surgery/surgery_helpers.dm @@ -108,9 +108,9 @@ to_chat(user, "You need to hold a [is_robotic ? "screwdriver" : "cautery"] in your inactive hand to stop [M]'s surgery!") return - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.bleed_rate = max( (H.bleed_rate - 3), 0) + if(S.operated_bodypart) + S.operated_bodypart.generic_bleedstacks -= 5 + M.surgeries -= S user.visible_message("[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool] and removes [I].", \ "You close [M]'s [parse_zone(selected_zone)] with [close_tool] and remove [I].") diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 869616841b2..611f4f8f1cb 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -113,6 +113,7 @@ sharpness = IS_SHARP_ACCURATE tool_behaviour = TOOL_SCALPEL toolspeed = 1 + bare_wound_bonus = 20 /obj/item/scalpel/Initialize() . = ..() @@ -143,11 +144,13 @@ throwforce = 9 throw_speed = 2 throw_range = 5 - custom_materials = list(/datum/material/iron=10000, /datum/material/glass=6000) + custom_materials = list(/datum/material/iron=1000) attack_verb = list("attacked", "slashed", "sawed", "cut") sharpness = IS_SHARP tool_behaviour = TOOL_SAW toolspeed = 1 + wound_bonus = 10 + bare_wound_bonus = 15 /obj/item/circular_saw/Initialize() . = ..() @@ -400,3 +403,17 @@ limb_snip_candidate.dismember() user.visible_message("[src] violently slams shut, amputating [patient]'s [candidate_name].", "You amputate [patient]'s [candidate_name] with [src].") +/obj/item/bonesetter + name = "bonesetter" + desc = "For setting things right." + icon = 'icons/obj/surgery.dmi' + icon_state = "bone setter" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2500) + flags_1 = CONDUCT_1 + item_flags = SURGICAL_TOOL + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("corrected", "properly set") + tool_behaviour = TOOL_BONESET + toolspeed = 1 diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index aac9725fa86..f48e3decb07 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -494,7 +494,7 @@ GLOBAL_LIST_EMPTY(vending_products) var/crit_case if(crit) - crit_case = rand(1,5) + crit_case = rand(1,6) if(forcecrit) crit_case = forcecrit @@ -507,7 +507,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(istype(C)) var/crit_rebate = 0 // lessen the normal damage we deal for some of the crits - if(crit_case != 5) // the head asplode case has its own description + if(crit_case < 5) // the body/head asplode case has its own description C.visible_message("[C] is crushed by [src]!", \ "You are crushed by [src]!") @@ -517,10 +517,10 @@ GLOBAL_LIST_EMPTY(vending_products) C.bleed(150) var/obj/item/bodypart/l_leg/l = C.get_bodypart(BODY_ZONE_L_LEG) if(l) - l.receive_damage(brute=200, updating_health=TRUE) + l.receive_damage(brute=200) var/obj/item/bodypart/r_leg/r = C.get_bodypart(BODY_ZONE_R_LEG) if(r) - r.receive_damage(brute=200, updating_health=TRUE) + r.receive_damage(brute=200) if(l || r) C.visible_message("[C]'s legs shatter with a sickening crunch!", \ "Your legs shatter with a sickening crunch!") @@ -542,7 +542,18 @@ GLOBAL_LIST_EMPTY(vending_products) // the new paraplegic gets like 4 lines of losing their legs so skip them visible_message("[C]'s spinal cord is obliterated with a sickening crunch!", ignored_mobs = list(C)) C.gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic) - if(5) // skull squish! + if(5) // limb squish! + for(var/i in C.bodyparts) + var/obj/item/bodypart/squish_part = i + if(squish_part.is_organic_limb()) + //var/type_wound = pick(WOUND_LIST_BONE) + var/type_wound = pick(list(/datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/moderate)) + squish_part.force_wound_upwards(type_wound) + else + squish_part.receive_damage(brute=30) + C.visible_message("[C]'s body is maimed underneath the mass of [src]!", \ + "Your body is maimed underneath the mass of [src]!") + if(6) // skull squish! var/obj/item/bodypart/head/O = C.get_bodypart(BODY_ZONE_HEAD) if(O) C.visible_message("[O] explodes in a shower of gore beneath [src]!", \ @@ -552,7 +563,11 @@ GLOBAL_LIST_EMPTY(vending_products) qdel(O) new /obj/effect/gibspawner/human/bodypartless(get_turf(C)) - C.apply_damage(max(0, squish_damage - crit_rebate), forced=TRUE, spread_damage=TRUE) + if(prob(30)) + C.apply_damage(max(0, squish_damage - crit_rebate), forced=TRUE, spread_damage=TRUE) // the 30% chance to spread the damage means you escape breaking any bones + else + C.take_bodypart_damage((squish_damage - crit_rebate)*0.5, wound_bonus = 5) // otherwise, deal it to 2 random limbs (or the same one) which will likely shatter something + C.take_bodypart_damage((squish_damage - crit_rebate)*0.5, wound_bonus = 5) C.AddElement(/datum/element/squish, 80 SECONDS) else L.visible_message("[L] is crushed by [src]!", \ diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index d6a15a7f683..77786456c69 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -24,7 +24,12 @@ /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/reagent_containers/medigel/libital = 2, /obj/item/reagent_containers/medigel/aiuri = 2, - /obj/item/reagent_containers/medigel/sterilizine = 1) + /obj/item/reagent_containers/medigel/sterilizine = 1, + /obj/item/stack/sticky_tape/surgical = 3, + /obj/item/healthanalyzer/wound = 4, + /obj/item/stack/medical/ointment = 2, + /obj/item/stack/medical/suture = 2, + /obj/item/stack/medical/bone_gel = 4) contraband = list(/obj/item/reagent_containers/pill/tox = 3, /obj/item/reagent_containers/pill/morphine = 4, /obj/item/reagent_containers/pill/multiver = 6, diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index 706fde6295a..c8e3d2b52d6 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -10,7 +10,9 @@ /obj/item/reagent_containers/pill/multiver = 2, /obj/item/reagent_containers/medigel/libital = 2, /obj/item/reagent_containers/medigel/aiuri = 2, - /obj/item/reagent_containers/medigel/sterilizine = 1) + /obj/item/reagent_containers/medigel/sterilizine = 1, + /obj/item/healthanalyzer/wound = 2, + /obj/item/stack/medical/bone_gel = 2) contraband = list(/obj/item/reagent_containers/pill/tox = 2, /obj/item/reagent_containers/pill/morphine = 2, /obj/item/storage/box/gum/happiness = 1) diff --git a/code/modules/vending/robotics.dm b/code/modules/vending/robotics.dm index e8b377db3db..ce3b8b336f8 100644 --- a/code/modules/vending/robotics.dm +++ b/code/modules/vending/robotics.dm @@ -16,6 +16,7 @@ /obj/item/healthanalyzer = 3, /obj/item/scalpel = 2, /obj/item/circular_saw = 2, + /obj/item/bonesetter = 2, /obj/item/tank/internals/anesthetic = 2, /obj/item/clothing/mask/breath/medical = 5, /obj/item/screwdriver = 5, diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index 6b46542020a..1c97853c466 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -12,6 +12,9 @@ var/icon_right = "bloodhand_right" hitsound = 'sound/hallucinations/growl1.ogg' force = 21 // Just enough to break airlocks with melee attacks + sharpness = IS_SHARP + wound_bonus = -30 + bare_wound_bonus = 15 damtype = "brute" /obj/item/zombie_hand/Initialize() diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi index 24452d057f8ab0142f7264c12ccbadaff13d9788..cf1ad37097e31bc55dbe44cbf76811287ff95266 100644 GIT binary patch delta 22157 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 a+B$d?y--@=gwK981U7vg&>K+GHsZgN%55J2 delta 21446 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 Kul3m7?*AW%+lo*C diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi index b1c697761880ded2f4927705acaec7c5bac24d5a..aa4d4cf7ddcc99ee2134222a267fae5c22965add 100644 GIT binary patch delta 61388 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
Fq*iZB_G>mwi`~$>ETd*6z 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�tmG3{1DG3k!# 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 z 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%0AFCMA5&wLD{vD+RZD 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 literal 0 HcmV?d00001 diff --git a/sound/effects/blood3.ogg b/sound/effects/blood3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f6024a5ff6acdd3cd140d970828638e37726aa88 GIT binary patch literal 13657 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 literal 0 HcmV?d00001 diff --git a/sound/effects/butcher.ogg b/sound/effects/butcher.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2e4a0d2ddc71995b05e2f55b4d981de6496a2097 GIT binary patch literal 9666 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 Zjg{^ELdF2RwSE3Y_oA>X6rlUJ_CK2~E9U?J literal 0 HcmV?d00001 diff --git a/sound/effects/crack1.ogg b/sound/effects/crack1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..aa3bf0ab014cc1098960240391eef2ba82cc3ba2 GIT binary patch literal 7950 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 literal 0 HcmV?d00001 diff --git a/sound/effects/crack2.ogg b/sound/effects/crack2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cef226c98bd0848de3602fb14a07f1de41c19eed GIT binary patch literal 15346 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 Jsqkab{|mdIFYN#T literal 0 HcmV?d00001 diff --git a/sound/effects/dismember.ogg b/sound/effects/dismember.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f5015ad961584f9559945ba0b21f0956fbe9b073 GIT binary patch literal 15382 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 GO8*CsO9tuy literal 0 HcmV?d00001 diff --git a/sound/effects/sizzle1.ogg b/sound/effects/sizzle1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4a3d2290181cf2fe219d0196f441420d133e0105 GIT binary patch literal 52702 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%0Dx5x7!DSAK$8YRZZ<^4K2-Zj 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 Fe*m7re$xN| literal 0 HcmV?d00001 diff --git a/strings/tips.txt b/strings/tips.txt index f2a2fb70e96..ef245d31183 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -252,3 +252,9 @@ You can light a cigar on a supermatter crystal. Using sticky tape on items can make them stick to people and walls! Be careful, grenades might stick to your hand during the moment of truth! In a pinch, stripping yourself naked will give you a sizeable resistance to being tackled. What do you value more, your freedom or your dignity? Wearing riot armor makes you significantly more effective at performing tackle takedowns, but will use extra stamina with each leap! It will also significantly protect you from other tackles! +As a Changeling, your Regenerate Limbs power will quickly heal all of your wounds, but they'll still leave scars. Changelings can use Fleshmend to get rid of scars, or you can ingest Carpotoxin to get rid of them like a normal person. +Stasis beds halt ALL passive life functions, including regeneration. If your patient isn't responding to treatment, especially with cut or burn wounds, try unbuckling them! +Epipens contain a powerful coagulant that drastically reduces bleeding on all open cuts. If you don't have time to properly treat someone with lots of cuts, stick them with a pen to buy some time! +If a patient has an absurd amount of wounds, putting them in cryo will slowly treat all of their wounds simultaneously. +Anything you can light a cigarette with, you can use to cauterize a bleeding wound. Technically, that includes the supermatter. +Moderate and Severe cuts will slowly clot by themselves and don't require immediate attention on their own. Critical cuts will actively get worse with time, and are an immediate threat to the patient's life. diff --git a/tgstation.dme b/tgstation.dme index a5b9ca3cabe..1ea4d7f468a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -113,6 +113,7 @@ #include "code\__DEFINES\vv.dm" #include "code\__DEFINES\wall_dents.dm" #include "code\__DEFINES\wires.dm" +#include "code\__DEFINES\wounds.dm" #include "code\__DEFINES\dcs\flags.dm" #include "code\__DEFINES\dcs\helpers.dm" #include "code\__DEFINES\dcs\signals.dm" @@ -615,6 +616,7 @@ #include "code\datums\status_effects\gas.dm" #include "code\datums\status_effects\neutral.dm" #include "code\datums\status_effects\status_effect.dm" +#include "code\datums\status_effects\wound_effects.dm" #include "code\datums\traits\_quirk.dm" #include "code\datums\traits\good.dm" #include "code\datums\traits\negative.dm" @@ -643,6 +645,11 @@ #include "code\datums\wires\syndicatebomb.dm" #include "code\datums\wires\tesla_coil.dm" #include "code\datums\wires\vending.dm" +#include "code\datums\wounds\_wounds.dm" +#include "code\datums\wounds\bones.dm" +#include "code\datums\wounds\burns.dm" +#include "code\datums\wounds\cuts.dm" +#include "code\datums\wounds\scars\_scars.dm" #include "code\game\alternate_appearance.dm" #include "code\game\atoms.dm" #include "code\game\atoms_movable.dm" @@ -2954,7 +2961,9 @@ #include "code\modules\station_goals\shield.dm" #include "code\modules\station_goals\station_goal.dm" #include "code\modules\surgery\amputation.dm" +#include "code\modules\surgery\bone_mending.dm" #include "code\modules\surgery\brain_surgery.dm" +#include "code\modules\surgery\burn_dressing.dm" #include "code\modules\surgery\cavity_implant.dm" #include "code\modules\surgery\core_removal.dm" #include "code\modules\surgery\coronary_bypass.dm" @@ -2995,10 +3004,11 @@ #include "code\modules\surgery\advanced\bioware\nerve_grounding.dm" #include "code\modules\surgery\advanced\bioware\nerve_splicing.dm" #include "code\modules\surgery\advanced\bioware\vein_threading.dm" -#include "code\modules\surgery\bodyparts\bodyparts.dm" +#include "code\modules\surgery\bodyparts\_bodyparts.dm" #include "code\modules\surgery\bodyparts\dismemberment.dm" #include "code\modules\surgery\bodyparts\head.dm" #include "code\modules\surgery\bodyparts\helpers.dm" +#include "code\modules\surgery\bodyparts\parts.dm" #include "code\modules\surgery\bodyparts\robot_bodyparts.dm" #include "code\modules\surgery\organs\appendix.dm" #include "code\modules\surgery\organs\augments_arms.dm"