Nuke Limb Processing (#22814)

<img width="1549" height="857" alt="image"
src="https://github.com/user-attachments/assets/3830233d-0635-4942-b2aa-024651e6cffa"
/>

Limbs make up roughly half of the "Per additional player" processing
overhead, while Organs make up most of the other half.
Not every organ is an easy candidate for "Event-only processing", but
external limbs are significantly easier to do so.

So this PR makes it so that External Limbs no longer require Processing
unless an event happens that would justify them requiring processing.
Which SIGNIFICANTLY reduces the overall additional cost to the
Processing subsystem per player that joins the server.

Oh and I also made the Appendix and Kidneys not require constant
processing. The Appendix will only process if it is hit by an
Appendicitis event, and the Kidneys will only process if they are either
damaged, or you get poisoned.
This commit is contained in:
VMSolidus
2026-07-12 20:45:24 +00:00
committed by GitHub
parent 48d8a06d1c
commit e117ef3f87
44 changed files with 310 additions and 216 deletions
@@ -11,4 +11,5 @@
continue
A.inflamed = 1
A.update_icon()
START_PROCESSING(SSprocessing, A)
break
+1 -1
View File
@@ -87,7 +87,7 @@
if(!B.can_prepare)
to_chat(user, SPAN_WARNING("\The [B] is incompatible with [src]!"))
return
if(B.damage >= B.max_damage)
if(B.get_damage() >= B.max_damage)
to_chat(user, SPAN_WARNING("That brain is well and truly dead."))
return
else if(!B.brainmob)
+3 -3
View File
@@ -256,16 +256,16 @@ and some alternative things that are toxic to other life, such as radium and mut
if (life_tick % LIFETICK_INTERVAL_LESS == 0)
if (bad_internal_organs.len)
for (var/obj/item/organ/O in bad_internal_organs)
var/CL = O.damage
var/CL = O.get_damage()
var/value
if(total_radiation > 0)
value = min(CL, total_radiation, 2 * DS.healing_factor * LIFETICK_INTERVAL_LESS)
O.damage += value/-1.5
O.add_damage(value/-1.5)
total_radiation -= value
CL = getCloneLoss()
value = min(CL, DS.stored_energy, 1 * DS.healing_factor * LIFETICK_INTERVAL_LESS)
O.damage += value/-3
O.add_damage(value/-3)
DS.stored_energy -= value
//Last up, growing brand new limbs and organs to replace those lost or removed.
@@ -114,9 +114,10 @@
if(!O)
to_chat(usr, SPAN_WARNING("\The [H] doesn't have that organ!"))
return
var/organ_damage = O.get_damage()
switch(params["action"])
if("damage")
var/damage_dealt = tgui_input_number(usr, "How much damage do you want to deal? (Current Damage: [O.damage])", "Brute Damage")
var/damage_dealt = tgui_input_number(usr, "How much damage do you want to deal? (Current Damage: [organ_damage])", "Brute Damage")
if(damage_dealt)
O.take_internal_damage(damage_dealt)
log_and_message_admins("used the Damage Menu to deal [damage_dealt] [params["action"]] to [H]'s [params["name"]]", usr, get_turf(H))
@@ -129,12 +130,12 @@
O.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("bruise")
if(O.damage < O.min_bruised_damage)
O.take_damage(O.damage + (O.min_bruised_damage - O.damage) + 1)
if(organ_damage < O.min_bruised_damage)
O.take_damage(organ_damage + (O.min_bruised_damage - organ_damage) + 1)
log_and_message_admins("used the Damage Menu to bruise [H]'s [params["name"]]", usr, get_turf(H))
if("break")
if(O.damage < O.min_broken_damage)
O.take_damage(O.damage + (O.min_broken_damage - O.damage) + 1)
if(organ_damage < O.min_broken_damage)
O.take_damage(organ_damage + (O.min_broken_damage - organ_damage) + 1)
log_and_message_admins("used the Damage Menu to break [H]'s [params["name"]]", usr, get_turf(H))
if("remove")
O.removed(H)
@@ -1128,7 +1128,7 @@
..()
if(should_have_organ(BP_STOMACH))
var/obj/item/organ/internal/stomach/stomach = internal_organs_by_name[BP_STOMACH]
if(!stomach || stomach.is_broken() || (stomach.is_bruised() && prob(stomach.damage)))
if(!stomach || stomach.is_broken() || (stomach.is_bruised() && prob(stomach.get_damage())))
if(should_have_organ(BP_HEART))
vessel.trans_to_obj(vomit, 5)
else
@@ -44,7 +44,7 @@
if(should_have_organ(BP_BRAIN) && internal_organs_by_name)
var/obj/item/organ/internal/brain/sponge = internal_organs_by_name[BP_BRAIN]
if(sponge)
sponge.damage = min(max(amount, 0),sponge.species.total_health)
sponge.set_damage(min(max(amount, 0),sponge.species.total_health))
updatehealth()
/mob/living/carbon/human/getBrainLoss()
@@ -63,7 +63,7 @@
if(sponge.status & ORGAN_DEAD)
return sponge.species.total_health
else
return sponge.damage
return sponge.get_damage()
else
return species.total_health
return 0
@@ -223,6 +223,9 @@
if(kidneys)
pick_organs -= kidneys
pick_organs.Insert(1, kidneys)
if (!heal)
// Kindly inform the kidneys that there's going to be poison to remove. :)
START_PROCESSING(SSprocessing, kidneys)
var/obj/item/organ/internal/liver/liver = null
@@ -247,15 +250,16 @@
break
if(BP_IS_ROBOTIC(I))
continue //Chems won't help, you need surgery to fix robot organs
var/organ_damage = I.get_damage()
if(heal)
if(I.damage < amount)
amount -= I.damage
I.damage = 0
if(organ_damage < amount)
amount -= organ_damage
I.set_damage(0)
else
I.damage -= amount
I.add_damage(-amount)
amount = 0
else
var/cap_dam = I.max_damage - I.damage
var/cap_dam = I.max_damage - organ_damage
if(amount >= cap_dam)
I.take_internal_damage(cap_dam, silent=TRUE)
amount -= cap_dam
@@ -195,7 +195,7 @@
if(!brain || stat == DEAD || (status_flags & FAKEDEATH))
brain_result = 0
else if(stat != DEAD)
brain_result = round(max(0,(1 - brain.damage/brain.max_damage)*100))
brain_result = round(max(0,(1 - brain.get_damage()/brain.max_damage)*100))
else
brain_result = -1
return brain_result
+1 -1
View File
@@ -470,7 +470,7 @@
for(var/obj/item/organ/external/O in organs)
if(QDELETED(O))
continue
if((O.damage + LOW_PRESSURE_DAMAGE) < O.max_damage)
if((O.get_damage() + LOW_PRESSURE_DAMAGE) < O.max_damage)
O.take_damage(brute = LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
if(getOxyLoss() < 55)
adjustOxyLoss(4)
@@ -103,7 +103,7 @@
for(var/obj/item/organ/I in H.internal_organs)
if((I.status & ORGAN_DEAD) || BP_IS_ROBOTIC(I))
continue
if(I.damage > 2)
if(I.get_damage() > 2)
if(prob(2))
var/obj/item/organ/external/parent = H.get_organ(I.parent_organ)
H.custom_emote(VISIBLE_MESSAGE, "clutches [H.get_pronoun("his")] [parent.name]!")
@@ -506,5 +506,5 @@
if(istype(voice_synth))
if(voice_synth.is_bruised())
// at most, 30 * 2 + 10 = 70, which is the maximum value we can use for Gibberish
message = Gibberish(message, voice_synth.damage * 2 + (voice_synth.is_broken() ? 10 : 0))
message = Gibberish(message, voice_synth.get_damage() * 2 + (voice_synth.is_broken() ? 10 : 0))
return list(HSP_MSG = message, HSP_VERB = pick(list("crackles", "buzzes")))
+2 -2
View File
@@ -557,8 +557,8 @@ default behaviour is:
if(repair_brain && should_have_organ(BP_BRAIN))
repair_brain = FALSE
var/obj/item/organ/internal/brain/brain = internal_organs_by_name[BP_BRAIN]
if(brain.damage > (brain.max_damage/2))
brain.damage = (brain.max_damage/2)
if(brain.get_damage() > (brain.max_damage/2))
brain.set_damage(brain.max_damage/2)
if(brain.status & ORGAN_DEAD)
brain.status &= ~ORGAN_DEAD
START_PROCESSING(SSprocessing, brain)
@@ -107,7 +107,7 @@
if(machine_organ.get_integrity() < 100)
to_chat(user, "<font color='#FFA500'><b>[machine_organ.name]:</b> Integrity damage detected.</font>")
found_damage = TRUE
else if(O.damage)
else if(O.get_damage())
to_chat(user, SPAN_WARNING("<b>[O.name]:</b> Core damage detected."))
found_damage = TRUE
if(!found_damage)
@@ -79,7 +79,7 @@
organ_data["name"] = organ.name
organ_data["desc"] = organ.desc
organ_data["damage"] = organ.damage
organ_data["damage"] = organ.get_damage()
organ_data["max_damage"] = organ.max_damage
data["organs"] += list(organ_data)
+1 -1
View File
@@ -111,7 +111,7 @@
pulse_mod *= heart.too_fast_pump_modifier
if(PULSE_THREADY)
pulse_mod *= heart.thready_pump_modifier
blood_volume *= pulse_mod * max(min_efficiency, (1-(heart.damage / heart.max_damage)))
blood_volume *= pulse_mod * max(min_efficiency, (1-(heart.get_damage() / heart.max_damage)))
return min(blood_volume, 100)
+4 -6
View File
@@ -39,20 +39,17 @@
return ..()
/// Sets the internal organ as belonging to the targeted external organ, and matches the target's species/robotness. Also updates all organ lists belonging to the owner.
/obj/item/organ/internal/replaced(var/mob/living/carbon/human/target, var/obj/item/organ/external/affected)
if(!istype(target))
return 0
/obj/item/organ/internal/replaced(mob/living/carbon/human/target, obj/item/organ/external/affected)
. = ..()
// robotic organs emulate behavior of the equivalent flesh organ of the species
if(BP_IS_ROBOTIC(src) || !species)
species = target.species
..()
target.internal_organs |= src
affected.internal_organs |= src
target.internal_organs_by_name[organ_tag] = src
return 1
return TRUE
/obj/item/organ/internal/die()
..()
@@ -121,6 +118,7 @@
min_bruised_damage = FLOOR(0.25 * max_damage, 1)
/obj/item/organ/internal/proc/take_internal_damage(amount, var/silent=0)
START_PROCESSING(SSprocessing, src)
if(BP_IS_ROBOTIC(src))
damage = between(0, src.damage + (amount * 0.8), max_damage)
else
+8 -1
View File
@@ -21,6 +21,13 @@
/// The amount of damage an appendix takes per second while in stage 2 of appendicitis.
var/stage_two_organ_damage_per_second = 0.006
/**
* Override so that the appendix will never process on its own.
* It is instead added to processing via the spontaneous_appendicitis event.
*/
/obj/item/organ/internal/appendix/process_initialize()
return
/obj/item/organ/internal/appendix/update_icon()
..()
if(inflamed)
@@ -30,7 +37,7 @@
/obj/item/organ/internal/appendix/process(seconds_per_tick)
..()
if(!owner || !inflamed || !BP_IS_ROBOTIC(src))
return
return PROCESS_KILL
if(owner.stasis_value > 0)
// Decrease the effective tickrate when in stasis.
+6 -3
View File
@@ -43,9 +43,9 @@
var/dead_toxin_accumulation_per_second = 0.66
/obj/item/organ/internal/kidneys/process(seconds_per_tick)
..()
if(!owner)
return
. = ..()
if(. == PROCESS_KILL || !owner)
return PROCESS_KILL
if(owner.stasis_value > 0) // Decrease the effective tickrate when in stasis.
seconds_per_tick /= owner.stasis_value
@@ -72,3 +72,6 @@
owner.adjustToxLoss(broken_toxin_accumulation_per_second * seconds_per_tick)
if(status & ORGAN_DEAD)
owner.adjustToxLoss(dead_toxin_accumulation_per_second * seconds_per_tick)
if (!owner.getToxLoss() && !damage) // None of the conditions triggered, therefore we have healthy kidneys that we don't care about.
return PROCESS_KILL
+35 -4
View File
@@ -16,7 +16,11 @@
var/death_time
//Organ damage stats.
var/damage = 0 // amount of damage to the organ
/**
* amount of damage to the organ. THIS IS PRIVATE FOR A REASON.
* USE get_damage and set_damage IF YOU NEED TO CHANGE OR RETRIEVE THIS.
*/
VAR_PRIVATE/damage = 0
/// Total amount of EMP damage a mechanical organ has taken. Effectively equal to "number of seconds the organ EMP effect will last".
var/surge_damage = 0.0
/**
@@ -83,8 +87,14 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
blood_DNA[dna.unique_enzymes] = dna.b_type
if(internal)
holder.internal_organs |= src
START_PROCESSING(SSprocessing, src)
process_initialize()
/**
* This proc exists so that organs which do not require "always processing" can override it
* in order to opt-out of processing for performance reasons.
*/
/obj/item/organ/proc/process_initialize()
START_PROCESSING(SSprocessing, src)
/obj/item/organ/Destroy()
STOP_PROCESSING(SSprocessing, src)
@@ -142,6 +152,7 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
return damage >= min_bruised_damage
/obj/item/organ/proc/bruise()
START_PROCESSING(SSprocessing, src)
damage = max(damage, min_bruised_damage)
#define ORGAN_RECOVERY_THRESHOLD (5 MINUTES)
@@ -205,15 +216,22 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
if(damage >= max_damage)
die()
/**
* Handles per-second EMP damage effects.
* returns FALSE if there's no EMP effects left.
* returns "Truthy" if there's still more EMP to handle on the next tick.
* It will wrap back around to FALSE if the surge damage recovery ticked it back down to 0.
*/
/obj/item/organ/proc/tick_surge_damage(seconds_per_tick)
ENFORCE_CALCULUS(seconds_per_tick)
if(!surge_damage)
clear_surge_effects()
return
return FALSE
do_surge_effects()
surge_damage = max(0, surge_damage - (surge_recovery_per_second * seconds_per_tick))
return surge_damage
/obj/item/organ/proc/do_surge_effects()
return
@@ -485,7 +503,7 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
forceMove(owner) //just in case
if(BP_IS_ROBOTIC(src))
set_dna(owner.dna)
return 1
return TRUE
/obj/item/organ/internal/eyes/replaced(var/mob/living/carbon/human/target)
@@ -524,3 +542,16 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
//used by stethoscope
/obj/item/organ/proc/listen()
return
/obj/item/organ/proc/get_damage()
return damage
/obj/item/organ/proc/set_damage(to_set)
damage = to_set
START_PROCESSING(SSprocessing, src)
/obj/item/organ/add_damage(to_add)
START_PROCESSING(SSprocessing, src)
if (..(to_add))
return
damage += to_add
+58 -63
View File
@@ -192,8 +192,6 @@
var/is_emissive = FALSE
/// Whether the limb has an active overlay icon state associated with it
var/is_overlay = FALSE
/// Whether the limb is a tesla limb (required for special handling)
var/is_tesla = FALSE
/obj/item/organ/external/Initialize(mapload)
if(robotize_type)
@@ -226,7 +224,6 @@
limb_flags &= ~ORGAN_HAS_TENDON
/obj/item/organ/external/Destroy()
if(parent?.children)
parent.children -= src
@@ -359,6 +356,8 @@
/obj/item/organ/external/proc/dislocate(var/primary)
if(dislocated == -1)
return
START_PROCESSING(SSprocessing, src)
if(primary)
dislocated = 2
else
@@ -372,6 +371,7 @@
if(dislocated == -1)
return
START_PROCESSING(SSprocessing, src)
dislocated = 0
if(children && children.len)
for(var/obj/item/organ/external/child in children)
@@ -385,11 +385,12 @@
remove_verb(owner, /mob/living/carbon/human/proc/undislocate)
/obj/item/organ/external/update_organ_health()
START_PROCESSING(SSprocessing, src)
damage = min(max_damage, (brute_dam + burn_dam))
/obj/item/organ/external/replaced(var/mob/living/carbon/human/target)
..()
/obj/item/organ/external/replaced(mob/living/carbon/human/target)
. = ..()
START_PROCESSING(SSprocessing, src)
if(istype(owner))
owner.organs_by_name[limb_name] = src
owner.organs |= src
@@ -438,11 +439,12 @@
brute = round(brute * brute_mod, 0.1)
burn = round(burn * burn_mod, 0.1)
if((brute <= 0) && (burn <= 0))
return 0
return FALSE
if(damage_flags & DAMAGE_FLAG_IGNORE_PROSTHETICS && BP_IS_ROBOTIC(src))
return 0
return FALSE
START_PROCESSING(SSprocessing, src)
var/laser = (damage_flags & DAMAGE_FLAG_LASER)
var/sharp = (damage_flags & DAMAGE_FLAG_SHARP)
var/edge = (damage_flags & DAMAGE_FLAG_EDGE)
@@ -548,7 +550,7 @@
var/list/victims = list()
var/organ_hit_chance = 0
for(var/obj/item/organ/internal/I in internal_organs)
if(I.damage < I.max_damage)
if(I.get_damage() < I.max_damage)
victims[I] = I.relative_size
organ_hit_chance += I.relative_size
@@ -569,6 +571,7 @@
var/obj/item/organ/internal/victim = pickweight(victims)
damage_amt -= max(damage_amt*victim.damage_reduction, 0)
victim.take_internal_damage(damage_amt)
START_PROCESSING(SSprocessing, src)
return TRUE
/obj/item/organ/external/proc/handle_limb_gibbing(var/used_weapon, var/brute, var/burn)
@@ -628,7 +631,7 @@
SEND_SIGNAL(src, COMSIG_UPDATE_LIMB_IMAGE)
owner.updatehealth()
START_PROCESSING(SSprocessing, src)
return update_icon()
/*
@@ -658,12 +661,12 @@ This function completely restores a damaged organ to perfect condition.
tendon.rejuvenate()
owner.updatehealth()
START_PROCESSING(SSprocessing, src)
/obj/item/organ/external/proc/createwound(type = INJURY_TYPE_CUT, damage)
if(damage <= 0 || !owner)
return
START_PROCESSING(SSprocessing, src)
//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
@@ -768,70 +771,50 @@ This function completely restores a damaged organ to perfect condition.
//Determines if we even need to process this organ.
/obj/item/organ/external/proc/need_process()
if(BP_IS_ROBOTIC(src) && surge_damage)
return TRUE
if(is_tesla && owner)
return TRUE
if(BP_IS_ROBOTIC(src))
return FALSE
if(get_pain())
return TRUE
if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_SPLINTED|ORGAN_DEAD|ORGAN_MUTATED))
return TRUE
if(brute_dam || burn_dam)
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)
return TRUE
if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up.
last_dam = brute_dam + burn_dam
return TRUE
else
last_dam = brute_dam + burn_dam
if(germ_level)
return TRUE
return FALSE
return germ_level
/obj/item/organ/external/process(seconds_per_tick)
if(owner)
//Specialized handling for tesla limbs. Checks if the limb currently has an associated tesla spine. Else, will disable the emissive and active overlays
if(is_tesla)
var/obj/item/organ/internal/augment/tesla/T = owner.internal_organs_by_name[BP_AUG_TESLA]
if(T && !T.is_broken())
is_emissive = initial(is_emissive)
is_overlay = initial(is_overlay)
else
is_emissive = FALSE
is_overlay = FALSE
return
. = ..()
if (!need_process())
return PROCESS_KILL
// 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()
if(!owner)
return
//Chem traces slowly vanish
if(owner.life_tick % 10 == 0)
for(var/chemID in trace_chemicals)
trace_chemicals[chemID] = trace_chemicals[chemID] - 1
if(trace_chemicals[chemID] <= 0)
trace_chemicals.Remove(chemID)
// 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()
if(!(status & ORGAN_BROKEN))
perma_injury = 0
//Chem traces slowly vanish
if(owner.life_tick % 10 == 0)
for(var/chemID in trace_chemicals)
trace_chemicals[chemID] = trace_chemicals[chemID] - 1
if(trace_chemicals[chemID] <= 0)
trace_chemicals.Remove(chemID)
if(status & ORGAN_NYMPH)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
if(!(status & ORGAN_BROKEN))
perma_injury = 0
if(surge_damage && (status & ORGAN_ASSISTED))
tick_surge_damage(seconds_per_tick) //Yes, this being here is intentional since this proc does not call ..() unless the owner is null.
if(surge_damage && (status & ORGAN_ASSISTED))
tick_surge_damage(seconds_per_tick) //Yes, this being here is intentional since this proc does not call ..() unless the owner is null.
//Infections
update_germs()
//Infections
update_germs()
//check if an online RIG can splint the broken bone
check_rigsplints()
else
..()
//check if an online RIG can splint the broken bone
check_rigsplints()
/obj/item/organ/external/do_surge_effects()
START_PROCESSING(SSprocessing, src)
if(prob(surge_damage))
owner.custom_pain("The artificial nerves in your [name] scream out in pain!", surge_damage/6)
@@ -898,6 +881,7 @@ Note that amputating the affected organ does in fact remove the infection from t
for(var/datum/wound/W as anything in wounds)
//Open wounds can become infected
if (owner.germ_level > W.germ_level && W.infection_check())
START_PROCESSING(SSprocessing, src)
W.germ_level++
if(!increased_own_germs && antibiotics < 5 && W.germ_level > germ_level)
germ_level++
@@ -928,6 +912,7 @@ Note that amputating the affected organ does in fact remove the infection from t
infect_target_external = null
return ..()
START_PROCESSING(SSprocessing, src)
germ_level++
if(germ_level >= INFECTION_LEVEL_TWO && REAGENT_VOLUME(owner.reagents, /singleton/reagent/thetamycin) < 5) //The presence of 5 units of thetamycin will stop infections spreading
@@ -1293,6 +1278,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(QDELETED(owner))
return
START_PROCESSING(SSprocessing, src)
if(!silent)
var/message = pick("broke in half", "shattered")
owner.visible_message(\
@@ -1358,9 +1344,13 @@ Note that amputating the affected organ does in fact remove the infection from t
else
is_overlay = FALSE
if(R.is_tesla)
is_tesla = TRUE
else
is_tesla = FALSE
// We don't know if the tesla limb or the tesla spine spawned first.
// So both will attempt to check for each other once during init.
var/obj/item/organ/internal/augment/tesla/T = owner?.internal_organs_by_name[BP_AUG_TESLA]
if (T && !T.is_broken())
is_emissive = TRUE
is_overlay = TRUE
brute_mod = R.brute_mod
burn_mod = R.burn_mod
robotize_type = company
@@ -1389,6 +1379,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(BP_IS_ROBOTIC(src))
return
src.status |= ORGAN_MUTATED
START_PROCESSING(SSprocessing, src)
if(owner) owner.update_body()
/obj/item/organ/external/proc/unmutate()
@@ -1396,7 +1387,7 @@ Note that amputating the affected organ does in fact remove the infection from t
src.status &= ~ORGAN_MUTATED
if(owner) owner.update_body()
/obj/item/organ/external/proc/get_damage() //returns total damage
/obj/item/organ/external/get_damage() //returns total damage
return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use max_damage?
/obj/item/organ/external/proc/has_infected_wound()
@@ -1461,6 +1452,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(!supplied_wound || (W in supplied_wound.embedded_objects)) // Just in case.
return
START_PROCESSING(SSprocessing, src)
LAZYADD(supplied_wound.embedded_objects, W)
implants += W
owner.embedded_flag = 1
@@ -1474,7 +1466,7 @@ Note that amputating the affected organ does in fact remove the infection from t
#undef EMBED_BASE_DAMAGE
/obj/item/organ/external/removed(var/mob/living/user, var/ignore_children = 0)
START_PROCESSING(SSprocessing, src)
if(!owner)
return
var/is_robotic = BP_IS_ROBOTIC(src)
@@ -1544,6 +1536,7 @@ Note that amputating the affected organ does in fact remove the infection from t
owner.visible_message(SPAN_WARNING("\The [owner]'s [name] melts away, turning into a mangled mess!"), \
SPAN_DANGER("Your [name] melts away!"), \
SPAN_WARNING("You hear a sickening sizzle."))
START_PROCESSING(SSprocessing, src)
disfigured = 1
/obj/item/organ/external/proc/get_wounds_desc()
@@ -1648,6 +1641,7 @@ Note that amputating the affected organ does in fact remove the infection from t
return FALSE
else
status |= ORGAN_ARTERY_CUT
START_PROCESSING(SSprocessing, src)
return TRUE
/obj/item/organ/external/proc/tendon_status()
@@ -1737,6 +1731,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(amount > 5 && owner)
owner.undo_srom_pull()
SEND_SIGNAL(src, COMSIG_UPDATE_LIMB_IMAGE)
START_PROCESSING(SSprocessing, src)
return pain-last_pain
/mob/living/carbon/human/proc/undo_srom_pull()
+1 -1
View File
@@ -83,7 +83,7 @@
// Damage to internal organs hurts a lot.
for(var/obj/item/organ/internal/I in internal_organs)
if(prob(1) && !((I.status & ORGAN_DEAD) || BP_IS_ROBOTIC(I)) && I.damage > 5 && I.parent_organ)
if(prob(1) && !((I.status & ORGAN_DEAD) || BP_IS_ROBOTIC(I)) && I.get_damage() > 5 && I.parent_organ)
var/obj/item/organ/external/parent = get_organ(I.parent_organ)
if (!parent) continue
var/pain = 10
@@ -35,6 +35,9 @@
/// If true, will make parent limb not count as broken, as long as it's not bruised (40%) and not broken (0%)
var/supports_limb = FALSE
/obj/item/organ/internal/augment/process_initialize()
return
/obj/item/organ/internal/augment/Initialize()
if(robotic == ROBOTIC_MECHANICAL)
robotize()
@@ -18,6 +18,9 @@
"Calmness",
)
/obj/item/organ/internal/augment/emotional_manipulator/process_initialize()
START_PROCESSING(SSprocessing, src)
/obj/item/organ/internal/augment/emotional_manipulator/attack_self(var/mob/user)
. = ..()
@@ -9,12 +9,6 @@
if (owner)
to_chat(owner, SPAN_DANGER("You sense your [name] stops functioning!"))
/obj/item/organ/internal/augment/head_fluff/process()
..()
if (is_broken() && !ORGAN_DEAD)
if (prob(5))
to_chat(owner, SPAN_WARNING("You sense your [name] isn't working right!"))
/obj/item/organ/internal/augment/head_fluff/removed()
if (owner)
to_chat(owner, SPAN_DANGER("You lose your connection with \the [name]!"))
@@ -13,6 +13,9 @@
/// Time until the next ongoing message
var/next_message = 0
/obj/item/organ/internal/augment/bioaug/mind_blanker/process_initialize()
START_PROCESSING(SSprocessing, src)
/obj/item/organ/internal/augment/bioaug/mind_blanker/Initialize()
. = ..()
if(!owner)
@@ -42,6 +42,64 @@
playsound(owner, 'sound/magic/LightningShock.ogg', 75, 1)
tesla_zap(owner, 7, 1500)
/// Toggles all of an owner's tesla augs.
/obj/item/organ/internal/augment/tesla/proc/toggle_tesla_augs(toggle)
if (!owner)
return
if (is_broken()) // Broken tesla spines will ALWAYS toggle the overlays off when this proc is called.
toggle = FALSE
for (var/obj/item/organ/external/organ in owner.organs)
if (!model)
continue
var/datum/robolimb/R = GLOB.all_robolimbs[model]
if (!R || !R.is_tesla)
continue
organ.is_emissive = toggle
organ.is_overlay = toggle
/**
* Tesla spines power all tesla augs, and if they break, the lights go out.
*/
/obj/item/organ/internal/augment/tesla/take_damage(amount, silent)
. = ..()
toggle_tesla_augs(FALSE)
/obj/item/organ/internal/augment/tesla/Initialize()
. = ..()
toggle_tesla_augs(TRUE)
/obj/item/organ/internal/augment/tesla/Destroy()
toggle_tesla_augs(FALSE)
return ..()
/obj/item/organ/internal/augment/tesla/take_surge_damage(surge)
. = ..()
toggle_tesla_augs(FALSE)
/obj/item/organ/internal/augment/tesla/clear_surge_effects()
. = ..()
toggle_tesla_augs(TRUE)
/obj/item/organ/internal/augment/tesla/rejuvenate()
. = ..()
toggle_tesla_augs(TRUE)
/obj/item/organ/internal/augment/tesla/heal_damage()
. = ..()
toggle_tesla_augs(TRUE)
/obj/item/organ/internal/augment/tesla/removed(mob/living/carbon/human/target, mob/living/user, drop_organ = TRUE, detach = TRUE)
toggle_tesla_augs(FALSE) // Toggle the owner's augs before letting the base organ proc trigger
return ..()
/obj/item/organ/internal/augment/tesla/replaced()
. = ..()
toggle_tesla_augs(TRUE)
/obj/item/organ/internal/augment/tesla/advanced
name = "advanced tesla spine"
max_charges = 15
+53 -67
View File
@@ -4,14 +4,7 @@
/obj/item/organ/external/leg/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
/obj/item/organ/external/leg/nymph/process()
..()
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
AddComponent(/datum/component/nymph_limb, src)
// Right Leg
/obj/item/organ/external/leg/right/nymph
@@ -19,14 +12,7 @@
/obj/item/organ/external/leg/right/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
/obj/item/organ/external/leg/right/nymph/process()
..()
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
AddComponent(/datum/component/nymph_limb, src)
// Left Arm
/obj/item/organ/external/arm/nymph
@@ -34,14 +20,7 @@
/obj/item/organ/external/arm/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
/obj/item/organ/external/arm/nymph/process()
..()
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
AddComponent(/datum/component/nymph_limb, src)
// Right Arm
/obj/item/organ/external/arm/right/nymph
@@ -49,50 +28,35 @@
/obj/item/organ/external/arm/right/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
/obj/item/organ/external/arm/right/nymph/process()
..()
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
AddComponent(/datum/component/nymph_limb, src)
// Left Hand
/obj/item/organ/external/hand/nymph
/obj/item/organ/external/hand/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
AddComponent(/datum/component/nymph_limb, src)
// Right Hand
/obj/item/organ/external/hand/right/nymph
/obj/item/organ/external/hand/right/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
AddComponent(/datum/component/nymph_limb, src)
// Left Foot
/obj/item/organ/external/foot/nymph
/obj/item/organ/external/foot/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
AddComponent(/datum/component/nymph_limb, src)
// Right Foot
/obj/item/organ/external/foot/right/nymph
/obj/item/organ/external/foot/right/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
AddComponent(/datum/component/nymph_limb, src)
/datum/component/nymph_limb
var/list/valid_species = list(SPECIES_UNATHI, SPECIES_SKRELL, SPECIES_SKRELL_AXIORI)
@@ -120,7 +84,51 @@
BP_R_FOOT = /obj/item/organ/external/foot/right/nymph
)
/datum/component/nymph_limb/proc/setup_limb(var/obj/item/organ/external/E)
/// Typecasted owner of the component as an external limb.
var/obj/item/organ/external/limb
/datum/component/nymph_limb/Initialize(obj/item/organ/external/E)
. = ..()
if (!istype(E))
qdel(src)
stack_trace("[src] was added to an entity that was not of type obj/item/organ/external. This component REQUIRES an external limb, and will delete itself immediately if one isn't provided to its AddComponent args.")
return
setup_limb(E)
START_PROCESSING(SSprocessing, src)
/datum/component/nymph_limb/process()
. = ..()
if (!limb)
qdel(src)
return PROCESS_KILL
var/mob/living/carbon/alien/diona/limb_nymph = limb.nymph
if(!istype(limb_nymph) || !limb || !is_type_in_list(limb, nymph_limb_types))
qdel(src)
return PROCESS_KILL
if((!limb.owner || limb_nymph.stat == DEAD))
nymph_out(limb, limb_nymph)
return PROCESS_KILL
if(!limb.is_usable())
nymph_out(limb, limb_nymph, forced = TRUE)
return PROCESS_KILL
var/blood_volume = round(REAGENT_VOLUME(limb.owner.vessel, /singleton/reagent/blood))
if(!blood_volume)
nymph_out(limb, limb_nymph, forced = TRUE)
return PROCESS_KILL
if(REAGENT_DATA(limb.owner.vessel, /singleton/reagent/blood))
limb.owner.vessel.remove_reagent(/singleton/reagent/blood, BLOOD_REGEN_RATE / (2 * nymph_limb_types_by_name.len))
if(blood_volume <= 0)
nymph_out(limb, limb_nymph, forced = TRUE)
return PROCESS_KILL
/datum/component/nymph_limb/proc/setup_limb(obj/item/organ/external/E)
limb = E
if(is_type_in_list(E, nymph_limb_types))
E.nymph = new /mob/living/carbon/alien/diona
@@ -133,28 +141,6 @@
E.limb_flags &= ~(ORGAN_CAN_BREAK | ORGAN_CAN_MAIM | ORGAN_HAS_TENDON)
// Called by process()
/datum/component/nymph_limb/proc/handle_nymph(var/obj/item/organ/external/E)
var/mob/living/carbon/alien/diona/limb_nymph = E.nymph
if(!istype(limb_nymph))
return FALSE
if(!E || !is_type_in_list(E, nymph_limb_types))
return FALSE
if((!E.owner || limb_nymph.stat == DEAD))
nymph_out(E, limb_nymph)
return FALSE
if(!E.is_usable())
nymph_out(E, limb_nymph, forced = TRUE)
return FALSE
var/blood_volume = round(REAGENT_VOLUME(E.owner.vessel, /singleton/reagent/blood))
if(blood_volume)
if(REAGENT_DATA(E.owner.vessel, /singleton/reagent/blood))
E.owner.vessel.remove_reagent(/singleton/reagent/blood, BLOOD_REGEN_RATE / (2 * nymph_limb_types_by_name.len))
if(blood_volume <= 0)
nymph_out(E, limb_nymph, forced = TRUE)
// Host detach
/mob/living/carbon/human/proc/detach_nymph_limb()
set category = "Abilities"
@@ -134,7 +134,7 @@
if(BP_IS_ROBOTIC(O))
continue
if(SPT_PROB(stage*stage, seconds_per_tick))
O.damage = min(O.damage+stage, O.max_damage)
O.set_damage(min(O.get_damage() + stage, O.max_damage))
if(stage >= 4) //after 15 minutes
if(SPT_PROB(3, seconds_per_tick))
+5 -5
View File
@@ -37,13 +37,13 @@
to_chat(user, SPAN_NOTICE("You start by flowing your regenerative psionic energy through their vital organs..."))
for(var/obj/item/organ/O in H.internal_organs)
if(do_mob(user, H, 15 SECONDS))
if(O.damage > 0) // Fix internal damage
if(O.get_damage() > 0) // Fix internal damage
to_chat(user, SPAN_NOTICE("You mend their [O]'s bruising."))
O.heal_damage(O.damage)
O.heal_damage(O.get_damage())
if((O.status & ORGAN_BROKEN))
to_chat(user, SPAN_NOTICE("You restart their [O]'s functionality."))
O.status &= ~ORGAN_BROKEN
if(O.damage <= 5 && O.organ_tag == BP_EYES) // Fix eyes
if(O.get_damage() <= 5 && O.organ_tag == BP_EYES) // Fix eyes
H.sdisabilities &= ~BLIND
to_chat(user, SPAN_NOTICE("You continue by flowing your regenerative psionic energy through their limbs..."))
@@ -52,13 +52,13 @@
continue
if(do_mob(user, H, 15 SECONDS))
to_chat(user, SPAN_NOTICE("You mend their [O]'s bruising."))
O.heal_damage(0, O.damage, internal = TRUE, robo_repair = FALSE)
O.heal_damage(0, O.get_damage(), internal = TRUE, robo_repair = FALSE)
to_chat(user, SPAN_NOTICE("Finally, you begin flowing your regenerative psionic energy through their broken limbs..."))
for(var/obj/item/organ/E in H.bad_external_organs) // Fix bones
var/obj/item/organ/external/affected = E
if(do_mob(user, H, 10 SECONDS))
if((affected.damage < affected.min_broken_damage * GLOB.config.organ_health_multiplier) && (affected.status & ORGAN_BROKEN))
if((affected.get_damage() < affected.min_broken_damage * GLOB.config.organ_health_multiplier) && (affected.status & ORGAN_BROKEN))
to_chat(user, SPAN_NOTICE("You mend their [affected] together."))
affected.status &= ~ORGAN_BROKEN
if((affected.status & ORGAN_ARTERY_CUT))
+1 -1
View File
@@ -67,7 +67,7 @@
to_chat(user, SPAN_WARNING("You notice some irregularity in the psionic flow through their [I]."))
if(I.is_broken())
to_chat(user, SPAN_WARNING("Your psionic flow through their [I] is <b>highly irregular</b>."))
if(I.damage)
if(I.get_damage())
to_chat(user, SPAN_WARNING("You are sure there is some damage in their [I]."))
var/pulse = target.get_pulse()
to_chat(user, SPAN_NOTICE("Their pulse is [pulse]."))
@@ -86,7 +86,7 @@
var/mob/living/carbon/human/pop = owner
if(pop.should_have_organ(BP_BRAIN))
var/obj/item/organ/internal/brain/sponge = pop.internal_organs_by_name[BP_BRAIN]
if(sponge && sponge.damage >= sponge.max_damage)
if(sponge && sponge.get_damage() >= sponge.max_damage)
var/obj/item/organ/external/affecting = pop.get_organ(sponge.parent_organ)
if(affecting && !affecting.is_stump())
affecting.droplimb(0, DROPLIMB_BLUNT)
@@ -249,7 +249,7 @@
for(var/obj/item/organ/internal/I in H.internal_organs)
if(!BP_IS_ROBOTIC(I))
if(I.organ_tag == BP_BRAIN)
var/brain_activity = 100 - ((I.damage / I.max_damage) * 100) //converts brain damage to a percentage, to calculate BA
var/brain_activity = 100 - ((I.get_damage() / I.max_damage) * 100) //converts brain damage to a percentage, to calculate BA
if(brain_activity >= 61) //will only treat brain activity below 61% brain activity
continue
I.heal_damage(4*removed)
@@ -283,7 +283,7 @@
for(var/obj/item/organ/internal/I in H.internal_organs)
if(!BP_IS_ROBOTIC(I))
if(I.organ_tag == BP_BRAIN)
var/brain_activity = 100 - ((I.damage / I.max_damage) * 100) //converts brain damage to a percentage, to calculate BA
var/brain_activity = 100 - ((I.get_damage() / I.max_damage) * 100) //converts brain damage to a percentage, to calculate BA
if(brain_activity >= 61) //will only treat brain activity below 61% brain activity
continue
I.heal_damage(4*removed)
@@ -658,10 +658,10 @@
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/eyes/E = H.get_eyes(no_synthetic = TRUE)
if(E && istype(E))
if(E.damage > 0)
E.damage = max(E.damage - 5 * removed, 0)
if(E.get_damage() > 0)
E.set_damage(max(E.get_damage() - 5 * removed, 0))
if(isvaurca(H))
if(E.damage < E.min_broken_damage && H.sdisabilities & BLIND)
if(E.get_damage() < E.min_broken_damage && H.sdisabilities & BLIND)
H.sdisabilities -= BLIND
/singleton/reagent/oculine/affect_chem_effect(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
@@ -691,17 +691,17 @@
for(var/obj/item/organ/internal/I in H.internal_organs)
if(I.organ_tag == BP_BRAIN)
if(I.damage >= I.min_bruised_damage)
if(I.get_damage() >= I.min_bruised_damage)
continue
if((I.damage > 0) && (I.robotic != 2)) //Peridaxon heals only non-robotic organs
if((I.get_damage() > 0) && (I.robotic != 2)) //Peridaxon heals only non-robotic organs
var/damage_healed = ((M.bodytemperature < 186) && M.chem_effects[CE_CRYO]) ? 2 : 1 //2x effective if administered in cryogenic conditions
I.damage = max(I.damage - damage_healed*removed, 0)
I.set_damage(max(I.get_damage() - damage_healed*removed, 0))
if((M.bodytemperature < 153) && M.chem_effects[CE_ANTIBIOTIC]) //peridaxon in extracool cryogenic conditions alongside antibiotics will have a chance to de-nercotise liver and kidneys, though will incur overdose symptoms
H.infest_with_parasite(H, BP_TUMOUR_NONSPREADING, pick(H.organs), 10)
for(var/obj/item/organ/internal/O in H.internal_organs)
if((O.organ_tag == BP_LIVER) || (O.organ_tag == BP_KIDNEYS))
if(O.damage && prob(5))
if(O.get_damage() && prob(5))
if((O.status & ORGAN_DEAD) && !BP_IS_ROBOTIC(O))
if(O.can_recover())
O.status &= ~ORGAN_DEAD
@@ -1485,12 +1485,14 @@
var/obj/item/organ/internal/brain = M.internal_organs_by_name[BP_BRAIN]
if((M.bodytemperature < 179) && (M.chem_effects[CE_CRYO])) //best use in cryogenics, experiment with Balanced or Prioritising Metabolisation settings, aiming for a gas cooler temperature target that minimises the cryostasis multiplier. remember the cryotube heats slowly when someone is inside.
if(brain)
if(brain.damage && brain.damage < brain.max_damage && !(M.chem_effects[CE_NEUROTOXIC])) //skips the oxygenation check under brain.dm
brain.damage = max(brain.damage - 16*removed, 0) //high number, as cryo slows metabolism. also needs to slightly outpace rough injuries to actually make it worthwhile to use.
var/brain_damage = brain.get_damage()
if(brain_damage && brain_damage < brain.max_damage && !(M.chem_effects[CE_NEUROTOXIC])) //skips the oxygenation check under brain.dm
brain.set_damage(max(brain_damage - 16*removed, 0)) //high number, as cryo slows metabolism. also needs to slightly outpace rough injuries to actually make it worthwhile to use.
else //without cryogenics. skips the oxygen check, however has large downsides if not pushed thorugh an IV to moderate volume in blood.
if(brain)
if(brain.damage && brain.damage < brain.max_damage && !(M.chem_effects[CE_NEUROTOXIC]) && prob(75))
brain.damage = max(brain.damage - 8*removed, 0) //pretty slow, non-guaranteed brain healing - 75% chance of restoring 2.5% brain activity per tick. only really useful during apocalyptic scenarios.
var/brain_damage = brain.get_damage()
if(brain_damage && brain_damage < brain.max_damage && !(M.chem_effects[CE_NEUROTOXIC]) && prob(75))
brain.set_damage(max(brain_damage - 8*removed, 0)) //pretty slow, non-guaranteed brain healing - 75% chance of restoring 2.5% brain activity per tick. only really useful during apocalyptic scenarios.
M.dizziness = max(200, M.dizziness + 15)
M.hallucination = max(M.hallucination, 100)
M.add_chemical_effect(CE_BLOODTHIN, 40) //treat (arterial) bleeding first
@@ -1780,7 +1782,7 @@
M.add_chemical_effect(CE_CARDIOTOXIC, -removed*2)
var/obj/item/organ/internal/heart/H = M.internal_organs_by_name[BP_HEART]
if(istype(H) && !BP_IS_ROBOTIC(H))
H.damage = max(H.damage - (removed * 2), 0)
H.set_damage(max(H.get_damage() - (removed * 2), 0))
..()
/singleton/reagent/adipemcina/overdose(var/mob/living/carbon/human/M, var/alien, var/datum/reagents/holder)
@@ -25,7 +25,7 @@
if(target_organ)
var/obj/item/organ/internal/I = H.internal_organs_by_name[target_organ]
if(I)
var/can_damage = I.max_damage - I.damage
var/can_damage = I.max_damage - I.get_damage()
if(can_damage > 0)
if(dam > can_damage)
I.take_internal_damage(can_damage, silent=TRUE)
@@ -73,9 +73,9 @@
return 1
for(var/obj/item/organ/I in E.internal_organs)
if(I.robotic < ORGAN_ROBOT && I.damage > 0)
if(I.robotic < ORGAN_ROBOT && I.get_damage() > 0)
to_chat(user, SPAN_NOTICE("You encourage the damaged tissue of \the [I] to repair itself."))
I.damage = max(0, I.damage - rand(3,5))
I.set_damage(max(0, I.get_damage() - rand(3,5)))
return 1
to_chat(user, SPAN_NOTICE("You can find nothing within \the [target]'s [E.name] to mend."))
+1 -1
View File
@@ -340,7 +340,7 @@
return FALSE
else if(target.species.has_organ[O.organ_tag] || O.is_augment)
if(O.damage > (O.max_damage * 0.75))
if(O.get_damage() > (O.max_damage * 0.75))
to_chat(user, SPAN_WARNING("\The [O.organ_tag] [o_is] in no state to be transplanted."))
return SURGERY_FAILURE
+1 -1
View File
@@ -78,7 +78,7 @@
break
if(!organ)
return
if(organ.damage > organ.max_damage)
if(organ.get_damage() > organ.max_damage)
to_chat(user, SPAN_WARNING("\The [organ] is too damaged. Repair it first."))
return 0
+1 -1
View File
@@ -52,7 +52,7 @@
organ_data["name"] = organ.name
organ_data["desc"] = organ.desc
organ_data["damage"] = edit_organ_status(organ.damage, diagnostics)
organ_data["damage"] = edit_organ_status(organ.get_damage(), diagnostics)
organ_data["max_damage"] = organ.max_damage
data["organs"] += list(organ_data)
@@ -22,7 +22,7 @@
var/list/data = list()
var/obj/item/organ/internal/machine/posibrain/posibrain = owner.internal_organs_by_name[BP_BRAIN]
if(istype(posibrain))
data["neural_coherence"] = posibrain.damage
data["neural_coherence"] = posibrain.get_damage()
data["max_neural_coherence"] = posibrain.max_damage
data["owner_real_name"] = posibrain.owner.real_name
data["firewall"] = posibrain.firewall