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>
This commit is contained in:
Contrabang
2025-08-17 20:12:44 +00:00
committed by GitHub
co-authored by PollardTheDragon
parent bd66906553
commit 5b0447edcc
7 changed files with 192 additions and 17 deletions
+174 -5
View File
@@ -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("<span class='notice'>[user] starts to apply [src] on [H]...</span>")
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, "<span class='notice'>You remove the splint from [H]'s [limb].</span>")
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("<span class='notice'>[user] starts to apply [src] to [H]'s [limb].</span>", \
"<span class='notice'>You start to apply [src] to [H]'s [limb].</span>", \
"<span class='notice'>You hear something being wrapped.</span>")
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, "<span class='warning'>You're already applying [src].</span>")
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, "<span class='warning'>You don't have any [heal_display] damage.</span>")
else
to_chat(user, "<span class='warning'>They don't have any [heal_display] damage.</span>")
return
var/obj/item/organ/external/current_limb = target.get_organ(user.zone_selected)
if(!current_limb)
to_chat(user, "<span class='danger'>That limb is missing!</span>")
return
if(current_limb.is_robotic())
to_chat(user, "<span class='danger'>This can't be used on a robotic limb.</span>")
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].", "<span class='notice'>You begin [healverb] your [current_limb.name] with [src].</span>")
mend_time = self_delay
else
user.visible_message("<span class='notice'>[user] begins [healverb] [target] with [src].</span>", "<span class='notice'>You begin [healverb] [target.p_their()] [current_limb.name] with [src].</span>")
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, "<span class='warning'>[target]'s [E.name] is cut open, you'll need more than some [name] to stop their bleeding.</span>")
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].", "<span class='notice'>You finish [healverb] yourself with [src].</span>")
else
user.visible_message("<span class='warning'>[user] finishes [healverb] [target] with [src].</span>", "<span class='notice'>You finish [healverb] [target] with [src].</span>")
break
if(!do_after(user, delay / 2, target = target))
break
current_limb = most_damaged_limb(target)
to_chat(user, "<span class='notice'>You begin [healverb] [target == user ? "your" : target.p_their()] [current_limb.name] with [src].</span>")
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
+4 -2
View File
@@ -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)