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