mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-23 13:05:44 +01:00
Tendon Health (#11826)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user