Tendon Health (#11826)

This commit is contained in:
Wildkins
2021-05-25 14:32:45 +02:00
committed by GitHub
parent 1166bb9579
commit 796c557856
15 changed files with 134 additions and 52 deletions
+32 -16
View File
@@ -66,7 +66,7 @@
var/datum/tendon/tendon
var/tendon_path = /datum/tendon
var/tendon_name = "tendon" // Name of the limb's tendon. Achilles heel, etc.
var/tendon_dt // Damage threshold required to possibly snap a tendon
var/tendon_health = 30 // HP value of the limb's tendon
var/list/tendon_msgs = list("tore apart", "ripped away")
var/damage_msg = "<span class='warning'>You feel an intense pain!</span>"
@@ -233,7 +233,7 @@
get_icon()
if((limb_flags & ORGAN_HAS_TENDON) && !BP_IS_ROBOTIC(src))
tendon = new tendon_path(src, tendon_name, tendon_dt, tendon_msgs)
tendon = new tendon_path(src, tendon_name, tendon_health, tendon_msgs)
/obj/item/organ/external/replaced(var/mob/living/carbon/human/target)
..()
@@ -299,11 +299,7 @@
handle_limb_gibbing(used_weapon, brute, burn)
if(brute_dam + brute > min_broken_damage && prob(brute_dam + brute * (1 + blunt)))
if((brute && !blunt) && istype(tendon) && brute_dam + brute > tendon.threshold)
tendon.sever()
if(brute_dam > FRACTURE_AND_TENDON_DAM_THRESHOLD)
fracture()
else
if(blunt || brute > FRACTURE_AND_TENDON_DAM_THRESHOLD)
fracture()
// High brute damage or sharp objects may damage internal organs
@@ -469,6 +465,9 @@ This function completely restores a damaged organ to perfect condition.
implanted_object.forceMove(owner.loc)
implants -= implanted_object
if(istype(tendon))
tendon.rejuvenate()
owner.updatehealth()
@@ -479,14 +478,18 @@ This function completely restores a damaged organ to perfect condition.
//moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage (because of the return)
//Possibly trigger an internal wound, too.
var/local_damage = brute_dam + burn_dam + damage
if(damage > 15 && !(type in list(BURN, LASER)) && local_damage > 30 && !(status & ORGAN_ROBOT))
if(prob(damage) && sever_artery())
owner.custom_pain("You feel something rip in your [name]!", 25)
if(istype(tendon) && type == CUT && !(status & ORGAN_ROBOT))
var/DT = tendon.threshold
if(DT && local_damage > DT && damage > (DT / 2) && prob(damage))
tendon.sever()
if(damage > (min_broken_damage / 2) && local_damage > min_broken_damage && !(status & ORGAN_ROBOT))
if(!(type in list(BURN, LASER)))
if(prob(damage) && sever_artery())
owner.custom_pain("You feel something rip in your [name]!", 25)
if(istype(tendon) && type == CUT)
var/new_brute = damage
if(min_broken_damage - brute_dam > 0)
// Only pass on damage that goes over the broken threshold
new_brute = brute_dam + damage - min_broken_damage
tendon.damage(new_brute)
//Burn damage can cause fluid loss due to blistering and cook-off
if((type in list(BURN, LASER)) && (damage > 5 || damage + burn_dam >= 15) && !BP_IS_ROBOTIC(src))
@@ -831,6 +834,9 @@ Note that amputating the affected organ does in fact remove the infection from t
if (open && !clamped && (H && !(H.species.flags & NO_BLOOD)))
status |= ORGAN_BLEEDING
if (istype(tendon))
tendon.update_damage(cut_dam - min_broken_damage)
update_damage_ratios()
/obj/item/organ/external/proc/update_damage_ratios()
@@ -1163,9 +1169,9 @@ Note that amputating the affected organ does in fact remove the infection from t
/obj/item/organ/external/is_usable()
if(is_dislocated())
return FALSE
if(istype(tendon) && !tendon.intact)
if(tendon_status() & TENDON_CUT)
return FALSE
if(parent && (istype(parent.tendon) && !parent.tendon.intact))
if(parent && (parent.tendon_status() & TENDON_CUT))
return FALSE
if(can_feel_pain() && get_pain() > pain_disability_threshold)
return FALSE
@@ -1369,6 +1375,16 @@ Note that amputating the affected organ does in fact remove the infection from t
status |= ORGAN_ARTERY_CUT
return TRUE
/obj/item/organ/external/proc/tendon_status()
if(!(limb_flags & ORGAN_HAS_TENDON))
return
if(!istype(tendon))
// Somehow this limb should have a tendon but doesn't. Assume it was destroyed
return TENDON_CUT
return tendon.status
// Damage procs
/obj/item/organ/external/proc/get_brute_damage()
return brute_dam
+2 -2
View File
@@ -251,8 +251,8 @@
O.status &= ~ORGAN_ARTERY_CUT
owner.visible_message(SPAN_WARNING("The severed artery in \the [owner]'s [O] stitches itself back together..."), SPAN_NOTICE("The severed artery in your [O] stitches itself back together..."))
healed = TRUE
else if(istype(O.tendon) && !O.tendon.intact)
O.tendon.heal()
else if((O.tendon_status() & TENDON_CUT) && O.tendon.can_recover())
O.tendon.rejuvenate()
owner.visible_message(SPAN_WARNING("The severed tendon in \the [owner]'s [O] stitches itself back together..."), SPAN_NOTICE("The severed tendon in your [O] stitches itself back together..."))
healed = TRUE
else if(O.status & ORGAN_BROKEN)
+68 -14
View File
@@ -1,13 +1,14 @@
/datum/tendon
var/name = "tendon"
var/threshold
var/intact = TRUE
var/max_health = 30
var/health = 30
var/status
var/list/messages
var/obj/item/organ/external/parent
/datum/tendon/New(var/obj/item/organ/external/E, var/name, var/damage_threshold, var/list/damage_msgs)
/datum/tendon/New(var/obj/item/organ/external/E, var/name, var/hp, var/list/damage_msgs)
if(!istype(E))
crash_with("Tendon created with invalid parent organ: [E]")
qdel(src)
@@ -20,28 +21,81 @@
if(islist(damage_msgs))
messages = damage_msgs
if(damage_threshold)
threshold = damage_threshold
else
threshold = parent.min_broken_damage
if(hp)
max_health = hp
health = max_health
/datum/tendon/proc/heal()
if(!parent?.owner || intact)
/datum/tendon/proc/update_status(var/fix_cut = FALSE)
// determine if tendon should be cut, bruised, or unbruised
if(health <= 0 && !(status & TENDON_CUT))
sever()
else if(get_health() >= 0.5 && status & TENDON_BRUISED)
status &= ~TENDON_BRUISED
else if(get_health() < 0.5 && get_health() > 0 && !status)
status |= TENDON_BRUISED
if(parent.owner.species && parent.owner.can_feel_pain())
parent.owner.custom_pain("You feel a burning soreness in your [parent.name]!", 10, nohalloss = TRUE)
if(fix_cut && status & TENDON_CUT)
// fix_cut should only be TRUE through means like surgery, adv. tech, or space magic
status &= ~TENDON_CUT
/datum/tendon/proc/update_damage(var/total_dmg)
// called by organ/external/update_damages()
var/lost_health = max_health - health
if(total_dmg <= 0)
heal(max_health)
else
if(total_dmg < lost_health)
heal(lost_health - total_dmg)
else
damage(total_dmg - lost_health)
/datum/tendon/proc/get_health()
if(!parent?.owner)
return FALSE
. = intact = TRUE
return health / max_health
/datum/tendon/proc/can_recover()
// This is basically just used for the half-dozen times that tendons are "healed"
// using methods that may or may not heal the limb enough to actually heal the tendon
// thus, this prevents infinite tendon snapping
update_status()
if(status & TENDON_CUT)
return health > 0
return TRUE
/datum/tendon/proc/rejuvenate()
heal(max_health, TRUE)
/datum/tendon/proc/heal(var/hp, var/fix_cut)
if(!parent?.owner || hp <= 0)
return
health = min(max_health, health + hp)
update_status(fix_cut)
/datum/tendon/proc/damage(var/dmg)
if(!parent?.owner || health <= 0 || dmg <= 0)
return
health = max(0, health - dmg)
update_status()
/datum/tendon/proc/sever()
if(!parent?.owner || !intact)
if(!parent?.owner || (status & TENDON_CUT))
return FALSE
playsound(parent.owner.loc, 'sound/effects/snap.ogg', 40, 1, -2)
intact = FALSE
status |= TENDON_CUT
if(parent.owner.species && parent.owner.can_feel_pain())
parent.owner.emote("scream")
parent.owner.flash_strong_pain()
parent.owner.custom_pain("You feel something [pick(messages)] in your [parent.owner.name]!", 25)
parent.owner.custom_pain(FONT_LARGE("You feel something [pick(messages)] in your [parent.name]!"), 25)
parent.owner.visible_message(SPAN_WARNING("You hear a loud snapping sound coming from [parent.owner]!"),
blind_message = "You hear a sickening snap!")
else
@@ -52,4 +106,4 @@
if(istype(parent, /obj/item/organ/external/hand))
parent.owner.update_hud_hands()
return TRUE
return status