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