diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm
index 8a1df2059b..70456bee77 100644
--- a/code/_helpers/mobs.dm
+++ b/code/_helpers/mobs.dm
@@ -158,7 +158,7 @@ Proc for attack log creation, because really why not
else
return pick("chest", "groin")
-/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1)
+/proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = 0, progress = 1)
if(!user || !target)
return 0
var/user_loc = user.loc
@@ -194,6 +194,10 @@ Proc for attack log creation, because really why not
. = 0
break
+ if(target_zone && user.zone_sel.selecting != target_zone)
+ . = 0
+ break
+
if (progbar)
qdel(progbar)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 1394b86b4a..1d94367c57 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -67,7 +67,7 @@
BP_L_LEG = skiplegs,
BP_R_LEG = skiplegs)
- var/msg = "*---------*\nThis is "
+ var/list/msg = list("*---------*\nThis is ")
var/datum/gender/T = gender_datums[get_gender()]
if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender
@@ -303,6 +303,7 @@
var/list/wound_flavor_text = list()
var/list/is_bleeding = list()
+ var/applying_pressure = ""
for(var/organ_tag in species.has_limbs)
@@ -336,8 +337,6 @@
wound_flavor_text["[temp.name]"] = "[T.He] has [temp.get_wounds_desc()] on [T.his] [parent.name].
"
else
wound_flavor_text["[temp.name]"] = "[T.He] has [temp.get_wounds_desc()] on [T.his] [temp.name].
"
- if(temp.status & ORGAN_BLEEDING)
- is_bleeding["[temp.name]"] = "[T.His] [temp.name] is bleeding!
"
else
wound_flavor_text["[temp.name]"] = ""
if(temp.dislocated == 2)
@@ -345,9 +344,14 @@
if(((temp.status & ORGAN_BROKEN) && temp.brute_dam > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED))
wound_flavor_text["[temp.name]"] += "[T.His] [temp.name] is dented and swollen!
"
+ if(!wound_flavor_text["[temp.name]"] && (temp.status & ORGAN_BLEEDING))
+ is_bleeding["[temp.name]"] = "[T.His] [temp.name] is bleeding!
"
+
+ if(temp.applied_pressure == src)
+ applying_pressure = "[T.He] is applying pressure to [T.his] [temp.name].
"
+
for(var/limb in wound_flavor_text)
msg += wound_flavor_text[limb]
- is_bleeding[limb] = null
for(var/limb in is_bleeding)
msg += is_bleeding[limb]
for(var/implant in get_visible_implants(0))
@@ -403,13 +407,14 @@
if(print_flavor_text()) msg += "[print_flavor_text()]\n"
- msg += "*---------*"
+ msg += "*---------*
"
+ msg += applying_pressure
if (pose)
if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 )
pose = addtext(pose,".") //Makes sure all emotes end with a period.
- msg += "\n[T.He] [pose]"
+ msg += "[T.He] [pose]"
- user << msg
+ user << jointext(msg, null)
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
/proc/hasHUD(mob/M as mob, hudtype)
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 62d469cb0e..6eb6b35a95 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -87,7 +87,7 @@
src << "You feel a breath of fresh air enter your lungs. It feels good."
H << "Repeat at least every 7 seconds."
- else
+ else if(!(M == src && apply_pressure(M, M.zone_sel.selecting)))
help_shake_act(M)
return 1
@@ -358,3 +358,38 @@
spawn(1)
qdel(rgrab)
return success
+
+/*
+ We want to ensure that a mob may only apply pressure to one organ of one mob at any given time. Currently this is done mostly implicitly through
+ the behaviour of do_after() and the fact that applying pressure to someone else requires a grab:
+ If you are applying pressure to yourself and attempt to grab someone else, you'll change what you are holding in your active hand which will stop do_mob()
+ If you are applying pressure to another and attempt to apply pressure to yourself, you'll have to switch to an empty hand which will also stop do_mob()
+ Changing targeted zones should also stop do_mob(), preventing you from applying pressure to more than one body part at once.
+*/
+/mob/living/carbon/human/proc/apply_pressure(mob/living/user, var/target_zone)
+ var/obj/item/organ/external/organ = get_organ(target_zone)
+ if(!organ || !(organ.status & ORGAN_BLEEDING) || (organ.robotic >= ORGAN_ROBOT))
+ return 0
+
+ if(organ.applied_pressure)
+ user << "Someone is already applying pressure to [user == src? "your [organ.name]" : "[src]'s [organ.name]"]."
+ return 0
+
+ if(user == src)
+ user.visible_message("\The [user] starts applying pressure to \his [organ.name]!", "You start applying pressure to your [organ.name]!")
+ else
+ user.visible_message("\The [user] starts applying pressure to [src]'s [organ.name]!", "You start applying pressure to [src]'s [organ.name]!")
+ spawn(0)
+ organ.applied_pressure = user
+
+ //apply pressure as long as they stay still and keep grabbing
+ do_mob(user, src, INFINITY, target_zone, progress = 0)
+
+ organ.applied_pressure = null
+
+ if(user == src)
+ user.visible_message("\The [user] stops applying pressure to \his [organ.name]!", "You stop applying pressure to your [organ]!")
+ else
+ user.visible_message("\The [user] stops applying pressure to [src]'s [organ.name]!", "You stop applying pressure to [src]'s [organ.name]!")
+
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index e40b14dffd..a7b982b1b7 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -301,6 +301,7 @@
//clicking on the victim while grabbing them
if(M == affecting)
if(ishuman(affecting))
+ var/mob/living/carbon/human/H = affecting
var/hit_zone = assailant.zone_sel.selecting
flick(hud.icon_state, hud)
switch(assailant.a_intent)
@@ -309,7 +310,10 @@
assailant << "You are no longer pinning [affecting] to the ground."
force_down = 0
return
- inspect_organ(affecting, assailant, hit_zone)
+ if(state >= GRAB_AGGRESSIVE)
+ H.apply_pressure(assailant, hit_zone)
+ else
+ inspect_organ(affecting, assailant, hit_zone)
if(I_GRAB)
jointlock(affecting, assailant, hit_zone)
diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm
index c167f949fa..7637264bac 100644
--- a/code/modules/organs/blood.dm
+++ b/code/modules/organs/blood.dm
@@ -128,8 +128,18 @@ var/const/BLOOD_VOLUME_SURVIVE = 40
for(var/obj/item/organ/external/temp in organs)
if(!(temp.status & ORGAN_BLEEDING) || (temp.robotic >= ORGAN_ROBOT))
continue
- for(var/datum/wound/W in temp.wounds) if(W.bleeding())
- blood_max += W.damage / 30
+ for(var/datum/wound/W in temp.wounds)
+ if(W.bleeding())
+ if(temp.applied_pressure)
+ if(ishuman(temp.applied_pressure))
+ var/mob/living/carbon/human/H = temp.applied_pressure
+ H.bloody_hands(src, 0)
+ //somehow you can apply pressure to every wound on the organ at the same time
+ //you're basically forced to do nothing at all, so let's make it pretty effective
+ var/min_eff_damage = max(0, W.damage - 10) / 6 //still want a little bit to drip out, for effect
+ blood_max += max(min_eff_damage, W.damage - 30) / 30
+ else
+ blood_max += W.damage / 30
if (temp.open)
blood_max += 2 //Yer stomach is cut open
drip(blood_max)
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 89f3e17ff3..49917d8a23 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -38,6 +38,7 @@
var/list/s_col // skin colour
var/list/h_col // hair colour
var/body_hair // Icon blend for body hair if any.
+ var/mob/living/applied_pressure
// Wound and structural data.
var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often
@@ -1028,6 +1029,8 @@ Note that amputating the affected organ does in fact remove the infection from t
/obj/item/organ/external/proc/apply_splint(var/atom/movable/splint)
if(!splinted)
splinted = splint
+ if(!applied_pressure)
+ applied_pressure = splint
return 1
return 0
@@ -1035,6 +1038,8 @@ Note that amputating the affected organ does in fact remove the infection from t
if(splinted)
if(splinted.loc == src)
splinted.dropInto(owner? owner.loc : src.loc)
+ if(applied_pressure == splinted)
+ applied_pressure = null
splinted = null
return 1
return 0
@@ -1244,11 +1249,20 @@ Note that amputating the affected organ does in fact remove the infection from t
for(var/datum/wound/W in wounds)
if(W.internal && !open) continue // can't see internal wounds
var/this_wound_desc = W.desc
- if(W.damage_type == BURN && W.salved) this_wound_desc = "salved [this_wound_desc]"
- if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]"
- else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]"
- if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]"
- else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]"
+
+ if(W.damage_type == BURN && W.salved)
+ this_wound_desc = "salved [this_wound_desc]"
+
+ if(W.bleeding())
+ this_wound_desc = "bleeding [this_wound_desc]"
+ else if(W.bandaged)
+ this_wound_desc = "bandaged [this_wound_desc]"
+
+ if(W.germ_level > 600)
+ this_wound_desc = "badly infected [this_wound_desc]"
+ else if(W.germ_level > 330)
+ this_wound_desc = "lightly infected [this_wound_desc]"
+
if(wound_descriptors[this_wound_desc])
wound_descriptors[this_wound_desc] += W.amount
else
diff --git a/html/changelogs/HarpyEagle-Bleeding.yml b/html/changelogs/HarpyEagle-Bleeding.yml
new file mode 100644
index 0000000000..55db4c0d4e
--- /dev/null
+++ b/html/changelogs/HarpyEagle-Bleeding.yml
@@ -0,0 +1,6 @@
+author: HarpyEagle
+
+delete-after: True
+
+changes:
+ - rscadd: "Adds applying pressure to body parts to reduce bleeding. With desired body part selected, help-intent click yourself or get an aggressive grab, then help-intent attack with the grab item. Each person should only be able to apply pressure to one body part on one person at a time, so choose wisely. Applying pressure will get blood on your hands."
\ No newline at end of file