Refactor Get Pain (#22847)

This PR refactors get_pain() to be essentially performance free.
Previously it was a member of the top 5 most expensive procs.
I had to touch a metric shitton of files to make this happen. Notably
get_pain() was also 1/3rd of the entire processing cost for Mobs - Life
This commit is contained in:
VMSolidus
2026-08-19 22:50:40 +00:00
committed by GitHub
parent db385f9710
commit 40e88e0d2d
35 changed files with 212 additions and 119 deletions
+1
View File
@@ -63,6 +63,7 @@
#include "code\__DEFINES\empulse.dm"
#include "code\__DEFINES\evacuation.dm"
#include "code\__DEFINES\fabricators.dm"
#include "code\__DEFINES\fast_getters.dm"
#include "code\__DEFINES\feedback.dm"
#include "code\__DEFINES\flags.dm"
#include "code\__DEFINES\font_awesome_icons.dm"
+19
View File
@@ -0,0 +1,19 @@
// This file exists because SpacemanDMM doesn't support GET PRIVATE SET vars, only fully PRIVATE vars.
// And these macro getters allow us to bypass this limitation by simulating an "Aggressively Inlined Public Get"
// Which kills proc overhead.
// If you use these to Set the associated vars, I will destroy you.
/// Public Get for /obj/organ/external/VAR_PRIVATE/pain
#define LIMB_GET_PAIN(limb) UNLINT(limb.pain)
/// Public Get for /obj/organ/external/VAR_PRIVATE/brute_dam
#define LIMB_GET_BRUTE_DAMAGE(limb) UNLINT(limb.brute_dam)
/// Public Get for /obj/organ/external/VAR_PRIVATE/burn_dam
#define LIMB_GET_BURN_DAMAGE(limb) UNLINT(limb.burn_dam)
/// Public Get for /obj/organ/external/VAR_PRIVATE/genetic_degradation
#define LIMB_GET_GENETIC_DAMAGE(limb) UNLINT(limb.genetic_degradation)
/// Public Get for /obj/organ/external/VAR_PRIVATE/dislocated
#define LIMB_GET_DISLOCATED(limb) UNLINT(limb.dislocated)
+1 -1
View File
@@ -1,5 +1,5 @@
#define ORGAN_CAN_FEEL_PAIN(organ) !BP_IS_ROBOTIC(organ) && (!organ.species || !(organ.species.flags & NO_PAIN))
#define ORGAN_IS_DISLOCATED(organ) (organ.dislocated > 0)
#define ORGAN_IS_DISLOCATED(organ) (LIMB_GET_DISLOCATED(organ) > 0)
#define SOCKET_UNSHIELDED 0
#define SOCKET_SHIELDED 1
#define SOCKET_FULLSHIELDED 2
@@ -282,10 +282,10 @@
for(var/obj/item/organ/external/org in damaged)
var/limb_name = "[capitalize(org.name)][BP_IS_ROBOTIC(org) ? " (Cybernetic)" : ""]"
var/limb_result = ""
if(org.brute_dam > 0)
limb_result = " [SPAN_SCAN_DANGER("[get_wound_severity(org.brute_dam, (org.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)] physical trauma")]"
if(org.burn_dam > 0)
limb_result = "[limb_result][limb_result ? " | " : " "][SPAN_SCAN_ORANGE_DANGER("[get_wound_severity(org.burn_dam, (org.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)] burns")]"
if(LIMB_GET_BRUTE_DAMAGE(org) > 0)
limb_result = " [SPAN_SCAN_DANGER("[get_wound_severity(LIMB_GET_BRUTE_DAMAGE(org), (org.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)] physical trauma")]"
if(LIMB_GET_BURN_DAMAGE(org) > 0)
limb_result = "[limb_result][limb_result ? " | " : " "][SPAN_SCAN_ORANGE_DANGER("[get_wound_severity(LIMB_GET_BURN_DAMAGE(org), (org.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)] burns")]"
if(org.status & ORGAN_BLEEDING)
limb_result = "[limb_result][limb_result ? " | " : " "][SPAN_SCAN_DANGER("bleeding")]"
var/is_bandaged = org.is_bandaged()
@@ -330,7 +330,7 @@
var/found_disloc
for(var/obj/item/organ/external/e in H.organs)
if(e)
if(!found_disloc && e.dislocated == 2)
if(!found_disloc && LIMB_GET_DISLOCATED(e) == 2)
dat += SPAN_SCAN_WARNING("Dislocation detected. Advanced scanner required for location.")
found_disloc = TRUE
if(!found_bleed && (e.status & ORGAN_ARTERY_CUT))
@@ -30,7 +30,7 @@
if(ishuman(L))
var/mob/living/carbon/human/H = L
for(var/obj/item/organ/external/O in H.organs)
if(BP_IS_ROBOTIC(O) && (O.brute_dam || O.burn_dam))
if(BP_IS_ROBOTIC(O) && (LIMB_GET_BRUTE_DAMAGE(O) || LIMB_GET_BURN_DAMAGE(O)))
return TRUE
return FALSE
if(L.isSynthetic() && (L.getBruteLoss() || L.getFireLoss()))
@@ -53,12 +53,12 @@
var/mob/living/carbon/human/H = target
for(var/obj/item/organ/external/E in H.organs)
var/obj/item/organ/external/O = E
if(!BP_IS_ROBOTIC(O) || (!O.brute_dam && !O.burn_dam))
if(!BP_IS_ROBOTIC(O) || (!LIMB_GET_BRUTE_DAMAGE(O) && !LIMB_GET_BURN_DAMAGE(O)))
continue
var/previous_brute = O.brute_dam
var/previous_burn = O.burn_dam
var/previous_brute = LIMB_GET_BRUTE_DAMAGE(O)
var/previous_burn = LIMB_GET_BURN_DAMAGE(O)
O.heal_damage(4 * strength, 4 * strength, 0, TRUE)
if(O.brute_dam < previous_brute || O.burn_dam < previous_burn)
if(LIMB_GET_BRUTE_DAMAGE(O) < previous_brute || LIMB_GET_BURN_DAMAGE(O) < previous_burn)
repaired_damage = TRUE
else
if(M.isSynthetic())
+1 -1
View File
@@ -53,7 +53,7 @@ Contains:
return 1
if(affecting.status & ORGAN_LIFELIKE)
if(!(affecting.brute_dam || affecting.burn_dam))
if(!(LIMB_GET_BRUTE_DAMAGE(affecting) || LIMB_GET_BURN_DAMAGE(affecting)))
to_chat(user, SPAN_NOTICE("[target_mob] seems healthy, there are no wounds to treat! "))
return 1
+3 -3
View File
@@ -445,8 +445,8 @@
to_chat(user, SPAN_WARNING("You need to light the welding tool first!"))
return
if(S.brute_dam)
if(S.brute_dam > ROBOLIMB_SELF_REPAIR_CAP)
if(LIMB_GET_BRUTE_DAMAGE(S))
if(LIMB_GET_BRUTE_DAMAGE(S) > ROBOLIMB_SELF_REPAIR_CAP)
to_chat(user, SPAN_WARNING("The damage is far too severe to patch over externally!"))
return
else
@@ -458,7 +458,7 @@
return ..()
/obj/item/weldingtool/proc/repair_organ(var/mob/living/user, var/mob/living/carbon/human/target, var/obj/item/organ/external/affecting)
if(!affecting.brute_dam)
if(!LIMB_GET_BRUTE_DAMAGE(affecting))
user.visible_message(SPAN_NOTICE("\The [user] finishes repairing the physical damage on \the [target]'s [affecting.name]."))
return
@@ -536,9 +536,9 @@
for(var/obj/item/organ/external/O in H.organs)
var/list/data = list()
data["name"] = capitalize_first_letters(O.name)
var/burn_damage = get_wound_severity(O.burn_dam, (O.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)
var/burn_damage = get_wound_severity(LIMB_GET_BURN_DAMAGE(O), (O.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)
data["burn_damage"] = burn_damage
var/brute_damage = get_wound_severity(O.brute_dam, (O.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)
var/brute_damage = get_wound_severity(LIMB_GET_BRUTE_DAMAGE(O), (O.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)
data["brute_damage"] = brute_damage
var/list/wounds = list()
+1 -1
View File
@@ -42,7 +42,7 @@
/datum/martial_art/karak_virul/proc/dislocating_strike(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
A.do_attack_animation(D)
var/obj/item/organ/external/organ = D.get_organ(A.zone_sel.selecting)
if(!organ || ORGAN_IS_DISLOCATED(organ) || organ.dislocated == -1)
if(!organ || ORGAN_IS_DISLOCATED(organ) || LIMB_GET_DISLOCATED(organ) == -1)
return 0
organ.dislocate(1)
A.visible_message(SPAN_WARNING("[A] strikes [D]'s [organ.name] with their closed fist!"))
+1 -1
View File
@@ -68,7 +68,7 @@
A.do_attack_animation(D, ATTACK_EFFECT_CLAW)
var/obj/item/organ/external/organ = D.get_organ(A.zone_sel.selecting)
A.visible_message(SPAN_DANGER("[A] stabs [D]'s [organ.name] with their claws!"))
D.apply_damage(organ.brute_dam, DAMAGE_BRUTE, organ, damage_flags = DAMAGE_FLAG_SHARP|DAMAGE_FLAG_EDGE)
D.apply_damage(LIMB_GET_BRUTE_DAMAGE(organ), DAMAGE_BRUTE, organ, damage_flags = DAMAGE_FLAG_SHARP|DAMAGE_FLAG_EDGE)
return 1
/datum/martial_art/baghrar/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+4 -4
View File
@@ -55,10 +55,10 @@
blinded = 1
set_stat(UNCONSCIOUS)
if(getHalLoss() > 0)
adjustHalLoss(-3)
adjustHalLoss(-0.03)
if(sleeping)
adjustHalLoss(-3)
adjustHalLoss(-0.03)
if (mind)
if(mind.active && client != null)
sleeping = max(sleeping-1, 0)
@@ -66,12 +66,12 @@
set_stat(UNCONSCIOUS)
else if(resting)
if(getHalLoss() > 0)
adjustHalLoss(-3)
adjustHalLoss(-0.03)
else
set_stat(CONSCIOUS)
if(getHalLoss() > 0)
adjustHalLoss(-1)
adjustHalLoss(-0.01)
// Eyes and blindness.
if(!has_eyes())
+3 -3
View File
@@ -244,8 +244,8 @@
var/painful_check = FALSE
for(var/obj/item/organ/external/org in H.organs)
var/list/status = list()
var/brutedamage = org.brute_dam
var/burndamage = org.burn_dam
var/brutedamage = LIMB_GET_BRUTE_DAMAGE(org)
var/burndamage = LIMB_GET_BURN_DAMAGE(org)
// Basic Anatomy 1: All the obvious stuff
// Damaged and missing limbs
@@ -290,7 +290,7 @@
// Broken limbs
// Regular and arterial bleeding are vague
// Necrotic is vague
if(org.dislocated == 2)
if(LIMB_GET_DISLOCATED(org) == 2)
status += (anatomy >= 2 ? "dislocated" : "hanging oddly")
if(org.status & ORGAN_BROKEN)
status += (anatomy < 3 ? "hurts when touched" : "broken")
@@ -67,12 +67,12 @@
return
switch(params["action"])
if("brute")
var/damage_dealt = tgui_input_number(usr, "How much brute damage do you want to deal? (Current Brute: [L.brute_dam] | Current Burn; [L.burn_dam])", "Brute Damage")
var/damage_dealt = tgui_input_number(usr, "How much brute damage do you want to deal? (Current Brute: [LIMB_GET_BRUTE_DAMAGE(L)] | Current Burn; [LIMB_GET_BURN_DAMAGE(L)])", "Brute Damage")
if(damage_dealt)
L.take_damage(damage_dealt, 0)
log_and_message_admins("used the Damage Menu to deploy deal [damage_dealt] [params["action"]] to [H]'s [params["name"]]", usr, get_turf(H))
if("burn")
var/damage_dealt = tgui_input_number(usr, "How much burn damage do you want to deal? (Current Brute: [L.brute_dam] | Current Burn; [L.burn_dam])", "Burn Damage")
var/damage_dealt = tgui_input_number(usr, "How much burn damage do you want to deal? (Current Brute: [LIMB_GET_BRUTE_DAMAGE(L)] | Current Burn; [LIMB_GET_BURN_DAMAGE(L)])", "Burn Damage")
if(damage_dealt)
L.take_damage(0, damage_dealt)
log_and_message_admins("used the Damage Menu to deploy deal [damage_dealt] [params["action"]] to [H]'s [params["name"]]", usr, get_turf(H))
@@ -85,8 +85,8 @@
L.decrease_germ_level()
log_and_message_admins("used the Damage Menu to decrease the infection level of [H]'s [params["name"]]", usr, get_turf(H))
if("shatter")
if(L.brute_dam < L.min_broken_damage * GLOB.config.organ_health_multiplier)
L.take_damage(L.brute_dam + ((L.min_broken_damage * GLOB.config.organ_health_multiplier) - L.brute_dam))
if(LIMB_GET_BRUTE_DAMAGE(L) < L.min_broken_damage * GLOB.config.organ_health_multiplier)
L.take_damage(LIMB_GET_BRUTE_DAMAGE(L) + ((L.min_broken_damage * GLOB.config.organ_health_multiplier) - LIMB_GET_BRUTE_DAMAGE(L)))
L.fracture()
log_and_message_admins("used the Damage Menu to shatter [H]'s [params["name"]]", usr, get_turf(H))
if("arterial")
@@ -324,7 +324,7 @@
continue
var/thin_covering = (skipbody & body_part) ? TRUE : FALSE
if((temp.status & ORGAN_ASSISTED) && !thin_covering)
if(!(temp.brute_dam + temp.burn_dam) && !(temp.open))
if(!(LIMB_GET_BRUTE_DAMAGE(temp) + LIMB_GET_BURN_DAMAGE(temp)) && !(temp.open))
continue
else
wound_flavor_text["[temp.name]"] = SPAN_WARNING("[get_pronoun("He")] [get_pronoun("has")] [temp.get_wounds_desc()] on [get_pronoun("his")] [temp.name].<br>")
@@ -339,9 +339,9 @@
is_bleeding["[temp.name]"] = SPAN_DANGER("[get_pronoun("His")] [temp.name] is bleeding")+ "<br>"
else
wound_flavor_text["[temp.name]"] = ""
if(temp.dislocated == 2)
if(LIMB_GET_DISLOCATED(temp) == 2)
wound_flavor_text["[temp.name]"] += SPAN_WARNING("[get_pronoun("His")] [temp.joint] is dislocated!<br>")
if(((temp.status & ORGAN_BROKEN) && temp.brute_dam > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED))
if(((temp.status & ORGAN_BROKEN) && LIMB_GET_BRUTE_DAMAGE(temp) > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED))
wound_flavor_text["[temp.name]"] += SPAN_WARNING("[get_pronoun("His")] [temp.name] is dented and swollen!<br>")
//Handles the text strings being added to the actual description.
@@ -1882,7 +1882,7 @@
var/list/limbs = list()
for(var/limb in organs_by_name)
var/obj/item/organ/external/current_limb = organs_by_name[limb]
if(current_limb && current_limb.dislocated == 2)
if(current_limb && LIMB_GET_DISLOCATED(current_limb) == 2)
limbs |= limb
var/choice = tgui_input_list(usr, "Which joint do you wish to relocate?", "Relocate Joint", limbs)
@@ -629,7 +629,7 @@
if(!target_zone)
return 0
var/obj/item/organ/external/organ = get_organ(check_zone(target_zone))
if(!organ || ORGAN_IS_DISLOCATED(organ) || organ.dislocated == -1)
if(!organ || ORGAN_IS_DISLOCATED(organ) || LIMB_GET_DISLOCATED(organ) == -1)
return 0
user.visible_message(SPAN_WARNING("[user] begins to dislocate [src]'s [organ.joint]!"))
@@ -72,7 +72,7 @@
/mob/living/carbon/human/getHalLoss()
var/amount = 0
for(var/obj/item/organ/external/E in organs)
amount += E.get_pain()
amount += LIMB_GET_PAIN(E)
return amount
///These procs fetch a cumulative total damage from all organs
@@ -81,7 +81,7 @@
for(var/obj/item/organ/external/O in organs)
if(BP_IS_ROBOTIC(O) && !O.vital)
continue //robot limbs don't count towards shock and crit
amount += O.brute_dam
amount += LIMB_GET_BRUTE_DAMAGE(O)
return amount
/mob/living/carbon/human/getFireLoss()
@@ -89,7 +89,7 @@
for(var/obj/item/organ/external/O in organs)
if(BP_IS_ROBOTIC(O) && !O.vital)
continue //robot limbs don't count towards shock and crit
amount += O.burn_dam
amount += LIMB_GET_BURN_DAMAGE(O)
return amount
/mob/living/carbon/human/adjustBruteLoss(var/amount)
@@ -133,7 +133,7 @@
/mob/living/carbon/human/getCloneLoss()
var/amount = 0
for(var/obj/item/organ/external/E in organs)
amount += E.get_genetic_damage()
amount += LIMB_GET_GENETIC_DAMAGE(E)
return amount
/mob/living/carbon/human/setCloneLoss(var/amount)
@@ -286,7 +286,7 @@
continue
if(heal)
if(E.get_pain() > 0)
if(LIMB_GET_PAIN(E) > 0)
amount -= E.remove_pain(amount)
else
amount -= E.add_pain(amount)
@@ -309,7 +309,7 @@
for(var/obj/item/organ/external/O in organs)
if(!prosthetic && BP_IS_ROBOTIC(O))
continue
if((brute && O.brute_dam) || (burn && O.burn_dam))
if((brute && LIMB_GET_BRUTE_DAMAGE(O)) || (burn && LIMB_GET_BURN_DAMAGE(O)))
parts += O
return parts
@@ -360,13 +360,13 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
while(parts.len && (brute>0 || burn>0) )
var/obj/item/organ/external/picked = pick(parts)
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
var/brute_was = LIMB_GET_BRUTE_DAMAGE(picked)
var/burn_was = LIMB_GET_BURN_DAMAGE(picked)
update |= picked.heal_damage(brute,burn)
brute -= (brute_was-picked.brute_dam)
burn -= (burn_was-picked.burn_dam)
brute -= (brute_was - LIMB_GET_BRUTE_DAMAGE(picked))
burn -= (burn_was - LIMB_GET_BURN_DAMAGE(picked))
parts -= picked
updatehealth()
@@ -383,12 +383,12 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
while(parts.len && (brute>0 || burn>0) )
var/obj/item/organ/external/picked = pick(parts)
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
var/brute_was = LIMB_GET_BRUTE_DAMAGE(picked)
var/burn_was = LIMB_GET_BURN_DAMAGE(picked)
update = picked.take_damage(brute, burn, damage_flags, used_weapon) ? TRUE : FALSE
brute -= (picked.brute_dam - brute_was)
burn -= (picked.burn_dam - burn_was)
brute -= (LIMB_GET_BRUTE_DAMAGE(picked) - brute_was)
burn -= (LIMB_GET_BURN_DAMAGE(picked) - burn_was)
parts -= picked
updatehealth()
@@ -317,7 +317,7 @@ emp_act
return TRUE
/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/blocked)
if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1))
if(!organ || (LIMB_GET_DISLOCATED(organ) == 2) || (LIMB_GET_DISLOCATED(organ) == -1))
return 0
var/blocked_ratio = get_blocked_ratio(organ.limb_name, W.damtype, W.damage_flags(), W.armor_penetration, W.force)
@@ -8,7 +8,7 @@
var/damage_this_tick = getToxLoss()
var/arterial_check = 0
for(var/obj/item/organ/external/O in organs)
damage_this_tick += O.burn_dam + O.brute_dam
damage_this_tick += LIMB_GET_BURN_DAMAGE(O) + LIMB_GET_BRUTE_DAMAGE(O)
if(O.status & ORGAN_ARTERY_CUT)
arterial_check = 1
+4 -4
View File
@@ -843,7 +843,7 @@
sleeping_msg_debounce = TRUE
to_chat(src, EXAMINE_BLOCK_BLUE(SPAN_NOTICE(FONT_LARGE("You are now unconscious. You will not remember anything you see, hear, or feel happening around you until you regain consciousness."))))
adjustHalLoss(-3)
adjustHalLoss(-0.03)
if (species.tail)
animate_tail_reset()
if(prob(2) && is_asystole() && isSynthetic())
@@ -883,11 +883,11 @@
dizziness = max(0, dizziness - 15)
jitteriness = max(0, jitteriness - 15)
drowsiness = max(0, drowsiness - 5)
adjustHalLoss(-3)
adjustHalLoss(-0.03)
else
dizziness = max(0, dizziness - 3)
jitteriness = max(0, jitteriness - 3)
adjustHalLoss(-1)
adjustHalLoss(-0.01)
//Other
handle_statuses()
@@ -1013,7 +1013,7 @@
// Collect and apply the images all at once to avoid appearance churn.
var/list/health_images = list()
for(var/obj/item/organ/external/E in organs)
if(no_damage && (E.brute_dam || E.burn_dam))
if(no_damage && (LIMB_GET_BRUTE_DAMAGE(E) || LIMB_GET_BURN_DAMAGE(E)))
no_damage = 0
health_images += E.get_damage_hud_image()
@@ -95,7 +95,7 @@
H.custom_emote(VISIBLE_MESSAGE, "clutches [H.get_pronoun("his")] [damaged_organ.name], trying to stop the blood.")
else if(damaged_organ.status & ORGAN_BROKEN)
H.custom_emote(VISIBLE_MESSAGE, "holds [H.get_pronoun("his")] [damaged_organ.name] carefully.")
else if(damaged_organ.burn_dam > damaged_organ.brute_dam && damaged_organ.organ_tag != BP_HEAD)
else if(LIMB_GET_BURN_DAMAGE(damaged_organ) > LIMB_GET_BRUTE_DAMAGE(damaged_organ) && damaged_organ.organ_tag != BP_HEAD)
H.custom_emote(VISIBLE_MESSAGE, "blows on [H.get_pronoun("his")] [damaged_organ.name] carefully.")
else
H.custom_emote(VISIBLE_MESSAGE, "rubs [H.get_pronoun("his")] [damaged_organ.name] carefully.")
@@ -84,7 +84,7 @@
if(!(E.status & (ORGAN_ROBOT || ORGAN_ASSISTED)))
continue
organ_found = TRUE
to_chat(user, "[E.name]: <span class='warning'>[get_robot_severity(E.brute_dam)]</span> <font color='#FFA500'>[get_robot_severity(E.burn_dam)]</font>")
to_chat(user, "[E.name]: <span class='warning'>[get_robot_severity(LIMB_GET_BRUTE_DAMAGE(E))]</span> <font color='#FFA500'>[get_robot_severity(LIMB_GET_BURN_DAMAGE(E))]</font>")
if(!organ_found)
to_chat(user, SPAN_NOTICE("No prosthetics located."))
to_chat(user, "<hr>")
+1 -1
View File
@@ -51,7 +51,7 @@
return
var/obj/item/organ/external/organ = target.get_organ(check_zone(target_zone))
if(!organ || organ.dislocated == -1)
if(!organ || LIMB_GET_DISLOCATED(organ) == -1)
return
attacker.visible_message(SPAN_DANGER("[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!"))
@@ -87,8 +87,8 @@
data["robolimb_self_repair_cap"] = ROBOLIMB_SELF_REPAIR_CAP
data["limbs"] = list()
for(var/obj/item/organ/external/limb in ipc.organs)
if(limb.brute_dam || limb.burn_dam)
data["limbs"] += list(list("name" = limb.name, "brute_damage" = limb.brute_dam, "burn_damage" = limb.burn_dam, "max_damage" = limb.max_damage))
if(LIMB_GET_BRUTE_DAMAGE(limb) || LIMB_GET_BURN_DAMAGE(limb))
data["limbs"] += list(list("name" = limb.name, "brute_damage" = LIMB_GET_BRUTE_DAMAGE(limb), "burn_damage" = LIMB_GET_BURN_DAMAGE(limb), "max_damage" = limb.max_damage))
var/obj/item/organ/internal/machine/power_core/C = ipc.internal_organs_by_name[BP_CELL]
if(C)
+9 -9
View File
@@ -546,20 +546,20 @@
var/obj/item/organ/external/l_foot = get_organ(BP_L_FOOT)
var/obj/item/organ/external/r_foot = get_organ(BP_R_FOOT)
if(prob(50) && l_foot && l_foot.dislocated != -1)
if(prob(50) && l_foot && LIMB_GET_DISLOCATED(l_foot) != -1)
fall_message("left ankle", "bends unnaturally")
l_foot.dislocate(TRUE)
else if(r_foot && r_foot.dislocated != -1)
else if(r_foot && LIMB_GET_DISLOCATED(r_foot) != -1)
fall_message("right ankle", "bends unnaturally")
r_foot.dislocate(TRUE)
else if(prob(15))
var/obj/item/organ/external/l_leg = get_organ(BP_L_LEG)
var/obj/item/organ/external/r_leg = get_organ(BP_R_LEG)
if(prob(50) && l_leg && l_leg.dislocated != -1)
if(prob(50) && l_leg && LIMB_GET_DISLOCATED(l_leg) != -1)
fall_message("left knee", "caves in")
l_leg.dislocate(TRUE)
else if(r_leg && r_leg.dislocated != -1)
else if(r_leg && LIMB_GET_DISLOCATED(r_leg) != -1)
fall_message("right knee", "caves in")
l_leg.dislocate(TRUE)
@@ -589,20 +589,20 @@
var/obj/item/organ/external/l_hand = get_organ(BP_L_HAND)
var/obj/item/organ/external/r_hand = get_organ(BP_R_HAND)
if(prob(50) && l_hand && l_hand.dislocated != -1)
if(prob(50) && l_hand && LIMB_GET_DISLOCATED(l_hand) != -1)
fall_message("left wrist", "bends unnaturally")
l_hand.dislocate(TRUE)
else if(r_hand && r_hand.dislocated != -1)
else if(r_hand && LIMB_GET_DISLOCATED(r_hand) != -1)
fall_message("right wrist", "bends unnaturally")
r_hand.dislocate(TRUE)
else if(prob(15))
var/obj/item/organ/external/l_arm = get_organ(BP_L_ARM)
var/obj/item/organ/external/r_arm = get_organ(BP_R_ARM)
if(prob(50) && l_arm && l_arm.dislocated != -1)
if(prob(50) && l_arm && LIMB_GET_DISLOCATED(l_arm) != -1)
fall_message("left elbow", "caves in")
l_arm.dislocate(TRUE)
else if(r_arm && r_arm.dislocated != -1)
else if(r_arm && LIMB_GET_DISLOCATED(r_arm) != -1)
fall_message("right elbow", "caves in")
r_arm.dislocate(TRUE)
@@ -612,7 +612,7 @@
SPAN_DANGER("With a loud thud, you land on your head. Hard."), "You hear a thud!")
var/obj/item/organ/external/head = get_organ(BP_HEAD)
if(prob(20) && head && head.dislocated != -1)
if(prob(20) && head && LIMB_GET_DISLOCATED(head) != -1)
fall_message("jaw", "cracks loose")
head.dislocate(TRUE)
+98 -39
View File
@@ -31,9 +31,23 @@
//Damage variables. Do not modify brute_dam or burn_dam directly. Use take_damage.
///Actual current brute damage
var/brute_dam = 0
VAR_PRIVATE/brute_dam = 0
/// Amount of pain generated per point of brute damage
VAR_PROTECTED/pain_per_brute = 0.7
///Actual current burn damage
var/burn_dam = 0
VAR_PRIVATE/burn_dam = 0
/// Amount of pain generated per point of burn damage
VAR_PROTECTED/pain_per_burn = 0.8
/// Amount of current genetic damage
VAR_PRIVATE/genetic_degradation = 0
/// Amount of pain generated per point of genetic damage
VAR_PROTECTED/pain_per_genetic = 0.5
/// Amount of pain generated by a limb being dislocated
VAR_PROTECTED/pain_per_dislocation = 5
/// Stores whether or not this limb was broken during the last check.
VAR_PRIVATE/was_broken = FALSE
/// Amount of pain generated by a limb being dislocated
VAR_PROTECTED/pain_per_broken = 10
///Ratio of current brute damage to max damage
var/brute_ratio = 0
@@ -47,8 +61,6 @@
var/last_dam = -1
///Amount of current genetic damage
var/genetic_degradation = 0
///How much the limb hurts
VAR_PRIVATE/pain = 0
@@ -148,7 +160,7 @@
var/amputation_point
/// If the joint is dislocated
var/dislocated = FALSE
VAR_PROTECTED/dislocated = FALSE
/// How often wounds should be updated, a higher number means less often
var/wound_update_accuracy = 1
@@ -357,6 +369,7 @@
if(dislocated == -1)
return
add_pain(pain_per_dislocation)
START_PROCESSING(SSprocessing, src)
if(primary)
dislocated = 2
@@ -373,6 +386,7 @@
START_PROCESSING(SSprocessing, src)
dislocated = 0
remove_pain(pain_per_dislocation)
if(children && children.len)
for(var/obj/item/organ/external/child in children)
if(child.dislocated == 1)
@@ -652,6 +666,9 @@ This function completely restores a damaged organ to perfect condition.
perma_injury = 0
brute_dam = 0
burn_dam = 0
genetic_degradation = 0
if (pain)
remove_pain(pain)
germ_level = 0
QDEL_LIST(wounds)
number_wounds = 0
@@ -782,7 +799,7 @@ This function completely restores a damaged organ to perfect condition.
/obj/item/organ/external/proc/need_process()
if(BP_IS_ROBOTIC(src))
return surge_damage
if(get_pain() || status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_SPLINTED|ORGAN_DEAD|ORGAN_MUTATED|ORGAN_ARTERY_CUT) || brute_dam || burn_dam)
if(LIMB_GET_PAIN(src) || status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_SPLINTED|ORGAN_DEAD|ORGAN_MUTATED|ORGAN_ARTERY_CUT) || brute_dam || burn_dam || length(wounds) || was_broken)
return TRUE
if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up.
last_dam = brute_dam + burn_dam
@@ -802,6 +819,13 @@ This function completely restores a damaged organ to perfect condition.
// Process wounds, doing healing etc. Only do this every few ticks to save processing power
if(owner.life_tick % wound_update_accuracy == 0)
update_wounds()
var/broken = is_broken()
if (!was_broken && broken)
was_broken = TRUE
add_pain(pain_per_broken)
else if (was_broken && !broken)
was_broken = FALSE
remove_pain(pain_per_broken)
//Chem traces slowly vanish
if(owner.life_tick % 10 == 0)
@@ -1029,8 +1053,8 @@ Note that amputating the affected organ does in fact remove the infection from t
//Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status.
/obj/item/organ/external/proc/update_damages()
number_wounds = 0
brute_dam = 0
burn_dam = 0
var/new_brute_dam = 0
var/new_burn_dam = 0
var/cut_dam = 0
status &= ~ORGAN_BLEEDING
var/clamped = 0
@@ -1046,9 +1070,9 @@ Note that amputating the affected organ does in fact remove the infection from t
continue
if(W.damage_type == INJURY_TYPE_BURN)
burn_dam += W.damage
new_burn_dam += W.damage
else
brute_dam += W.damage
new_brute_dam += W.damage
if(W.damage_type == INJURY_TYPE_CUT)
cut_dam += W.damage
@@ -1059,6 +1083,18 @@ Note that amputating the affected organ does in fact remove the infection from t
number_wounds += W.amount
var/brute_difference = new_brute_dam - brute_dam
if (brute_difference)
if (brute_difference > 0)
add_brute_damage(brute_difference)
else remove_brute_damage(brute_difference)
var/burn_difference = new_burn_dam - burn_dam
if (burn_difference)
if (burn_difference > 0)
add_burn_damage(burn_difference)
else remove_burn_damage(burn_difference)
//things tend to bleed if they are CUT OPEN
if (open && !clamped && can_bleed)
status |= ORGAN_BLEEDING
@@ -1414,7 +1450,7 @@ Note that amputating the affected organ does in fact remove the infection from t
return FALSE
if(parent && (parent.tendon_status() & TENDON_CUT))
return FALSE
if(get_pain() > pain_disability_threshold)
if(LIMB_GET_PAIN(src) > pain_disability_threshold)
return FALSE
if(brute_ratio >= 100)
return FALSE
@@ -1663,34 +1699,60 @@ Note that amputating the affected organ does in fact remove the infection from t
return tendon.status
// Damage procs
/obj/item/organ/external/proc/get_brute_damage()
return brute_dam
/obj/item/organ/external/proc/add_brute_damage(amount)
if (amount <= 0)
return
/obj/item/organ/external/proc/get_burn_damage()
return burn_dam
brute_dam += amount
add_pain(amount * pain_per_brute)
/obj/item/organ/external/proc/get_genetic_damage()
return BP_IS_ROBOTIC(src) ? 0 : genetic_degradation
/obj/item/organ/external/proc/remove_brute_damage(amount)
if (amount <= 0)
return
brute_dam -= amount
remove_pain(amount * pain_per_brute)
/obj/item/organ/external/proc/add_burn_damage(amount)
if (amount <= 0)
return
burn_dam += amount
add_pain(amount * pain_per_burn)
/obj/item/organ/external/proc/remove_burn_damage(amount)
if (amount <= 0)
return
burn_dam -= amount
remove_pain(amount * pain_per_burn)
/obj/item/organ/external/proc/remove_genetic_damage(amount)
if (amount <= 0)
return
/obj/item/organ/external/proc/remove_genetic_damage(var/amount)
if(BP_IS_ROBOTIC(src) || (species.flags & NO_SCAN))
genetic_degradation = 0
status &= ~ORGAN_MUTATED
return
return FALSE
var/last_gene_dam = genetic_degradation
genetic_degradation = min(100,max(0,genetic_degradation - amount))
if(genetic_degradation <= 30)
if(status & ORGAN_MUTATED)
unmutate()
to_chat(src, SPAN_NOTICE("Your [name] is shaped normally again."))
return -(genetic_degradation - last_gene_dam)
var/difference = genetic_degradation - last_gene_dam
remove_pain(difference * pain_per_genetic)
return -difference
/obj/item/organ/external/proc/add_genetic_damage(amount)
if (amount <= 0)
return
/obj/item/organ/external/proc/add_genetic_damage(var/amount)
if(BP_IS_ROBOTIC(src) || (species.flags & NO_SCAN))
genetic_degradation = 0
status &= ~ORGAN_MUTATED
return
return FALSE
var/last_gene_dam = genetic_degradation
genetic_degradation = min(100,max(0,genetic_degradation + amount))
if(genetic_degradation > 10)
@@ -1699,22 +1761,16 @@ Note that amputating the affected organ does in fact remove the infection from t
if(!(status & ORGAN_MUTATED) && prob(genetic_degradation))
mutate()
to_chat(owner, SPAN_NOTICE("Something is not right with your [name]..."))
return (genetic_degradation - last_gene_dam)
// Pain/halloss
/obj/item/organ/external/proc/get_pain()
var/difference = genetic_degradation - last_gene_dam
add_pain(difference * pain_per_genetic)
return difference
/obj/item/organ/external/proc/remove_pain(amount)
if (amount <= 0)
return
if(!ORGAN_CAN_FEEL_PAIN(src) || BP_IS_ROBOTIC(src))
return 0
. = pain + 0.7 * brute_dam + 0.8 * burn_dam + 0.5 * get_genetic_damage()
if(is_broken())
. += 10
else if(ORGAN_IS_DISLOCATED(src))
. += 5
for(var/obj/item/organ/internal/I as anything in internal_organs)
. += 0.3 * I.getToxLoss()
/obj/item/organ/external/proc/remove_pain(var/amount)
if(!ORGAN_CAN_FEEL_PAIN(src))
pain = 0
return
var/last_pain = pain
@@ -1722,8 +1778,11 @@ Note that amputating the affected organ does in fact remove the infection from t
SEND_SIGNAL(src, COMSIG_UPDATE_LIMB_IMAGE)
return -(pain-last_pain)
/obj/item/organ/external/proc/add_pain(var/amount)
if(!ORGAN_CAN_FEEL_PAIN(src))
/obj/item/organ/external/proc/add_pain(amount)
if (amount <= 0)
return
if(!ORGAN_CAN_FEEL_PAIN(src) || BP_IS_ROBOTIC(src))
pain = 0
return
var/last_pain = pain
+1 -1
View File
@@ -402,7 +402,7 @@ GLOBAL_LIST_INIT(robot_hud_colours, list("#ffffff","#cccccc","#aaaaaa","#888888"
// Calculate the required color index.
var/dam_state = min(1,((brute_dam+burn_dam)/max(1,max_damage)))
var/min_dam_state = min(1,(get_pain()/max(1,max_damage)))
var/min_dam_state = min(1,(LIMB_GET_PAIN(src)/max(1,max_damage)))
if(min_dam_state && dam_state < min_dam_state)
dam_state = min_dam_state
// Apply colour and return product.
+1 -1
View File
@@ -69,7 +69,7 @@
if(maxdam > 50 && prob(maxdam / 5))
to_chat(src, SPAN_WARNING("A bolt of pain shoots through your body, causing your hands to spasm!"))
drop_item()
var/burning = damaged_organ.burn_dam > damaged_organ.brute_dam
var/burning = LIMB_GET_BURN_DAMAGE(damaged_organ) > LIMB_GET_BRUTE_DAMAGE(damaged_organ)
var/msg
switch(maxdam)
if(1 to 10)
+10
View File
@@ -81,6 +81,12 @@
/datum/wound/Destroy()
if(parent_organ)
// Clear any leftover damage from parent limb.
if (damage)
if (damage_type == INJURY_TYPE_BURN)
parent_organ.remove_burn_damage(damage)
else parent_organ.remove_brute_damage(damage)
LAZYREMOVE(parent_organ.wounds, src)
parent_organ = null
LAZYCLEARLIST(embedded_objects)
@@ -183,6 +189,10 @@
var/healed_damage = min(src.damage, amount)
amount -= healed_damage
src.damage -= healed_damage
if (parent_organ)
if (damage_type == INJURY_TYPE_BURN)
parent_organ.remove_burn_damage(healed_damage)
else parent_organ.remove_brute_damage(healed_damage)
while((src.damage / src.amount) < damage_list[current_stage] && current_stage < length(src.desc_list))
current_stage++
+3 -3
View File
@@ -604,8 +604,8 @@ By design, d1 is the smallest direction and d2 is the highest
to_chat(user, SPAN_WARNING("You can't repair damage to your own body - it's against OH&S."))
return
if(S.burn_dam)
if(S.burn_dam > ROBOLIMB_SELF_REPAIR_CAP)
if(LIMB_GET_BURN_DAMAGE(S))
if(LIMB_GET_BURN_DAMAGE(S) > ROBOLIMB_SELF_REPAIR_CAP)
to_chat(user, SPAN_WARNING("The damage is far too severe to patch over externally!"))
return
else
@@ -618,7 +618,7 @@ By design, d1 is the smallest direction and d2 is the highest
return ..()
/obj/item/stack/cable_coil/proc/repair_organ(var/mob/living/user, var/mob/living/carbon/human/target, var/obj/item/organ/external/affecting)
if(!affecting.burn_dam)
if(!LIMB_GET_BURN_DAMAGE(affecting))
user.visible_message(SPAN_NOTICE("\The [user] finishes mending the burnt wiring in [target]'s [affecting]."))
return
+1 -1
View File
@@ -405,7 +405,7 @@
if(ishuman(G.affecting))
var/mob/living/carbon/human/human_shield = G.affecting
var/obj/item/organ/external/organ = human_shield.get_organ(def_zone)
if(organ.burn_dam + organ.brute_dam > organ.max_damage) //If the hit zone is above the max damage threshold, the shot hits both.
if(LIMB_GET_BURN_DAMAGE(organ) + LIMB_GET_BRUTE_DAMAGE(organ) > organ.max_damage) //If the hit zone is above the max damage threshold, the shot hits both.
penetrating += 1
projectile_piercing = PASSMOB
pierce_chance = 100
+1 -1
View File
@@ -108,7 +108,7 @@
to_chat(user, SPAN_NOTICE("You flow your regenerative psionic energy through the flesh of their [external_organ.name]..."))
if(!do_mob(user, H, 10 SECONDS / effect_multiplier) || !pay_energy(20))
return
external_organ.heal_damage(external_organ.get_brute_damage(), external_organ.get_burn_damage(), internal = FALSE, robo_repair = FALSE)
external_organ.heal_damage(LIMB_GET_BRUTE_DAMAGE(external_organ), LIMB_GET_BURN_DAMAGE(external_organ), internal = FALSE, robo_repair = FALSE)
to_chat(user, SPAN_NOTICE("You mend their [external_organ.name]'s flesh."))
for(var/datum/wound/W as anything in external_organ.wounds)
if(LAZYLEN(W.embedded_objects))
+2 -2
View File
@@ -202,7 +202,7 @@
var/obj/item/weldingtool/welder = tool
if(!welder.isOn() || welder.get_fuel() < 2)
return FALSE
return affected && affected.open == ORGAN_ENCASED_RETRACTED && affected.brute_dam > 0 && target_zone != BP_MOUTH
return affected && affected.open == ORGAN_ENCASED_RETRACTED && LIMB_GET_BRUTE_DAMAGE(affected) > 0 && target_zone != BP_MOUTH
/singleton/surgery_step/robotics/repair_brute/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
@@ -243,7 +243,7 @@
var/obj/item/stack/cable_coil/C = tool
var/obj/item/organ/external/affected = target.get_organ(target_zone)
var/limb_can_operate = (affected && affected.open == ORGAN_ENCASED_RETRACTED && affected.burn_dam > 0 && target_zone != BP_MOUTH)
var/limb_can_operate = (affected && affected.open == ORGAN_ENCASED_RETRACTED && LIMB_GET_BURN_DAMAGE(affected) > 0 && target_zone != BP_MOUTH)
if(limb_can_operate)
if(istype(C))
if(!C.get_amount() >= 6)
+2 -2
View File
@@ -60,8 +60,8 @@
data["robolimb_self_repair_cap"] = ROBOLIMB_SELF_REPAIR_CAP
data["limbs"] = list()
for(var/obj/item/organ/external/limb in ipc.organs)
if(limb.brute_dam || limb.burn_dam)
data["limbs"] += list(list("name" = limb.name, "brute_damage" = edit_organ_status(limb.brute_dam, diagnostics), "burn_damage" = edit_organ_status(limb.burn_dam, diagnostics), "max_damage" = limb.max_damage))
if(LIMB_GET_BRUTE_DAMAGE(limb) || LIMB_GET_BRUTE_DAMAGE(limb))
data["limbs"] += list(list("name" = limb.name, "brute_damage" = edit_organ_status(LIMB_GET_BRUTE_DAMAGE(limb), diagnostics), "burn_damage" = edit_organ_status(LIMB_GET_BURN_DAMAGE(limb), diagnostics), "max_damage" = limb.max_damage))
var/obj/item/organ/internal/machine/power_core/C = ipc.internal_organs_by_name[BP_CELL]
if(C)
@@ -0,0 +1,4 @@
author: Hellfirejag
delete-after: True
changes:
- refactor: "Refactored get_pain() to have essentially nonexistent cost."