From 8360bb1a7f52b651edf1bfefdd93a64dd792be96 Mon Sep 17 00:00:00 2001 From: timothyteakettle <59849408+timothyteakettle@users.noreply.github.com> Date: Fri, 24 Jul 2020 23:44:57 +0100 Subject: [PATCH] section 2 --- code/modules/cargo/packs/medical.dm | 2 +- code/modules/hydroponics/grown/banana.dm | 6 + code/modules/mob/living/living_defense.dm | 15 +- .../ninja/suit/n_suit_verbs/ninja_stars.dm | 2 +- code/modules/paperwork/pen.dm | 1 + .../projectiles/boxes_magazines/ammo_boxes.dm | 2 +- code/modules/projectiles/gun.dm | 3 +- code/modules/projectiles/projectile.dm | 36 ++- .../modules/projectiles/projectile/bullets.dm | 10 +- .../projectiles/projectile/bullets/lmg.dm | 10 +- .../projectiles/projectile/bullets/pistol.dm | 2 + .../projectile/bullets/revolver.dm | 16 +- .../projectiles/projectile/bullets/rifle.dm | 3 + .../projectiles/projectile/bullets/shotgun.dm | 23 +- .../projectiles/projectile/bullets/smg.dm | 6 + .../chemistry/reagents/drink_reagents.dm | 21 +- .../chemistry/reagents/medicine_reagents.dm | 69 ++++- .../chemistry/reagents/other_reagents.dm | 8 + .../reagents/chemistry/recipes/medicine.dm | 12 + .../reagents/reagent_containers/hypospray.dm | 2 +- .../reagents/reagent_containers/syringes.dm | 1 + code/modules/surgery/bodyparts/_bodyparts.dm | 253 ++++++++++++++---- .../surgery/bodyparts/dismemberment.dm | 61 ++++- code/modules/surgery/bodyparts/head.dm | 3 +- code/modules/surgery/bodyparts/parts.dm | 2 +- code/modules/surgery/burn_dressing.dm | 3 +- code/modules/surgery/repair_puncture.dm | 108 ++++++++ code/modules/vending/_vending.dm | 3 +- interface/stylesheet.dm | 7 +- sound/effects/{ => wounds}/blood1.ogg | Bin sound/effects/{ => wounds}/blood2.ogg | Bin sound/effects/{ => wounds}/blood3.ogg | Bin sound/effects/{ => wounds}/crack1.ogg | Bin sound/effects/{ => wounds}/crack2.ogg | Bin sound/effects/wounds/crackandbleed.ogg | Bin 0 -> 15662 bytes sound/effects/wounds/pierce1.ogg | Bin 0 -> 8726 bytes sound/effects/wounds/pierce2.ogg | Bin 0 -> 17779 bytes sound/effects/wounds/pierce3.ogg | Bin 0 -> 19758 bytes sound/effects/{ => wounds}/sizzle1.ogg | Bin sound/effects/{ => wounds}/sizzle2.ogg | Bin strings/wounds/bone_scar_desc.json | 26 ++ strings/wounds/flesh_scar_desc.json | 86 ++++++ strings/wounds/scar_loc.json | 52 ++++ tgstation.dme | 5 +- 44 files changed, 760 insertions(+), 99 deletions(-) create mode 100644 code/modules/surgery/repair_puncture.dm rename sound/effects/{ => wounds}/blood1.ogg (100%) rename sound/effects/{ => wounds}/blood2.ogg (100%) rename sound/effects/{ => wounds}/blood3.ogg (100%) rename sound/effects/{ => wounds}/crack1.ogg (100%) rename sound/effects/{ => wounds}/crack2.ogg (100%) create mode 100644 sound/effects/wounds/crackandbleed.ogg create mode 100644 sound/effects/wounds/pierce1.ogg create mode 100644 sound/effects/wounds/pierce2.ogg create mode 100644 sound/effects/wounds/pierce3.ogg rename sound/effects/{ => wounds}/sizzle1.ogg (100%) rename sound/effects/{ => wounds}/sizzle2.ogg (100%) create mode 100644 strings/wounds/bone_scar_desc.json create mode 100644 strings/wounds/flesh_scar_desc.json create mode 100644 strings/wounds/scar_loc.json diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm index ce66fc52d5..6a4165f840 100644 --- a/code/modules/cargo/packs/medical.dm +++ b/code/modules/cargo/packs/medical.dm @@ -230,6 +230,6 @@ /obj/item/reagent_containers/hypospray/medipen/ekit, /obj/item/reagent_containers/hypospray/medipen/blood_loss, /obj/item/reagent_containers/hypospray/medipen/blood_loss, - /obj/item/reagent_containers/hypospray/medipen/blood_loss + /obj/item/reagent_containers/hypospray/medipen/blood_loss) crate_name = "medipen crate" diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index 0411a80443..81318f8fe1 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -27,6 +27,12 @@ juice_results = list(/datum/reagent/consumable/banana = 0) distill_reagent = /datum/reagent/consumable/ethanol/bananahonk +/obj/item/reagent_containers/food/snacks/grown/banana/generate_trash(atom/location) + . = ..() + var/obj/item/grown/bananapeel/peel = . + if(istype(peel)) + peel.grind_results = list(/datum/reagent/consumable/banana_peel = seed.potency * 0.2) + /obj/item/reagent_containers/food/snacks/grown/banana/suicide_act(mob/user) user.visible_message("[user] is aiming [src] at [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/items/bikehorn.ogg', 50, 1, -1) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index e24e9641bf..bc88a048ea 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -85,7 +85,7 @@ totaldamage = block_calculate_resultant_damage(totaldamage, returnlist) var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null) if(!P.nodamage) - apply_damage(totaldamage, P.damage_type, def_zone, armor, wound_bonus=P.wound_bonus, bare_wound_bonus=P.bare_wound_bonus, sharpness=P.sharpness) + apply_damage(totaldamage, P.damage_type, def_zone, armor, wound_bonus = P.wound_bonus, bare_wound_bonus = P.bare_wound_bonus, sharpness = P.sharpness) if(P.dismemberment) check_projectile_dismemberment(P, def_zone) var/missing = 100 - final_percent @@ -135,12 +135,13 @@ dtype = I.damtype if(!blocked) - visible_message("[src] has been hit by [I].", \ - "You have been hit by [I].") - var/armor = run_armor_check(impacting_zone, "melee", "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration) - apply_damage(total_damage, dtype, impacting_zone, armor, sharpness=I.sharpness) - if(I.thrownby) - log_combat(I.thrownby, src, "threw and hit", I) + if(!nosell_hit) + visible_message("[src] is hit by [I]!", \ + "You're hit by [I]!") + 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, sharpness=I.get_sharpness(), wound_bonus=(nosell_hit * CANT_WOUND)) else return 1 else diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm index 508722ecf2..57faad9493 100644 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm @@ -14,5 +14,5 @@ /obj/item/throwing_star/ninja name = "ninja throwing star" - throwforce = 30 + throwforce = 20 embedding = list("pain_mult" = 6, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 77ff8e9d8d..997ada6b21 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -28,6 +28,7 @@ var/degrees = 0 var/font = PEN_FONT embedding = list() + sharpness = SHARP_POINTY /obj/item/pen/suicide_act(mob/user) user.visible_message("[user] is scribbling numbers all over [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit sudoku...") diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm index e4674f4f4c..987efc0404 100644 --- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm +++ b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm @@ -47,7 +47,7 @@ /obj/item/ammo_box/c38/dumdum name = "speed loader (.38 DumDum)" - desc = "Designed to quickly reload revolvers. DumDum bullets shatter on impact and shred the target's innards, likely getting caught inside." + desc = "Designed to quickly reload revolvers. These rounds expand on impact, allowing them to shred the target and cause massive bleeding. Very weak against armor and distant targets." ammo_type = /obj/item/ammo_casing/c38/dumdum /obj/item/ammo_box/c38/match diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index f34343debd..679f80dcc1 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -186,7 +186,8 @@ return if(iscarbon(target)) var/mob/living/carbon/C = target - for(var/datum/wound/W in C.all_wounds) + for(var/i in C.all_wounds) + var/datum/wound/W = i if(W.try_treating(src, user)) return // another coward cured! diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 199842d8e2..cb9a758e3f 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -149,19 +149,28 @@ var/temporary_unstoppable_movement = FALSE - ///If defined, on hit we create an item of this type then call hitby() on the hit target with this + ///If defined, on hit we create an item of this type then call hitby() on the hit target with this, mainly used for embedding items (bullets) in targets var/shrapnel_type ///If TRUE, hit mobs even if they're on the floor and not our target var/hit_stunned_targets = FALSE wound_bonus = CANT_WOUND + ///How much we want to drop both wound_bonus and bare_wound_bonus (to a minimum of 0 for the latter) per tile, for falloff purposes + var/wound_falloff_tile + ///How much we want to drop the embed_chance value, if we can embed, per tile, for falloff purposes + var/embed_falloff_tile /// For telling whether we want to roll for bone breaking or lacerations if we're bothering with wounds sharpness = SHARP_NONE + ///If we have a shrapnel_type defined, these embedding stats will be passed to the spawned shrapnel type, which will roll for embedding on the target + var/list/embedding + /obj/item/projectile/Initialize() . = ..() permutated = list() decayedRange = range + if(embedding) + updateEmbedding() /** * Artificially modified to be called at around every world.icon_size pixels of movement. @@ -169,6 +178,11 @@ */ /obj/item/projectile/proc/Range() range-- + if(wound_bonus != CANT_WOUND) + wound_bonus += wound_falloff_tile + bare_wound_bonus = max(0, bare_wound_bonus + wound_falloff_tile) + if(embedding) + embedding["embed_chance"] += embed_falloff_tile if(range <= 0 && loc) on_range() @@ -815,6 +829,26 @@ /obj/item/projectile/experience_pressure_difference() return +///Like [/obj/item/proc/updateEmbedding] but for projectiles instead, call this when you want to add embedding or update the stats on the embedding element +/obj/projectile/proc/updateEmbedding() + if(!shrapnel_type || !LAZYLEN(embedding)) + return + + AddElement(/datum/element/embed,\ + embed_chance = (!isnull(embedding["embed_chance"]) ? embedding["embed_chance"] : EMBED_CHANCE),\ + fall_chance = (!isnull(embedding["fall_chance"]) ? embedding["fall_chance"] : EMBEDDED_ITEM_FALLOUT),\ + pain_chance = (!isnull(embedding["pain_chance"]) ? embedding["pain_chance"] : EMBEDDED_PAIN_CHANCE),\ + pain_mult = (!isnull(embedding["pain_mult"]) ? embedding["pain_mult"] : EMBEDDED_PAIN_MULTIPLIER),\ + remove_pain_mult = (!isnull(embedding["remove_pain_mult"]) ? embedding["remove_pain_mult"] : EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER),\ + rip_time = (!isnull(embedding["rip_time"]) ? embedding["rip_time"] : EMBEDDED_UNSAFE_REMOVAL_TIME),\ + ignore_throwspeed_threshold = (!isnull(embedding["ignore_throwspeed_threshold"]) ? embedding["ignore_throwspeed_threshold"] : FALSE),\ + impact_pain_mult = (!isnull(embedding["impact_pain_mult"]) ? embedding["impact_pain_mult"] : EMBEDDED_IMPACT_PAIN_MULTIPLIER),\ + jostle_chance = (!isnull(embedding["jostle_chance"]) ? embedding["jostle_chance"] : EMBEDDED_JOSTLE_CHANCE),\ + jostle_pain_mult = (!isnull(embedding["jostle_pain_mult"]) ? embedding["jostle_pain_mult"] : EMBEDDED_JOSTLE_PAIN_MULTIPLIER),\ + pain_stam_pct = (!isnull(embedding["pain_stam_pct"]) ? embedding["pain_stam_pct"] : EMBEDDED_PAIN_STAM_PCT),\ + projectile_payload = shrapnel_type) + return TRUE + /////// MISC HELPERS //////// /// Is this atom reflectable with ""standardized"" reflection methods like you know eshields and deswords and similar /proc/is_energy_reflectable_projectile(atom/A) diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index bc0030afc3..9fb7e83577 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -8,4 +8,12 @@ flag = "bullet" hitsound_wall = "ricochet" impact_effect_type = /obj/effect/temp_visual/impact_effect - sharpness = SHARP_EDGED \ No newline at end of file + sharpness = SHARP_POINTY + shrapnel_type = /obj/item/shrapnel/bullet + embedding = list(embed_chance=15, fall_chance=2, jostle_chance=0, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.5, pain_mult=3, rip_time=10) + wound_falloff_tile = -5 + embed_falloff_tile = -5 + +/obj/projectile/bullet/smite + name = "divine retribution" + damage = 10 diff --git a/code/modules/projectiles/projectile/bullets/lmg.dm b/code/modules/projectiles/projectile/bullets/lmg.dm index 2ea1fe7c9a..e3eff6dcb0 100644 --- a/code/modules/projectiles/projectile/bullets/lmg.dm +++ b/code/modules/projectiles/projectile/bullets/lmg.dm @@ -25,8 +25,10 @@ /obj/item/projectile/bullet/mm195x129 name = "1.95x129mm bullet" - damage = 45 + damage = 40 armour_penetration = 5 + wound_bonus = -50 + wound_falloff_tile = 0 /obj/item/projectile/bullet/mm195x129_ap name = "1.95x129mm armor-piercing bullet" @@ -35,8 +37,12 @@ /obj/item/projectile/bullet/mm195x129_hp name = "1.95x129mm hollow-point bullet" - damage = 60 + damage = 50 armour_penetration = -60 + sharpness = SHARP_EDGED + wound_bonus = -40 + bare_wound_bonus = 30 + wound_falloff_tile = -8 /obj/item/projectile/bullet/incendiary/mm195x129 name = "1.95x129mm incendiary bullet" diff --git a/code/modules/projectiles/projectile/bullets/pistol.dm b/code/modules/projectiles/projectile/bullets/pistol.dm index 38c9c9f7d9..23a749415c 100644 --- a/code/modules/projectiles/projectile/bullets/pistol.dm +++ b/code/modules/projectiles/projectile/bullets/pistol.dm @@ -3,11 +3,13 @@ /obj/item/projectile/bullet/c9mm name = "9mm bullet" damage = 20 + embedding = list(embed_chance=15, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) /obj/item/projectile/bullet/c9mm_ap name = "9mm armor-piercing bullet" damage = 15 armour_penetration = 40 + embedding = null /obj/item/projectile/bullet/incendiary/c9mm name = "9mm incendiary bullet" diff --git a/code/modules/projectiles/projectile/bullets/revolver.dm b/code/modules/projectiles/projectile/bullets/revolver.dm index c61ce57c1d..95d43ba1ce 100644 --- a/code/modules/projectiles/projectile/bullets/revolver.dm +++ b/code/modules/projectiles/projectile/bullets/revolver.dm @@ -19,8 +19,9 @@ ricochet_chance = 50 ricochet_auto_aim_angle = 10 ricochet_auto_aim_range = 3 - wound_bonus = -35 - sharpness = SHARP_EDGED + wound_bonus = -20 + bare_wound_bonus = 10 + embedding = list(embed_chance=15, fall_chance=2, jostle_chance=2, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=3, jostle_pain_mult=5, rip_time=10) /obj/item/projectile/bullet/c38/match name = ".38 Match bullet" @@ -43,13 +44,21 @@ ricochet_chance = 130 ricochet_decay_damage = 0.8 shrapnel_type = NONE + sharpness = SHARP_NONE + embedding = null +// premium .38 ammo from cargo, weak against armor, lower base damage, but excellent at embedding and causing slice wounds at close range /obj/item/projectile/bullet/c38/dumdum name = ".38 DumDum bullet" damage = 15 armour_penetration = -30 ricochets_max = 0 - shrapnel_type = /obj/item/shrapnel/bullet/c38/dumdum + sharpness = SHARP_EDGED + wound_bonus = 20 + bare_wound_bonus = 20 + embedding = list(embed_chance=75, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) + wound_falloff_tile = -5 + embed_falloff_tile = -15 /obj/item/projectile/bullet/c38/rubber name = ".38 rubber bullet" @@ -102,6 +111,7 @@ /obj/item/projectile/bullet/a357 name = ".357 bullet" damage = 60 + wound_bonus = -70 /obj/item/projectile/bullet/a357/ap name = ".357 armor-piercing bullet" diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm index ae1611cb00..ce30f5e787 100644 --- a/code/modules/projectiles/projectile/bullets/rifle.dm +++ b/code/modules/projectiles/projectile/bullets/rifle.dm @@ -3,12 +3,15 @@ /obj/item/projectile/bullet/a556 name = "5.56mm bullet" damage = 35 + wound_bonus = -40 // 7.62 (Nagant Rifle) /obj/item/projectile/bullet/a762 name = "7.62 bullet" damage = 60 + wound_bonus = -35 + wound_falloff_tile = 0 /obj/item/projectile/bullet/a762_enchanted name = "enchanted 7.62 bullet" diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm index cc98331004..69f976d213 100644 --- a/code/modules/projectiles/projectile/bullets/shotgun.dm +++ b/code/modules/projectiles/projectile/bullets/shotgun.dm @@ -1,16 +1,18 @@ /obj/item/projectile/bullet/shotgun_slug name = "12g shotgun slug" - damage = 60 + damage = 50 + sharpness = SHARP_POINTY + wound_bonus = 0 /obj/item/projectile/bullet/shotgun_slug/executioner name = "executioner slug" // admin only, can dismember limbs sharpness = SHARP_EDGED - wound_bonus = 0 + wound_bonus = 80 /obj/item/projectile/bullet/shotgun_slug/pulverizer name = "pulverizer slug" // admin only, can crush bones sharpness = SHARP_NONE - wound_bonus = 0 + wound_bonus = 80 /obj/item/projectile/bullet/shotgun_beanbag name = "beanbag slug" @@ -18,6 +20,7 @@ stamina = 70 wound_bonus = 20 sharpness = SHARP_NONE + embedding = null /obj/item/projectile/bullet/incendiary/shotgun name = "incendiary slug" @@ -83,18 +86,22 @@ return BULLET_ACT_HIT /obj/item/projectile/bullet/pellet - var/tile_dropoff = 0.75 + var/tile_dropoff = 0.45 var/tile_dropoff_s = 1.25 /obj/item/projectile/bullet/pellet/shotgun_buckshot name = "buckshot pellet" - damage = 12.5 - wound_bonus = -10 + damage = 7.5 + wound_bonus = 5 + bare_wound_bonus = 5 + wound_falloff_tile = -2.5 // low damage + additional dropoff will already curb wounding potential anything past point blank /obj/item/projectile/bullet/pellet/shotgun_rubbershot name = "rubbershot pellet" damage = 2 stamina = 15 + sharpness = SHARP_NONE + embedding = null /obj/item/projectile/bullet/pellet/Range() ..() @@ -106,8 +113,10 @@ qdel(src) /obj/item/projectile/bullet/pellet/shotgun_improvised - tile_dropoff = 0.55 //Come on it does 6 damage don't be like that. + tile_dropoff = 0.35 //Come on it does 6 damage don't be like that. damage = 6 + wound_bonus = 0 + bare_wound_bonus = 7.5 /obj/item/projectile/bullet/pellet/shotgun_improvised/Initialize() . = ..() diff --git a/code/modules/projectiles/projectile/bullets/smg.dm b/code/modules/projectiles/projectile/bullets/smg.dm index eb4c8e9776..5c9d5b92a3 100644 --- a/code/modules/projectiles/projectile/bullets/smg.dm +++ b/code/modules/projectiles/projectile/bullets/smg.dm @@ -3,6 +3,8 @@ /obj/item/projectile/bullet/c45 name = ".45 bullet" damage = 30 + wound_bonus = -10 + wound_falloff_tile = -10 /obj/item/projectile/bullet/c45_cleaning name = ".45 bullet" @@ -51,11 +53,15 @@ /obj/item/projectile/bullet/c46x30mm name = "4.6x30mm bullet" damage = 15 + wound_bonus = -5 + bare_wound_bonus = 5 + embed_falloff_tile = -4 /obj/item/projectile/bullet/c46x30mm_ap name = "4.6x30mm armor-piercing bullet" damage = 12.5 armour_penetration = 40 + embedding = null /obj/item/projectile/bullet/incendiary/c46x30mm name = "4.6x30mm incendiary bullet" diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index d76f6af165..6b933ce759 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -1016,4 +1016,23 @@ if(M.getToxLoss() && prob(30)) M.adjustToxLoss(-1, 0) ..() - . = TRUE \ No newline at end of file + . = TRUE + +// i googled "natural coagulant" and a couple of results came up for banana peels, so after precisely 30 more seconds of research, i now dub grinding banana peels good for your blood +/datum/reagent/consumable/banana_peel + name = "Pulped Banana Peel" + description = "Okay, so you put a banana peel in a grinder... Why, exactly?" + color = "#863333" // rgb: 175, 175, 0 + reagent_state = SOLID + taste_description = "stringy, bitter pulp" + glass_name = "glass of banana peel pulp" + glass_desc = "Okay, so you put a banana peel in a grinder... Why, exactly?" + +/datum/reagent/consumable/baked_banana_peel + name = "Baked Banana Peel Powder" + description = "You took a banana peel... pulped it... baked it... Where are you going with this?" + color = "#863333" // rgb: 175, 175, 0 + reagent_state = SOLID + taste_description = "bitter powder" + glass_name = "glass of banana peel powder" + description = "You took a banana peel... pulped it... baked it... Where are you going with this?" diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 050b1f29b5..60f86283c0 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -145,8 +145,8 @@ 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) + var/datum/wound/iter_wound = i + iter_wound.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) @@ -196,8 +196,8 @@ 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) + var/datum/wound/iter_wound = i + iter_wound.on_xadone(power) REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) . = 1 ..() @@ -365,7 +365,7 @@ /datum/reagent/medicine/salglu_solution name = "Saline-Glucose Solution" - description = "Has a 33% chance per metabolism cycle to heal brute and burn damage. Can be used as a temporary blood substitute." + description = "Has a 33% chance per metabolism cycle to heal brute and burn damage. Can be used as a temporary blood substitute, as well as slowly speeding blood regeneration." reagent_state = LIQUID color = "#DCDCDC" metabolization_rate = 0.5 * REAGENTS_METABOLISM @@ -373,6 +373,7 @@ taste_description = "sweetness and salt" var/last_added = 0 var/maximum_reachable = BLOOD_VOLUME_NORMAL - 10 //So that normal blood regeneration can continue with salglu active + var/extra_regen = 0.25 // in addition to acting as temporary blood, also add this much to their actual blood per tick pH = 5.5 /datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/carbon/M) @@ -385,7 +386,7 @@ var/amount_to_add = min(M.blood_volume, volume*5) var/new_blood_level = min(M.blood_volume + amount_to_add, maximum_reachable) last_added = new_blood_level - M.blood_volume - M.blood_volume = new_blood_level + M.blood_volume = new_blood_level + extra_regen if(prob(33)) M.adjustBruteLoss(-0.5*REM, 0) M.adjustFireLoss(-0.5*REM, 0) @@ -471,8 +472,9 @@ else if(method in list(PATCH, TOUCH)) M.adjustBruteLoss(-1 * reac_volume) M.adjustFireLoss(-1 * reac_volume) - for(var/datum/wound/burn/burn_wound in C.all_wounds) - burn_wound.regenerate_flesh(reac_volume) + for(var/i in carbies.all_wounds) + var/datum/wound/iter_wound = i + iter_wound.on_synthflesh(reac_volume) if(show_message) to_chat(M, "You feel your burns and bruises healing! It stings like hell!") SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine) @@ -1592,10 +1594,57 @@ to_chat(C, "[pick(GLOB.wisdoms)]") //give them a random wisdom ..() -// handled in cut wounds process +// helps bleeding wounds clot faster /datum/reagent/medicine/coagulant name = "Sanguirite" - description = "A coagulant used to help open cuts clot faster." + description = "A proprietary coagulant used to help bleeding wounds clot faster." reagent_state = LIQUID color = "#bb2424" metabolization_rate = 0.25 * REAGENTS_METABOLISM + +overdose_threshold = 20 + /// How much base clotting we do per bleeding wound, multiplied by the below number for each bleeding wound + var/clot_rate = 0.25 + /// If we have multiple bleeding wounds, we count the number of bleeding wounds, then multiply the clot rate by this^(n) before applying it to each cut, so more cuts = less clotting per cut (though still more total clotting) + var/clot_coeff_per_wound = 0.9 + +/datum/reagent/medicine/coagulant/on_mob_life(mob/living/carbon/M) + . = ..() + if(!M.blood_volume || !M.all_wounds) + return + + var/effective_clot_rate = clot_rate + + for(var/i in M.all_wounds) + var/datum/wound/iter_wound = i + if(iter_wound.blood_flow) + effective_clot_rate *= clot_coeff_per_wound + + for(var/i in M.all_wounds) + var/datum/wound/iter_wound = i + iter_wound.blood_flow = max(0, iter_wound.blood_flow - effective_clot_rate) + +/datum/reagent/medicine/coagulant/overdose_process(mob/living/M) + . = ..() + if(!M.blood_volume) + return + + if(prob(15)) + M.losebreath += rand(2,4) + M.adjustOxyLoss(rand(1,3)) + if(prob(30)) + to_chat(M, "You can feel your blood clotting up in your veins!") + else if(prob(10)) + to_chat(M, "You feel like your blood has stopped moving!") + if(prob(50)) + var/obj/item/organ/lungs/our_lungs = M.getorganslot(ORGAN_SLOT_LUNGS) + our_lungs.applyOrganDamage(1) + else + var/obj/item/organ/heart/our_heart = M.getorganslot(ORGAN_SLOT_HEART) + our_heart.applyOrganDamage(1) + +// can be synthesized on station rather than bought. made by grinding a banana peel, heating it up, then mixing the banana peel powder with salglu +/datum/reagent/medicine/coagulant/weak + name = "Synthi-Sanguirite" + description = "A synthetic coagulant used to help bleeding wounds clot faster. Not quite as effective as name brand Sanguirite, especially on patients with lots of cuts." + clot_coeff_per_wound = 0.8 diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 5c5821381e..5b6418779b 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -244,6 +244,11 @@ glass_desc = "The father of all refreshments." shot_glass_icon_state = "shotglassclear" +/datum/reagent/water/on_mob_life(mob/living/carbon/M) + . = ..() + if(M.blood_volume) + M.blood_volume += 0.1 // water is good for you! + /* * Water reaction to turf */ @@ -334,6 +339,8 @@ return ..() /datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M) + if(M.blood_volume) + M.blood_volume += 0.1 // water is good for you! if(!data) data = list("misc" = 1) data["misc"]++ @@ -2304,6 +2311,7 @@ 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 + self_consuming = TRUE /datum/reagent/determination/on_mob_end_metabolize(mob/living/carbon/M) if(significant) diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index e591daeb8e..bb9a951cac 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -50,6 +50,18 @@ results = list(/datum/reagent/medicine/salglu_solution = 3) required_reagents = list(/datum/reagent/consumable/sodiumchloride = 1, /datum/reagent/water = 1, /datum/reagent/consumable/sugar = 1) +/datum/chemical_reaction/baked_banana_peel + results = list(/datum/reagent/consumable/baked_banana_peel = 1) + required_temp = 413.15 // if it's good enough for caramel it's good enough for this + required_reagents = list(/datum/reagent/consumable/banana_peel = 1) + mix_message = "The pulp dries up and takes on a powdery state!" + mob_react = FALSE + +/datum/chemical_reaction/coagulant_weak + results = list(/datum/reagent/medicine/coagulant/weak = 3) + required_reagents = list(/datum/reagent/medicine/salglu_solution = 2, /datum/reagent/consumable/baked_banana_peel = 1) + mob_react = FALSE + /datum/chemical_reaction/mine_salve name = "Miner's Salve" id = /datum/reagent/medicine/mine_salve diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 7dcf996cab..f37210ad1c 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -135,7 +135,7 @@ /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." + desc = "An epinephrine medipen with extra coagulant 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/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 4ab1470667..4b73ebde4a 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -16,6 +16,7 @@ custom_materials = list(/datum/material/iron=10, /datum/material/glass=20) reagent_flags = TRANSPARENT custom_price = PRICE_CHEAP_AS_FREE + sharpness = SHARP_POINTY /obj/item/reagent_containers/syringe/Initialize() . = ..() diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index bcf1bc8e0a..c79f50c03c 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -86,12 +86,12 @@ /// 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 + /// If we have a gauze wrapping currently applied (not including splints) + var/obj/item/stack/current_gauze /obj/item/bodypart/examine(mob/user) . = ..() @@ -151,8 +151,20 @@ var/turf/T = get_turf(src) if(status != BODYPART_ROBOTIC) playsound(T, 'sound/misc/splort.ogg', 50, 1, -1) - for(var/obj/item/I in src) - I.forceMove(T) + if(current_gauze) + QDEL_NULL(current_gauze) + for(var/obj/item/organ/drop_organ in get_organs()) + drop_organ.transfer_to_limb(src, owner) + +///since organs aren't actually stored in the bodypart themselves while attached to a person, we have to query the owner for what we should have +/obj/item/bodypart/proc/get_organs() + if(!owner) + return + . = list() + for(var/i in owner.internal_organs) //internal organs inside the dismembered limb are dropped. + var/obj/item/organ/organ_check = i + if(check_zone(organ_check.zone) == body_zone) + . += organ_check /obj/item/bodypart/proc/consider_processing() if(stamina_dam > DAMAGE_PRECISION) @@ -192,16 +204,64 @@ if(ALIEN_BODYPART,LARVA_BODYPART) //aliens take some additional burn //nothing can burn with so much snowflake code around burn *= 1.2 - var/wounding_type = (brute > burn ? WOUND_BRUTE : WOUND_BURN) + /* + // START WOUND HANDLING + */ + + // what kind of wounds we're gonna roll for, take the greater between brute and burn, then if it's brute, we subdivide based on sharpness + var/wounding_type = (brute > burn ? WOUND_BLUNT : 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 + var/mangled_state = get_mangled_state() + var/bio_state = owner.get_biological_state() + var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%) + + if(wounding_type == WOUND_BLUNT) + if(sharpness == SHARP_EDGED) + wounding_type = WOUND_SLASH + else if(sharpness == SHARP_POINTY) + wounding_type = WOUND_PIERCE + + //Handling for bone only/flesh only(none right now)/flesh and bone targets + switch(bio_state) + // if we're bone only, all cutting attacks go straight to the bone + if(BIO_JUST_BONE) + if(wounding_type == WOUND_SLASH) + wounding_type = WOUND_BLUNT + wounding_dmg *= (easy_dismember ? 1 : 0.5) + else if(wounding_type == WOUND_PIERCE) + wounding_type = WOUND_BLUNT + wounding_dmg *= (easy_dismember ? 1 : 0.75) + if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)) + return + // note that there's no handling for BIO_JUST_FLESH since we don't have any that are that right now (slimepeople maybe someday) + // standard humanoids + if(BIO_FLESH_BONE) + // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate + // So a big sharp weapon is still all you need to destroy a limb + if(mangled_state == BODYPART_MANGLED_FLESH && sharpness) + playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100) + if(wounding_type == WOUND_SLASH && !easy_dismember) + wounding_dmg *= 0.5 // edged weapons pass along 50% of their wounding damage to the bone since the power is spread out over a larger area + if(wounding_type == WOUND_PIERCE && !easy_dismember) + wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated + wounding_type = WOUND_BLUNT + else if(mangled_state == BODYPART_MANGLED_BOTH && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)) + return + + // now we have our wounding_type and are ready to carry on with wounds and dealing the actual damage + if(owner && wounding_dmg >= WOUND_MINIMUM_DAMAGE && wound_bonus != CANT_WOUND) check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus) + for(var/i in wounds) + var/datum/wound/iter_wound = i + iter_wound.receive_damage(wounding_type, wounding_dmg, wound_bonus) + + /* + // END WOUND HANDLING + */ + + //back to our regularly scheduled program, we now actually apply damage if there's room below limb damage cap + var/can_inflict = max_damage - get_damage() var/total_damage = brute + burn @@ -213,10 +273,6 @@ if(can_inflict <= 0) return FALSE - for(var/i in wounds) - var/datum/wound/W = i - W.receive_damage(wounding_type, wounding_dmg, wound_bonus) - brute_dam += brute burn_dam += burn @@ -236,14 +292,58 @@ update_disabled() return update_bodypart_damage_state() +/// Allows us to roll for and apply a wound without actually dealing damage. Used for aggregate wounding power with pellet clouds +/obj/item/bodypart/proc/painless_wound_roll(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus, sharpness=SHARP_NONE) + if(!owner || phantom_wounding_dmg <= WOUND_MINIMUM_DAMAGE || wound_bonus == CANT_WOUND) + return + + var/mangled_state = get_mangled_state() + var/bio_state = owner.get_biological_state() + var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%) + + if(wounding_type == WOUND_BLUNT) + if(sharpness == SHARP_EDGED) + wounding_type = WOUND_SLASH + else if(sharpness == SHARP_POINTY) + wounding_type = WOUND_PIERCE + + //Handling for bone only/flesh only(none right now)/flesh and bone targets + switch(bio_state) + // if we're bone only, all cutting attacks go straight to the bone + if(BIO_JUST_BONE) + if(wounding_type == WOUND_SLASH) + wounding_type = WOUND_BLUNT + phantom_wounding_dmg *= (easy_dismember ? 1 : 0.5) + else if(wounding_type == WOUND_PIERCE) + wounding_type = WOUND_BLUNT + phantom_wounding_dmg *= (easy_dismember ? 1 : 0.75) + if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus)) + return + // note that there's no handling for BIO_JUST_FLESH since we don't have any that are that right now (slimepeople maybe someday) + // standard humanoids + if(BIO_FLESH_BONE) + // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate + // So a big sharp weapon is still all you need to destroy a limb + if(mangled_state == BODYPART_MANGLED_FLESH && sharpness) + playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100) + if(wounding_type == WOUND_SLASH && !easy_dismember) + phantom_wounding_dmg *= 0.5 // edged weapons pass along 50% of their wounding damage to the bone since the power is spread out over a larger area + if(wounding_type == WOUND_PIERCE && !easy_dismember) + phantom_wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated + wounding_type = WOUND_BLUNT + else if(mangled_state == BODYPART_MANGLED_BOTH && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus)) + return + + check_wounding(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus) + /** * 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 generate a "score" for how woundable the attack was based on the damage and other factors discussed in [/obj/item/bodypart/proc/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. + * * woundtype- Either WOUND_BLUNT, WOUND_SLASH, WOUND_PIERCE, 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 @@ -252,19 +352,24 @@ // actually roll wounds if applicable if(HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE)) damage *= 1.5 + else + damage = min(damage, WOUND_MAX_CONSIDERED_DAMAGE) 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 + var/list/wounds_checking = GLOB.global_wound_types[woundtype] - switch(woundtype) - if(WOUND_SHARP) - wounds_checking = WOUND_LIST_SLASH - if(WOUND_BRUTE) - wounds_checking = WOUND_LIST_BLUNT - if(WOUND_BURN) - wounds_checking = WOUND_LIST_BURN + // quick re-check to see if bare_wound_bonus applies, for the benefit of log_wound(), see about getting the check from check_woundings_mods() somehow + if(ishuman(owner)) + var/mob/living/carbon/human/human_wearer = owner + var/list/clothing = human_wearer.clothingonpart(src) + for(var/i in clothing) + var/obj/item/clothing/clothes_check = i + // 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 + if(clothes_check.armor.getRating("wound")) + bare_wound_bonus = 0 + break //cycle through the wounds of the relevant category from the most severe down for(var/PW in wounds_checking) @@ -279,21 +384,22 @@ replaced_wound = existing_wound if(initial(possible_wound.threshold_minimum) < injury_roll) + var/datum/wound/new_wound 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) + new_wound = replaced_wound.replace_wound(possible_wound) + log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll) // dismembering wounds are logged in the apply_wound() for loss wounds since they delete themselves immediately, these will be immediately returned else - var/datum/wound/new_wound = new possible_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 + return new_wound // 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.wound_type == 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 @@ -301,12 +407,20 @@ var/datum/wound/new_wound = new potential_wound new_wound.apply_wound(src, smited = smited) +/** + * check_wounding_mods() is where we handle the various modifiers of a wound roll + * + * A short list of things we consider: any armor a human target may be wearing, and if they have no wound armor on the limb, if we have a bare_wound_bonus to apply, plus the plain wound_bonus + * We also flick through all of the wounds we currently have on this limb and add their threshold penalties, so that having lots of bad wounds makes you more liable to get hurt worse + * Lastly, we add the inherent wound_resistance variable the bodypart has (heads and chests are slightly harder to wound), and a small bonus if the limb is already disabled + * + * Arguments: + * * It's the same ones on [receive_damage] + */ /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) @@ -314,7 +428,7 @@ 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) + if(wounding_type == WOUND_SLASH) 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) @@ -330,7 +444,7 @@ injury_mod += W.threshold_penalty var/part_mod = -wound_resistance - if(is_disabled()) + if(get_damage(TRUE) >= max_damage) part_mod += disabled_wound_penalty injury_mod += part_mod @@ -383,11 +497,11 @@ return BODYPART_DISABLED_WOUND if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NODISMEMBER)) . = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled - 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% + if(get_damage(TRUE) >= max_damage * (HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE) ? 0.6 : 1)) //Easy limb disable disables the limb at 40% health instead of 0% if(!last_maxed) owner.emote("scream") last_maxed = TRUE - if(!is_organic_limb()) + if(!is_organic_limb() || stamina_dam >= max_damage) 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 @@ -741,17 +855,29 @@ /obj/item/bodypart/proc/get_wound_type(checking_type) if(isnull(wounds)) return - for(var/thing in wounds) - var/datum/wound/W = thing - if(istype(W, checking_type)) - return W + for(var/i in wounds) + if(istype(i, checking_type)) + return i -/// 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() +/** + * update_wounds() is called whenever a wound is gained or lost on this bodypart, as well as if there's a change of some kind on a bone wound possibly changing disabled status + * + * Covers tabulating the damage multipliers we have from wounds (burn specifically), as well as deleting our gauze wrapping if we don't have any wounds that can use bandaging + * + * Arguments: + * * replaced- If true, this is being called from the remove_wound() of a wound that's being replaced, so the bandage that already existed is still relevant, but the new wound hasn't been added yet + */ +/obj/item/bodypart/proc/update_wounds(replaced = FALSE) var/dam_mul = 1 //initial(wound_damage_multiplier) // 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 + // we can (normally) only have one wound per type, but remember there's multiple types (smites like :B:loodless can generate multiple cuts on a limb) + for(var/i in wounds) + var/datum/wound/iter_wound = i + dam_mul *= iter_wound.damage_mulitplier_penalty + + if(!LAZYLEN(wounds) && current_gauze && !replaced) + owner.visible_message("\The [current_gauze] on [owner]'s [name] fall away.", "The [current_gauze] on your [name] fall away.") + QDEL_NULL(current_gauze) wound_damage_multiplier = dam_mul update_disabled() @@ -761,8 +887,6 @@ var/bleed_rate = 0 if(generic_bleedstacks > 0) bleed_rate++ - if(brute_dam >= 40) - bleed_rate += (brute_dam * 0.008) //We want an accurate reading of .len listclearnulls(embedded_objects) @@ -773,5 +897,40 @@ for(var/thing in wounds) var/datum/wound/W = thing bleed_rate += W.blood_flow - + if(owner.mobility_flags & ~MOBILITY_STAND) + bleed_rate *= 0.75 return bleed_rate + +/** + * apply_gauze() is used to- well, apply gauze to a bodypart + * + * As of the Wounds 2 PR, all bleeding is now bodypart based rather than the old bleedstacks system, and 90% of standard bleeding comes from flesh wounds (the exception is embedded weapons). + * The same way bleeding is totaled up by bodyparts, gauze now applies to all wounds on the same part. Thus, having a slash wound, a pierce wound, and a broken bone wound would have the gauze + * applying blood staunching to the first two wounds, while also acting as a sling for the third one. Once enough blood has been absorbed or all wounds with the ACCEPTS_GAUZE flag have been cleared, + * the gauze falls off. + * + * Arguments: + * * gauze- Just the gauze stack we're taking a sheet from to apply here + */ +/obj/item/bodypart/proc/apply_gauze(obj/item/stack/gauze) + if(!istype(gauze) || !gauze.absorption_capacity) + return + QDEL_NULL(current_gauze) + current_gauze = new gauze.type(src, 1) + gauze.use(1) + +/** + * seep_gauze() is for when a gauze wrapping absorbs blood or pus from wounds, lowering its absorption capacity. + * + * The passed amount of seepage is deducted from the bandage's absorption capacity, and if we reach a negative absorption capacity, the bandages fall off and we're left with nothing. + * + * Arguments: + * * seep_amt - How much absorption capacity we're removing from our current bandages (think, how much blood or pus are we soaking up this tick?) + */ +/obj/item/bodypart/proc/seep_gauze(seep_amt = 0) + if(!current_gauze) + return + current_gauze.absorption_capacity -= seep_amt + if(current_gauze.absorption_capacity < 0) + owner.visible_message("\The [current_gauze] on [owner]'s [name] fall away in rags.", "\The [current_gauze] on your [name] fall away in rags.", vision_distance=COMBAT_MESSAGE_RANGE) + QDEL_NULL(current_gauze) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 2ce6ca8862..fa003e3f3c 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -4,7 +4,7 @@ return TRUE //Dismember a limb -/obj/item/bodypart/proc/dismember(dam_type = BRUTE) +/obj/item/bodypart/proc/dismember(dam_type = BRUTE, silent=TRUE) if(!owner) return FALSE var/mob/living/carbon/C = owner @@ -16,7 +16,8 @@ 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), wound_bonus=CANT_WOUND) //Damage the chest based on limb's existing damage - C.visible_message("[C]'s [src.name] has been violently dismembered!") + if(!silent) + C.visible_message("[C]'s [name] is violently dismembered!") C.emote("scream") SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered) drop_limb() @@ -30,6 +31,7 @@ burn() return TRUE add_mob_blood(C) + C.bleed(rand(20, 40)) var/direction = pick(GLOB.cardinals) var/t_range = rand(2,max(throw_range/2, 2)) var/turf/target_turf = get_turf(src) @@ -80,8 +82,6 @@ if(organ_spilled) C.visible_message("[C]'s internal organs spill out onto the floor!") - - //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, dismembered) if(!owner) @@ -153,7 +153,52 @@ forceMove(Tsec) +/** + * get_mangled_state() is relevant for flesh and bone bodyparts, and returns whether this bodypart has mangled skin, mangled bone, or both (or neither i guess) + * + * Dismemberment for flesh and bone requires the victim to have the skin on their bodypart destroyed (either a critical cut or piercing wound), and at least a hairline fracture + * (severe bone), at which point we can start rolling for dismembering. The attack must also deal at least 10 damage, and must be a brute attack of some kind (sorry for now, cakehat, maybe later) + * + * Returns: BODYPART_MANGLED_NONE if we're fine, BODYPART_MANGLED_FLESH if our skin is broken, BODYPART_MANGLED_BONE if our bone is broken, or BODYPART_MANGLED_BOTH if both are broken and we're up for dismembering + */ +/obj/item/bodypart/proc/get_mangled_state() + . = BODYPART_MANGLED_NONE + for(var/i in wounds) + var/datum/wound/iter_wound = i + if((iter_wound.wound_flags & MANGLES_BONE)) + . |= BODYPART_MANGLED_BONE + if((iter_wound.wound_flags & MANGLES_FLESH)) + . |= BODYPART_MANGLED_FLESH + +/** + * try_dismember() is used, once we've confirmed that a flesh and bone bodypart has both the skin and bone mangled, to actually roll for it + * + * Mangling is described in the above proc, [/obj/item/bodypart/proc/get_mangled_state()]. This simply makes the roll for whether we actually dismember or not + * using how damaged the limb already is, and how much damage this blow was for. If we have a critical bone wound instead of just a severe, we add +10% to the roll. + * Lastly, we choose which kind of dismember we want based on the wounding type we hit with. Note we don't care about all the normal mods or armor for this + * + * Arguments: + * * wounding_type: Either WOUND_BLUNT, WOUND_SLASH, or WOUND_PIERCE, basically only matters for the dismember message + * * wounding_dmg: The damage of the strike that prompted this roll, higher damage = higher chance + * * wound_bonus: Not actually used right now, but maybe someday + * * bare_wound_bonus: ditto above + */ +/obj/item/bodypart/proc/try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus) + if(wounding_dmg < DISMEMBER_MINIMUM_DAMAGE) + return + + var/base_chance = wounding_dmg + (get_damage() / max_damage * 50) // how much damage we dealt with this blow, + 50% of the damage percentage we already had on this bodypart + if(locate(/datum/wound/blunt/critical) in wounds) // we only require a severe bone break, but if there's a critical bone break, we'll add 10% more + base_chance += 10 + + if(!prob(base_chance)) + return + + var/datum/wound/loss/dismembering = new + dismembering.apply_dismember(src, wounding_type) + + return TRUE //when a limb is dropped, the internal organs are removed from the mob and put into the limb /obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/LB, mob/living/carbon/C) @@ -378,7 +423,7 @@ /mob/living/carbon/regenerate_limb(limb_zone, noheal) var/obj/item/bodypart/L if(get_bodypart(limb_zone)) - return 0 + return FALSE L = newBodyPart(limb_zone, 0, 0) if(L) if(!noheal) @@ -386,6 +431,8 @@ L.burn_dam = 0 L.brutestate = 0 L.burnstate = 0 - + var/datum/scar/scaries = new + var/datum/wound/loss/phantom_loss = new // stolen valor, really + scaries.generate(L, phantom_loss) L.attach_limb(src, 1) - return 1 + return TRUE diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index a67f16b934..13b1140527 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -36,11 +36,10 @@ var/custom_head wound_resistance = 10 - specific_locations = list("left eyebrow", "cheekbone", "neck", "throat", "jawline", "entire face") scars_covered_by_clothes = FALSE /obj/item/bodypart/head/can_dismember(obj/item/I) - if(!((owner.stat == DEAD) || owner.InFullCritical())) + if(owner && !((owner.stat == DEAD) || owner.InFullCritical())) return FALSE return ..() diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index a18b31e4c1..5a887ee6b7 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -12,7 +12,7 @@ var/obj/item/cavity_item /obj/item/bodypart/chest/can_dismember(obj/item/I) - if(!((owner.stat == DEAD) || owner.InFullCritical())) + if(!((owner.stat == DEAD) || owner.InFullCritical()) || !get_organs()) return FALSE return ..() diff --git a/code/modules/surgery/burn_dressing.dm b/code/modules/surgery/burn_dressing.dm index 1688f7b5d1..8bfa52d245 100644 --- a/code/modules/surgery/burn_dressing.dm +++ b/code/modules/surgery/burn_dressing.dm @@ -94,7 +94,8 @@ 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) + var/obj/item/bodypart/the_part = target.get_bodypart(target_zone) + the_part.apply_gauze(tool) else to_chat(user, "[target] has no burns there!") return ..() diff --git a/code/modules/surgery/repair_puncture.dm b/code/modules/surgery/repair_puncture.dm new file mode 100644 index 0000000000..12aefefc82 --- /dev/null +++ b/code/modules/surgery/repair_puncture.dm @@ -0,0 +1,108 @@ + +/////BURN FIXING SURGERIES////// + +//the step numbers of each of these two, we only currently use the first to switch back and forth due to advancing after finishing steps anyway +#define REALIGN_INNARDS 1 +#define WELD_VEINS 2 + +///// Repair puncture wounds +/datum/surgery/repair_puncture + name = "Repair puncture" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/repair_innards, /datum/surgery_step/seal_veins, /datum/surgery_step/close) // repeat between steps 2 and 3 until healed + target_mobtypes = list(/mob/living/carbon) + 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/pierce + +/datum/surgery/repair_puncture/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/pierce_wound = targeted_bodypart.get_wound_type(targetable_wound) + return(pierce_wound && pierce_wound.blood_flow > 0) + +//SURGERY STEPS + +///// realign the blood vessels so we can reweld them +/datum/surgery_step/repair_innards + name = "realign blood vessels" + implements = list(TOOL_HEMOSTAT = 100, TOOL_SCALPEL = 85, TOOL_WIRECUTTER = 40) + time = 3 SECONDS + +/datum/surgery_step/repair_innards/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/datum/wound/pierce/pierce_wound = surgery.operated_wound + if(!pierce_wound) + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + return + + if(pierce_wound.blood_flow <= 0) + to_chat(user, "[target]'s [parse_zone(user.zone_selected)] has no puncture to repair!") + surgery.status++ + return + + display_results(user, target, "You begin to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)].") + +/datum/surgery_step/repair_innards/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + var/datum/wound/pierce/pierce_wound = surgery.operated_wound + if(!pierce_wound) + to_chat(user, "[target] has no puncture wound there!") + return ..() + + display_results(user, target, "You successfully realign some of the blood vessels in [target]'s [parse_zone(target_zone)].", + "[user] successfully realigns some of the blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully realigns some of the blood vessels in [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) + pierce_wound.blood_flow -= 0.25 + return ..() + +/datum/surgery_step/repair_innards/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + . = ..() + display_results(user, target, "You jerk apart some of the blood vessels in [target]'s [parse_zone(target_zone)].", + "[user] jerks apart some of the blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] jerk apart some of the blood vessels in [target]'s [parse_zone(target_zone)]!") + surgery.operated_bodypart.receive_damage(brute=rand(4,8), sharpness=SHARP_EDGED, wound_bonus = 10) + +///// Sealing the vessels back together +/datum/surgery_step/seal_veins + name = "weld veins" // if your doctor says they're going to weld your blood vessels back together, you're either A) on SS13, or B) in grave mortal peril + implements = list(TOOL_CAUTERY = 100, /obj/item/gun/energy/laser = 90, TOOL_WELDER = 70, /obj/item = 30) + time = 4 SECONDS + +/datum/surgery_step/seal_veins/tool_check(mob/user, obj/item/tool) + if(implement_type == TOOL_WELDER || implement_type == /obj/item) + return tool.get_temperature() + + return TRUE + +/datum/surgery_step/seal_veins/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/datum/wound/pierce/pierce_wound = surgery.operated_wound + if(!pierce_wound) + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + return + display_results(user, target, "You begin to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)].") + +/datum/surgery_step/seal_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + var/datum/wound/pierce/pierce_wound = surgery.operated_wound + if(!pierce_wound) + to_chat(user, "[target] has no puncture there!") + return ..() + + display_results(user, target, "You successfully meld some of the split blood vessels in [target]'s [parse_zone(target_zone)] with [tool].", + "[user] successfully melds some of the split blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully melds some of the split blood vessels in [target]'s [parse_zone(target_zone)]!") + log_combat(user, target, "dressed burns in", addition="INTENT: [uppertext(user.a_intent)]") + pierce_wound.blood_flow -= 0.5 + if(pierce_wound.blood_flow > 0) + surgery.status = REALIGN_INNARDS + to_chat(user, "There still seems to be misaligned blood vessels to finish...") + else + to_chat(user, "You've repaired all the internal damage in [target]'s [parse_zone(target_zone)]!") + return ..() + +#undef REALIGN_INNARDS +#undef WELD_VEINS diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 040f3ce487..7a5356ce06 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -530,8 +530,7 @@ GLOBAL_LIST_EMPTY(vending_products) 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_BLUNT) - var/type_wound = pick(list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate)) + var/type_wound = pick(list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate)) squish_part.force_wound_upwards(type_wound) else squish_part.receive_damage(brute=30) diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 9f3d8911ec..9c35ddb75f 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -66,7 +66,9 @@ h1.alert, h2.alert {color: #000000;} .passive {color: #660000;} .userdanger {color: #ff0000; font-weight: bold; font-size: 3;} -.danger {color: #ff0000;} +.danger {color: #ff0000; font-weight: bold;} +.tinydanger {color: #ff0000; font-size: 85%;} +.smalldanger {color: #ff0000; font-size: 90%;} .warning {color: #ff0000; font-style: italic;} .boldwarning {color: #ff0000; font-style: italic; font-weight: bold} .announce {color: #228b22; font-weight: bold;} @@ -75,6 +77,9 @@ h1.alert, h2.alert {color: #000000;} .rose {color: #ff5050;} .info {color: #0000CC;} .notice {color: #000099;} +.tinynotice {color: #000099; font-size: 85%;} +.smallnotice {color: #000099; font-size: 90%;} +.smallnoticeital {color: #000099; font-style: italic; font-size: 90%;} .boldnotice {color: #000099; font-weight: bold;} .adminnotice {color: #0000ff;} .adminhelp {color: #ff0000; font-weight: bold;} diff --git a/sound/effects/blood1.ogg b/sound/effects/wounds/blood1.ogg similarity index 100% rename from sound/effects/blood1.ogg rename to sound/effects/wounds/blood1.ogg diff --git a/sound/effects/blood2.ogg b/sound/effects/wounds/blood2.ogg similarity index 100% rename from sound/effects/blood2.ogg rename to sound/effects/wounds/blood2.ogg diff --git a/sound/effects/blood3.ogg b/sound/effects/wounds/blood3.ogg similarity index 100% rename from sound/effects/blood3.ogg rename to sound/effects/wounds/blood3.ogg diff --git a/sound/effects/crack1.ogg b/sound/effects/wounds/crack1.ogg similarity index 100% rename from sound/effects/crack1.ogg rename to sound/effects/wounds/crack1.ogg diff --git a/sound/effects/crack2.ogg b/sound/effects/wounds/crack2.ogg similarity index 100% rename from sound/effects/crack2.ogg rename to sound/effects/wounds/crack2.ogg diff --git a/sound/effects/wounds/crackandbleed.ogg b/sound/effects/wounds/crackandbleed.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ea07f13d482087be78a525d993bf912626925e46 GIT binary patch literal 15662 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�U|E2pS-PVJnM8WxMioIfus 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 S<^2F2lVd6ny$diMr~d^L?J`vW literal 0 HcmV?d00001 diff --git a/sound/effects/wounds/pierce1.ogg b/sound/effects/wounds/pierce1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cd7b7c39610214fd14ae4e6bb2e267f9f91fb3b7 GIT binary patch literal 8726 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 literal 0 HcmV?d00001 diff --git a/sound/effects/wounds/pierce2.ogg b/sound/effects/wounds/pierce2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4977cab299f273a74f00de7c2f7425e04c150ede GIT binary patch literal 17779 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 SldO-Z&s+!&4h{|u4h{~SE}iWF literal 0 HcmV?d00001 diff --git a/sound/effects/sizzle1.ogg b/sound/effects/wounds/sizzle1.ogg similarity index 100% rename from sound/effects/sizzle1.ogg rename to sound/effects/wounds/sizzle1.ogg diff --git a/sound/effects/sizzle2.ogg b/sound/effects/wounds/sizzle2.ogg similarity index 100% rename from sound/effects/sizzle2.ogg rename to sound/effects/wounds/sizzle2.ogg diff --git a/strings/wounds/bone_scar_desc.json b/strings/wounds/bone_scar_desc.json new file mode 100644 index 0000000000..3540547c4a --- /dev/null +++ b/strings/wounds/bone_scar_desc.json @@ -0,0 +1,26 @@ +{ + "generic": ["general disfigurement"], + + "bluntmoderate": [ + "the bone equivalent of a faded bruise", + "a series of tiny chip marks" + ], + + "bluntsevere": [ + "a series of faded hairline cracks", + "a small bone dent" + ], + + "bluntcritical": [ + "large streaks of refilled cracks", + "a fractal of reformed stress marks", + "a cluster of calluses" + ], + + "dismember": [ + "is slightly misaligned", + "has clearly been dropped recently", + "has a damaged socket" + ] + +} \ No newline at end of file diff --git a/strings/wounds/flesh_scar_desc.json b/strings/wounds/flesh_scar_desc.json new file mode 100644 index 0000000000..fb2b927a30 --- /dev/null +++ b/strings/wounds/flesh_scar_desc.json @@ -0,0 +1,86 @@ +{ + "generic": ["general disfigurement"], + + "bluntmoderate": [ + "light discoloring", + "a slight blue tint" + ], + + "bluntsevere": [ + "a faded, fist-sized bruise", + "a vaguely triangular peel scar" + ], + + "bluntcritical": [ + "a section of janky skin lines and badly healed scars", + "a large patch of uneven skin tone", + "a cluster of calluses" + ], + + + + "slashmoderate": [ + "light, faded lines", + "minor cut marks", + "a small faded slit", + "a series of small scars" + ], + + "slashsevere": [ + "a twisted line of faded gashes", + "a gnarled sickle-shaped slice scar" + ], + + "slashcritical": [ + "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" + ], + + + + "piercemoderate": [ + "a small, faded bruise", + "a small twist of reformed skin", + "a thumb-sized puncture scar" + ], + + "piercesevere": [ + "an ink-splat shaped pocket of scar tissue", + "a long-faded puncture wound", + "a tumbling puncture hole with evidence of faded stitching" + ], + + "piercecritical": [ + "a rippling shockwave of scar tissue", + "a wide, scattered cloud of shrapnel marks", + "a gruesome multi-pronged puncture scar" + ], + + + + "burnmoderate": [ + "small amoeba-shaped skinmarks", + "a faded streak of depressed skin" + ], + + "burnsevere": [ + "a large, jagged patch of faded skin", + "random spots of shiny, smooth skin", + "spots of taut, leathery skin" + ], + + "burncritical": [ + "massive, disfiguring keloid scars", + "several long streaks of badly discolored and malformed skin", + "unmistakeable splotches of dead tissue from serious burns" + ], + + + "dismember": [ + "is several skintone shades paler than the rest of the body", + "is a gruesome patchwork of artificial flesh", + "has a large series of attachment scars at the articulation points" + ] + +} \ No newline at end of file diff --git a/strings/wounds/scar_loc.json b/strings/wounds/scar_loc.json new file mode 100644 index 0000000000..f721294925 --- /dev/null +++ b/strings/wounds/scar_loc.json @@ -0,0 +1,52 @@ +{ + "": ["general area"], + + "head": [ + "left eyebrow", + "cheekbone", + "neck", + "throat", + "jawline", + "entire face" + ], + + "chest": [ + "upper chest", + "lower abdomen", + "midsection", + "collarbone", + "lower back" + ], + + "l_arm": [ + "outer left forearm", + "inner left wrist", + "left elbow", + "left bicep", + "left shoulder" + ], + + "r_arm": [ + "outer right forearm", + "inner right wrist", + "right elbow", + "right bicep", + "right shoulder" + ], + + "l_leg": [ + "inner left thigh", + "outer left calf", + "outer left hip", + "left kneecap", + "lower left shin" + ], + + "r_leg": [ + "inner right thigh", + "outer right calf", + "outer right hip", + "right kneecap", + "lower right shin" + ] +} \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 2a7156f043..59fe18bdff 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -659,7 +659,9 @@ #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\loss.dm" +#include "code\datums\wounds\pierce.dm" +#include "code\datums\wounds\slash.dm" #include "code\game\alternate_appearance.dm" #include "code\game\atoms.dm" #include "code\game\atoms_movable.dm" @@ -3290,6 +3292,7 @@ #include "code\modules\surgery\plastic_surgery.dm" #include "code\modules\surgery\prosthetic_replacement.dm" #include "code\modules\surgery\remove_embedded_object.dm" +#include "code\modules\surgery\repair_puncture.dm" #include "code\modules\surgery\surgery.dm" #include "code\modules\surgery\surgery_step.dm" #include "code\modules\surgery\tools.dm"