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 98356581603..348a22f61ca 100644 Binary files a/icons/obj/medical.dmi and b/icons/obj/medical.dmi differ