[MIRROR] Grabbing Yourself + Wound Fixes: Take 2 (+Minor Scar Changes) (#544)

* Grabbing Yourself + Wound Fixes: Take 2 (+Minor Scar Changes) (#52951)

By clicking yourself with grab intent while targeting a limb of yours that's bleeding, you'll "grab" onto it with your free hand to apply pressure. This takes 1.5 seconds to do, takes up a hand while you do so, and applies a slowdown while you're holding it. In return, that limb will bleed 30% less while you're holding it (though it won't clot any faster). This stacks with the 25% reduction in bleeding you get from being horizontal, so laying down clutching your gushing gut while waiting for help is now both thematic and viable!
Other fixes and changes

I also made some other changes to wounds of various importance. Here's a quick list

-Most wound treatments now respect thick clothing/materials, so you can no longer suture slashes through spacesuits.
-Using sutures on slashes and pierces now actually use up sutures, and regen mesh must be opened to treat wounds with
-Infectious zombies (romerol) can now be wounded as intended
-Coagulant has been nerfed again to reduce bleeding less for every wound it's reducing bleeding on. This'll still need more love and attention later, but I need to find a good middle point where medipens are good for bleeding in an emergency without being a way to sidestep any and all bleeding wounds in one go.
-I added a recipe for improvised coagulant in the Wounds 2 PR using baked pulped banana peels and salglu, but then realized that recipe sucked and was overly complicated. You can now drink straight up ground/juiced banana peels to help close up slashes and piercings. Yuckm!
-You can no longer repeatedly disembowel people who have already lost their internal organs
-Whetstones now make things edged sharp rather than pointy sharp, fixing a carryover from when sharpness = 2 used to be accurate sharpness. This'll have the effect of making sharpened weapons less sucky at chopping people apart since slashing is usually more devastating than piercing

I've also made a few tweaks to scars, mostly making them a bit smaller. It now takes twice as much scar severity to reach "absolutely fucked up" when examined, and the other steps have been raised a few points as well. Minor scar examine text is a tad smaller text-wise, and the precise locations for the scars are a bit more procedural as well (more location modifiers like upper/lower/inner/outer wrist/whatever). These changes will hopefully add a bit more variety to the scarring you see on random crew members, since it's pretty easy to hit max examine severity as is.

* Grabbing Yourself + Wound Fixes: Take 2 (+Minor Scar Changes)

Co-authored-by: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com>
This commit is contained in:
SkyratBot
2020-08-27 21:52:59 +02:00
committed by GitHub
co-authored by Ryll Ryll
parent cf13a48927
commit 76efc3d305
29 changed files with 281 additions and 156 deletions
+21 -19
View File
@@ -148,25 +148,27 @@
return !held_items[hand_index]
/mob/proc/put_in_hand(obj/item/I, hand_index, forced = FALSE, ignore_anim = TRUE)
if(forced || can_put_in_hand(I, hand_index))
if(isturf(I.loc) && !ignore_anim)
I.do_pickup_animation(src)
if(hand_index == null)
return FALSE
if(get_item_for_held_index(hand_index) != null)
dropItemToGround(get_item_for_held_index(hand_index), force = TRUE)
I.forceMove(src)
held_items[hand_index] = I
I.layer = ABOVE_HUD_LAYER
I.plane = ABOVE_HUD_PLANE
I.equipped(src, ITEM_SLOT_HANDS)
if(I.pulledby)
I.pulledby.stop_pulling()
update_inv_hands()
I.pixel_x = initial(I.pixel_x)
I.pixel_y = initial(I.pixel_y)
return hand_index || TRUE
return FALSE
if(hand_index == null || (!forced && !can_put_in_hand(I, hand_index)))
return FALSE
if(isturf(I.loc) && !ignore_anim)
I.do_pickup_animation(src)
if(get_item_for_held_index(hand_index) != null)
dropItemToGround(get_item_for_held_index(hand_index), force = TRUE)
I.forceMove(src)
held_items[hand_index] = I
I.layer = ABOVE_HUD_LAYER
I.plane = ABOVE_HUD_PLANE
I.equipped(src, ITEM_SLOT_HANDS)
if(QDELETED(I)) // this is here because some ABSTRACT items like slappers and circle hands could be moved from hand to hand then delete, which meant you'd have a null in your hand until you cleared it (say, by dropping it)
held_items[hand_index] = null
return FALSE
if(I.pulledby)
I.pulledby.stop_pulling()
update_inv_hands()
I.pixel_x = initial(I.pixel_x)
I.pixel_y = initial(I.pixel_y)
return hand_index
//Puts the item into the first available left hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(obj/item/I)
+4
View File
@@ -13,6 +13,10 @@
QDEL_LIST(internal_organs)
QDEL_LIST(bodyparts)
QDEL_LIST(implants)
for(var/wound in all_wounds) // these LAZYREMOVE themselves when deleted so no need to remove the list here
qdel(wound)
for(var/scar in all_scars)
qdel(scar)
remove_from_all_data_huds()
QDEL_NULL(dna)
GLOB.carbon_list -= src
@@ -635,4 +635,75 @@
if (limb.status != BODYPART_ORGANIC)
. += (limb.brute_dam * limb.body_damage_coeff) + (limb.burn_dam * limb.body_damage_coeff)
/mob/living/carbon/grabbedby(mob/living/carbon/user, supress_message = FALSE)
if(user != src)
return ..()
var/obj/item/bodypart/grasped_part = get_bodypart(zone_selected)
if(!grasped_part?.get_bleed_rate())
return
var/starting_hand_index = active_hand_index
if(starting_hand_index == grasped_part.held_index)
to_chat(src, "<span class='danger'>You can't grasp your [grasped_part.name] with itself!</span>")
return
to_chat(src, "<span class='warning'>You try grasping at your [grasped_part.name], trying to stop the bleeding...</span>")
if(!do_after(src, 1.5 SECONDS))
to_chat(src, "<span class='danger'>You fail to grasp your [grasped_part.name].</span>")
return
var/obj/item/self_grasp/grasp = new
if(starting_hand_index != active_hand_index || !put_in_active_hand(grasp))
to_chat(src, "<span class='danger'>You fail to grasp your [grasped_part.name].</span>")
QDEL_NULL(grasp)
return
grasp.grasp_limb(grasped_part)
/// an abstract item representing you holding your own limb to staunch the bleeding, see [/mob/living/carbon/proc/grabbedby] will probably need to find somewhere else to put this.
/obj/item/self_grasp
name = "self-grasp"
desc = "Sometimes all you can do is slow the bleeding."
icon_state = "latexballon"
inhand_icon_state = "nothing"
force = 0
throwforce = 0
slowdown = 1
item_flags = DROPDEL | ABSTRACT | NOBLUDGEON | SLOWS_WHILE_IN_HAND | HAND_ITEM
/// The bodypart we're staunching bleeding on, which also has a reference to us in [/obj/item/bodypart/var/grasped_by]
var/obj/item/bodypart/grasped_part
/// The carbon who owns all of this mess
var/mob/living/carbon/user
/obj/item/self_grasp/Destroy()
if(user)
to_chat(user, "<span class='warning'>You stop holding onto your[grasped_part ? " [grasped_part.name]" : "self"].</span>")
UnregisterSignal(user, COMSIG_PARENT_QDELETING)
if(grasped_part)
UnregisterSignal(grasped_part, list(COMSIG_CARBON_REMOVE_LIMB, COMSIG_PARENT_QDELETING))
grasped_part.grasped_by = null
grasped_part = null
user = null
return ..()
/// The limb or the whole damn person we were grasping got deleted or dismembered, so we don't care anymore
/obj/item/self_grasp/proc/qdel_void()
qdel(src)
/// We've already cleared that the bodypart in question is bleeding in [the place we create this][/mob/living/carbon/proc/grabbedby], so set up the connections
/obj/item/self_grasp/proc/grasp_limb(obj/item/bodypart/grasping_part)
user = grasping_part.owner
if(!istype(user))
stack_trace("[src] attempted to try_grasp() with [istype(user, /datum) ? user.type : isnull(user) ? "null" : user] user")
qdel(src)
return
grasped_part = grasping_part
grasped_part.grasped_by = src
RegisterSignal(user, COMSIG_PARENT_QDELETING, .proc/qdel_void)
RegisterSignal(grasped_part, list(COMSIG_CARBON_REMOVE_LIMB, COMSIG_PARENT_QDELETING), .proc/qdel_void)
user.visible_message("<span class='danger'>[user] grasps at [user.p_their()] [grasped_part.name], trying to stop the bleeding.</span>", "<span class='notice'>You grab hold of your [grasped_part.name] tightly.</span>", vision_distance=COMBAT_MESSAGE_RANGE)
playsound(get_turf(src), 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
return TRUE
#undef SHAKE_ANIMATION_OFFSET
+7 -7
View File
@@ -111,13 +111,13 @@
scar_severity += S.severity
switch(scar_severity)
if(1 to 2)
msg += "<span class='smallnoticeital'>[t_He] [t_has] visible scarring, you can look again to take a closer look...</span>\n"
if(3 to 4)
msg += "<span class='notice'><i>[t_He] [t_has] several bad scars, you can look again to take a closer look...</i></span>\n"
if(5 to 6)
msg += "<span class='notice'><b><i>[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...</i></b></span>\n"
if(7 to INFINITY)
if(1 to 4)
msg += "<span class='tinynoticeital'>[t_He] [t_has] visible scarring, you can look again to take a closer look...</span>\n"
if(5 to 8)
msg += "<span class='smallnoticeital'>[t_He] [t_has] several bad scars, you can look again to take a closer look...</span>\n"
if(9 to 11)
msg += "<span class='notice'><i>[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...</i></span>\n"
if(12 to INFINITY)
msg += "<span class='notice'><b><i>[t_He] [t_is] just absolutely fucked up, you can look again to take a closer look...</i></b></span>\n"
msg += "</span>"
+33 -25
View File
@@ -140,29 +140,29 @@
var/list/missing = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/list/disabled = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(BP.bodypart_disabled)
disabled += BP
missing -= BP.body_zone
for(var/obj/item/I in BP.embedded_objects)
var/obj/item/bodypart/body_part = X
if(body_part.bodypart_disabled)
disabled += body_part
missing -= body_part.body_zone
for(var/obj/item/I in body_part.embedded_objects)
if(I.isEmbedHarmless())
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!</B>\n"
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [body_part.name]!</B>\n"
else
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!</B>\n"
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [body_part.name]!</B>\n"
for(var/i in BP.wounds)
for(var/i in body_part.wounds)
var/datum/wound/iter_wound = i
msg += "[iter_wound.get_examine_description(user)]\n"
for(var/X in disabled)
var/obj/item/bodypart/BP = X
var/obj/item/bodypart/body_part = X
var/damage_text
if(BP.is_disabled() != BODYPART_DISABLED_WOUND) // skip if it's disabled by a wound (cuz we'll be able to see the bone sticking out!)
if(!(BP.get_damage(include_stamina = FALSE) >= BP.max_damage)) //we don't care if it's stamcritted
if(body_part.is_disabled() != BODYPART_DISABLED_WOUND) // skip if it's disabled by a wound (cuz we'll be able to see the bone sticking out!)
if(!(body_part.get_damage(include_stamina = FALSE) >= body_part.max_damage)) //we don't care if it's stamcritted
damage_text = "limp and lifeless"
else
damage_text = (BP.brute_dam >= BP.burn_dam) ? BP.heavy_brute_msg : BP.heavy_burn_msg
msg += "<B>[capitalize(t_his)] [BP.name] is [damage_text]!</B>\n"
damage_text = (body_part.brute_dam >= body_part.burn_dam) ? body_part.heavy_brute_msg : body_part.heavy_burn_msg
msg += "<B>[capitalize(t_his)] [body_part.name] is [damage_text]!</B>\n"
//stores missing limbs
var/l_limbs_missing = 0
@@ -252,11 +252,14 @@
msg += "[t_He] [t_is] embued with a power that defies bleeding.\n" // only statues and highlander sword can cause this so whatever
else if(is_bleeding())
var/list/obj/item/bodypart/bleeding_limbs = list()
var/list/obj/item/bodypart/grasped_limbs = list()
for(var/i in bodyparts)
var/obj/item/bodypart/BP = i
if(BP.get_bleed_rate())
bleeding_limbs += BP
var/obj/item/bodypart/body_part = i
if(body_part.get_bleed_rate())
bleeding_limbs += body_part
if(body_part.grasped_by)
grasped_limbs += body_part
var/num_bleeds = LAZYLEN(bleeding_limbs)
@@ -271,8 +274,8 @@
bleed_text += " [bleeding_limbs[1].name][num_bleeds == 2 ? " and [bleeding_limbs[2].name]" : ""]"
if(3 to INFINITY)
for(var/i in 1 to (num_bleeds - 1))
var/obj/item/bodypart/BP = bleeding_limbs[i]
bleed_text += " [BP.name],"
var/obj/item/bodypart/body_part = bleeding_limbs[i]
bleed_text += " [body_part.name],"
bleed_text += " and [bleeding_limbs[num_bleeds].name]"
if(appears_dead)
@@ -282,6 +285,11 @@
bleed_text += " incredibly quickly"
bleed_text += "!</B>\n"
for(var/i in grasped_limbs)
var/obj/item/bodypart/grasped_part = i
bleed_text += "[t_He] [t_is] holding [t_his] [grasped_part.name] to slow the bleeding!\n"
msg += bleed_text.Join()
if(reagents.has_reagent(/datum/reagent/teslium, needs_metabolizing = TRUE))
@@ -359,13 +367,13 @@
scar_severity += S.severity
switch(scar_severity)
if(1 to 2)
msg += "<span class='smallnoticeital'>[t_He] [t_has] visible scarring, you can look again to take a closer look...</span>\n"
if(3 to 4)
msg += "<span class='notice'><i>[t_He] [t_has] several bad scars, you can look again to take a closer look...</i></span>\n"
if(5 to 6)
msg += "<span class='notice'><b><i>[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...</i></b></span>\n"
if(7 to INFINITY)
if(1 to 4)
msg += "<span class='tinynoticeital'>[t_He] [t_has] visible scarring, you can look again to take a closer look...</span>\n"
if(5 to 8)
msg += "<span class='smallnoticeital'>[t_He] [t_has] several bad scars, you can look again to take a closer look...</span>\n"
if(9 to 11)
msg += "<span class='notice'><i>[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...</i></span>\n"
if(12 to INFINITY)
msg += "<span class='notice'><b><i>[t_He] [t_is] just absolutely fucked up, you can look again to take a closer look...</i></b></span>\n"