From 5b0447edcc13a064a3a11eb3834e05d46247dd8e Mon Sep 17 00:00:00 2001 From: Contrabang <91113370+Contrabang@users.noreply.github.com> Date: Sun, 17 Aug 2025 13:12:44 -0700 Subject: [PATCH] Makes automenders rarer. Adds sutures/regenerative meshes. (#30003) * suture * tweak * bio 6 -> bio 7 * tweak bleed supression * review * Update code/game/objects/items/stacks/medical_packs.dm Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Signed-off-by: Contrabang <91113370+Contrabang@users.noreply.github.com> --------- Signed-off-by: Contrabang <91113370+Contrabang@users.noreply.github.com> Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> --- .../machinery/vendors/departmental_vendors.dm | 6 +- .../game/machinery/vendors/generic_vendors.dm | 1 + .../objects/items/stacks/medical_packs.dm | 179 +++++++++++++++++- code/game/objects/items/storage/firstaid.dm | 6 +- .../research/designs/autolathe_designs.dm | 8 - .../research/designs/medical_designs.dm | 9 + icons/obj/medical.dmi | Bin 1918 -> 7641 bytes 7 files changed, 192 insertions(+), 17 deletions(-) diff --git a/code/game/machinery/vendors/departmental_vendors.dm b/code/game/machinery/vendors/departmental_vendors.dm index 01437bc26c5..2ac713c84da 100644 --- a/code/game/machinery/vendors/departmental_vendors.dm +++ b/code/game/machinery/vendors/departmental_vendors.dm @@ -260,8 +260,10 @@ /obj/item/stack/medical/ointment/advanced = 2, /obj/item/reagent_containers/patch/styptic = 3, /obj/item/reagent_containers/patch/silver_sulf = 3, - /obj/item/reagent_containers/applicator/brute = 2, - /obj/item/reagent_containers/applicator/burn = 2, + /obj/item/stack/medical/suture/medicated = 3, + /obj/item/stack/medical/suture = 5, + /obj/item/stack/medical/suture/regen_mesh/advanced = 3, + /obj/item/stack/medical/suture/regen_mesh = 5, /obj/item/stack/medical/bruise_pack = 2, /obj/item/stack/medical/splint = 3, /obj/item/reagent_containers/syringe = 6, diff --git a/code/game/machinery/vendors/generic_vendors.dm b/code/game/machinery/vendors/generic_vendors.dm index f920aca2056..9a1e411e5bd 100644 --- a/code/game/machinery/vendors/generic_vendors.dm +++ b/code/game/machinery/vendors/generic_vendors.dm @@ -1371,6 +1371,7 @@ density = FALSE //It is wall-mounted, and thus, not dense. --Superxpdude tiltable = FALSE products = list(/obj/item/stack/medical/bruise_pack = 2, + /obj/item/stack/medical/suture/emergency = 2, /obj/item/stack/medical/ointment = 2, /obj/item/reagent_containers/syringe/charcoal = 4, /obj/item/reagent_containers/hypospray/autoinjector/epinephrine = 4, diff --git a/code/game/objects/items/stacks/medical_packs.dm b/code/game/objects/items/stacks/medical_packs.dm index fc94995a094..b449cdf81ae 100644 --- a/code/game/objects/items/stacks/medical_packs.dm +++ b/code/game/objects/items/stacks/medical_packs.dm @@ -11,7 +11,7 @@ parent_stack = TRUE var/heal_brute = 0 var/heal_burn = 0 - var/self_delay = 20 + var/delay = 20 var/unique_handling = FALSE //some things give a special prompt, do we want to bypass some checks in parent? var/stop_bleeding = 0 var/healverb = "bandage" @@ -48,7 +48,7 @@ if(M == user && !unique_handling) user.visible_message("[user] starts to apply [src] on [H]...") - if(!do_mob(user, H, self_delay)) + if(!do_mob(user, H, delay)) return TRUE return @@ -308,7 +308,7 @@ singular_name = "medical splint" icon_state = "splint" unique_handling = TRUE - self_delay = 100 + delay = 100 merge_type = /obj/item/stack/medical/splint var/other_delay = 0 @@ -333,12 +333,12 @@ to_chat(user, "You remove the splint from [H]'s [limb].") return TRUE - if((M == user && self_delay > 0) || (M != user && other_delay > 0)) + if((M == user && delay > 0) || (M != user && other_delay > 0)) user.visible_message("[user] starts to apply [src] to [H]'s [limb].", \ "You start to apply [src] to [H]'s [limb].", \ "You hear something being wrapped.") - if(M == user && !do_mob(user, H, self_delay)) + if(M == user && !do_mob(user, H, delay)) return TRUE else if(!do_mob(user, H, other_delay)) return TRUE @@ -362,3 +362,172 @@ name = "tribal splints" icon_state = "tribal_splint" other_delay = 50 + +// Sutures and burn meshes + +/obj/item/stack/medical/suture + name = "sutures" + singular_name = "suture" + desc = "A bundle of sterilized sutures used for sealing up minor cuts and lacerations." + icon_state = "suture" + gender = PLURAL + merge_type = /obj/item/stack/medical/suture + healverb = "suturing" + amount = 10 + max_amount = 10 + heal_brute = 10 + stop_bleeding = 1200 + dynamic_icon_state = TRUE + delay = 1 SECONDS + var/self_delay = 3 SECONDS + var/applying = FALSE + +/obj/item/stack/medical/suture/apply(mob/living/carbon/human/target, mob/user) + . = TRUE + if(applying) + to_chat(user, "You're already applying [src].") + return + if(!ishuman(target) || !target.can_inject(user, TRUE)) + return + var/heal_type = (heal_brute ? BRUTE : BURN) + var/heal_display = (heal_brute ? BRUTE : "burn") + if(!target.get_damage_amount(heal_type)) + if(target == user) + to_chat(user, "You don't have any [heal_display] damage.") + else + to_chat(user, "They don't have any [heal_display] damage.") + return + + var/obj/item/organ/external/current_limb = target.get_organ(user.zone_selected) + if(!current_limb) + to_chat(user, "That limb is missing!") + return + if(current_limb.is_robotic()) + to_chat(user, "This can't be used on a robotic limb.") + return + if((heal_brute > 0 && !current_limb.brute_dam) || (heal_burn > 0 && !current_limb.burn_dam)) + if(!do_after(user, delay / 2, target = target)) + return + current_limb = most_damaged_limb(target) + + var/mend_time = delay + if(target == user) + target.visible_message("[user] begins [healverb] [user.p_themselves()] with [src].", "You begin [healverb] your [current_limb.name] with [src].") + mend_time = self_delay + else + user.visible_message("[user] begins [healverb] [target] with [src].", "You begin [healverb] [target.p_their()] [current_limb.name] with [src].") + + applying = TRUE + while(do_after(user, mend_time, target = target)) + if(!target.can_inject(user, TRUE)) + break + var/cut_open = FALSE + if(stop_bleeding) + for(var/obj/item/organ/external/E in target.bodyparts) + if(E.open >= ORGAN_ORGANIC_OPEN) + cut_open = TRUE + to_chat(user, "[target]'s [E.name] is cut open, you'll need more than some [name] to stop their bleeding.") + break + if(!apply_to(target, user, current_limb, !cut_open)) + break + if(is_zero_amount(TRUE)) + break + if((heal_brute > 0 && !current_limb.brute_dam) || (heal_burn > 0 && !current_limb.burn_dam)) + if(!target.get_damage_amount(heal_type)) + if(target == user) + target.visible_message("[user] finishes [healverb] [user.p_themselves()] with [src].", "You finish [healverb] yourself with [src].") + else + user.visible_message("[user] finishes [healverb] [target] with [src].", "You finish [healverb] [target] with [src].") + break + if(!do_after(user, delay / 2, target = target)) + break + current_limb = most_damaged_limb(target) + to_chat(user, "You begin [healverb] [target == user ? "your" : target.p_their()] [current_limb.name] with [src].") + if(!target.can_inject(user, TRUE)) + break + applying = FALSE + user.changeNext_move(CLICK_CD_MELEE) + +/obj/item/stack/medical/suture/proc/apply_to(mob/living/carbon/human/target, mob/user, obj/item/organ/external/current_limb, allow_stop_bleeding = TRUE) + if(!use(1)) + return FALSE + + current_limb.heal_damage(heal_brute, heal_burn, FALSE, FALSE, updating_health = TRUE) + + if(stop_bleeding && !target.bleedsuppress && allow_stop_bleeding) + target.suppress_bloodloss(stop_bleeding) + return TRUE + +/obj/item/stack/medical/suture/proc/most_damaged_limb(mob/living/carbon/human/target) + var/obj/item/organ/external/most_damaged + var/most_damaged_amount = 0 + var/focus_brute = (heal_brute > 0) + for(var/obj/item/organ/external/E in target.bodyparts) + if(focus_brute) + if(E.brute_dam > most_damaged_amount) + most_damaged = E + most_damaged_amount = E.brute_dam + else if(E.burn_dam > most_damaged_amount) + most_damaged = E + most_damaged_amount = E.burn_dam + return most_damaged + +/obj/item/stack/medical/suture/emergency + name = "emergency sutures" + singular_name = "emergency suture" + desc = "A small bundle of cheap sutures. They're not pretty, but still quite effective at keeping the blood inside your body." + merge_type = /obj/item/stack/medical/suture/emergency + heal_brute = 5 + +/obj/item/stack/medical/suture/medicated + name = "medicated sutures" + singular_name = "medicated suture" + desc = "A bundle of sterilized sutures used for sealing up minor cuts and lacerations. These have been treated with potent healing chemicals, dramatically improving their wound-sealing capability." + icon_state = "suture_medicated" + merge_type = /obj/item/stack/medical/suture/medicated + heal_brute = 15 + stop_bleeding = 2000 + +/obj/item/stack/medical/suture/regen_mesh + name = "regenerative mesh" + desc = "A sheet of bacteriostatic mesh used to graft minor burns, housed in a sterile packet." + singular_name = "mesh piece" + icon_state = "regen_mesh" + merge_type = /obj/item/stack/medical/suture/regen_mesh + healverb = "grafting" + heal_brute = 0 + heal_burn = 10 + /// This var determines if the sterile packaging of the mesh has been opened. + var/is_open = TRUE + +/obj/item/stack/medical/suture/regen_mesh/Initialize(mapload, new_amount, merge) + . = ..() + if(amount == max_amount) // only seal full mesh packs + is_open = FALSE + update_appearance() + +/obj/item/stack/medical/suture/regen_mesh/update_icon_state() + if(is_open) + return ..() + icon_state = "[initial(icon_state)]_closed" + +/obj/item/stack/medical/suture/regen_mesh/apply(mob/living/carbon/human/target, mob/user) + open_mesh() + . = ..() + +/obj/item/stack/medical/suture/regen_mesh/change_stack(mob/user, amount) + open_mesh() + . = ..() + +/obj/item/stack/medical/suture/regen_mesh/proc/open_mesh() + if(!is_open) + is_open = TRUE + update_icon(UPDATE_ICON_STATE) + playsound(src, 'sound/items/poster_ripped.ogg', 20, TRUE) + +/obj/item/stack/medical/suture/regen_mesh/advanced + name = "advanced regenerative mesh" + desc = "A sheet of medically-treated bacteriostatic mesh used to graft moderate burns, housed in a sterile packet." + icon_state = "advanced_mesh" + merge_type = /obj/item/stack/medical/suture/regen_mesh/advanced + heal_burn = 15 diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index b197c8d058c..c3b78583239 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -65,7 +65,8 @@ icon_state = pick("ointment", "firefirstaid") /obj/item/storage/firstaid/fire/populate_contents() - new /obj/item/reagent_containers/applicator/burn(src) + new /obj/item/stack/medical/suture/regen_mesh/advanced(src) + new /obj/item/stack/medical/suture/regen_mesh(src) new /obj/item/reagent_containers/patch/silver_sulf/small(src) new /obj/item/healthanalyzer(src) new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src) @@ -123,7 +124,8 @@ icon_state = pick("brute", "brute2") /obj/item/storage/firstaid/brute/populate_contents() - new /obj/item/reagent_containers/applicator/brute(src) + new /obj/item/stack/medical/suture/medicated(src) + new /obj/item/stack/medical/suture(src) new /obj/item/reagent_containers/patch/styptic/small(src) new /obj/item/healthanalyzer(src) new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src) diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 516b8aab2c8..12f41c3b863 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -752,14 +752,6 @@ build_path = /obj/item/reagent_containers/hypospray/safety category = list("initial", "Medical") -/datum/design/automender - name = "Auto-mender" - id = "automender" - build_type = AUTOLATHE - materials = list(MAT_METAL = 1000, MAT_GLASS = 1000) - build_path = /obj/item/reagent_containers/applicator - category = list("initial", "Medical") - /datum/design/prox_sensor name = "Proximity Sensor" id = "prox_sensor" diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 73eabdfeead..d7652b3d0a3 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -52,6 +52,15 @@ build_path = /obj/item/healthupgrade category = list("Medical") +/datum/design/automender + name = "Auto-mender" + id = "automender" + req_tech = list("biotech" = 7, "magnets" = 3) + build_type = PROTOLATHE + materials = list(MAT_TITANIUM = 3000, MAT_GLASS = 1000) + build_path = /obj/item/reagent_containers/applicator + category = list("Medical") + /datum/design/handheld_defib name = "Handheld Defibrillator" desc = "A smaller defibrillator only capable of treating cardiac arrest." diff --git a/icons/obj/medical.dmi b/icons/obj/medical.dmi index 983565816036bfe1840f893f4551babb67cea6ac..348a22f61caa95bea1a82328340395c8325e34b2 100644 GIT binary patch literal 7641 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 Ef(P$wSpWb4