From e117ef3f87f871b714b61e117c58cc0ad8c2ea52 Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Sun, 12 Jul 2026 16:45:24 -0400 Subject: [PATCH] Nuke Limb Processing (#22814) image 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. --- code/ZAS/Phoron.dm | 4 +- .../technomancer/spells/mend_organs.dm | 7 +- code/game/objects/items.dm | 4 +- code/game/objects/items/devices/auto_cpr.dm | 2 +- .../items/devices/lighting/flashlight.dm | 2 +- .../objects/structures/machinery/iv_drip.dm | 2 +- .../events/spontaneous_appendicitis.dm | 1 + code/modules/mob/living/carbon/brain/MMI.dm | 2 +- code/modules/mob/living/carbon/diona_base.dm | 6 +- .../mob/living/carbon/human/damage_menu.dm | 11 +- code/modules/mob/living/carbon/human/human.dm | 2 +- .../mob/living/carbon/human/human_damage.dm | 18 ++- .../mob/living/carbon/human/human_organs.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 2 +- .../human/species/station/human/human.dm | 2 +- .../carbon/human/species/station/ipc/ipc.dm | 2 +- code/modules/mob/living/living.dm | 4 +- .../mob/living/silicon/robot/analyzer.dm | 2 +- .../file_system/programs/research/robotics.dm | 2 +- code/modules/organs/blood.dm | 2 +- code/modules/organs/internal/_internal.dm | 10 +- code/modules/organs/internal/appendix.dm | 9 +- code/modules/organs/internal/kidneys.dm | 9 +- code/modules/organs/organ.dm | 39 +++++- code/modules/organs/organ_external.dm | 121 +++++++++--------- code/modules/organs/pain.dm | 2 +- .../organs/subtypes/augment/augment.dm | 3 + .../augment/augments/emotional_manipulator.dm | 3 + .../organs/subtypes/augment/augments/fluff.dm | 6 - .../subtypes/augment/augments/mind_blanker.dm | 3 + .../organs/subtypes/augment/augments/tesla.dm | 58 +++++++++ code/modules/organs/subtypes/nymph_limbs.dm | 120 ++++++++--------- .../organs/subtypes/parasite/tumours.dm | 2 +- code/modules/psionics/abilities/mend.dm | 10 +- code/modules/psionics/abilities/skinsight.dm | 2 +- .../psionics/complexus/complexus_helpers.dm | 2 +- .../Chemistry-Reagents-Medicine.dm | 30 +++-- .../Chemistry-Reagents-Toxins.dm | 2 +- .../spells/spell_list/others/generic/mend.dm | 4 +- code/modules/surgery/organs_internal.dm | 2 +- code/modules/surgery/other.dm | 2 +- code/modules/tgui/modules/ipc_diagnostic.dm | 2 +- .../tgui/modules/neural_configuration.dm | 2 +- .../hellfirejag-kill-organ-processing.yml | 4 + 44 files changed, 310 insertions(+), 216 deletions(-) create mode 100644 html/changelogs/hellfirejag-kill-organ-processing.yml diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index bb76edb4c62..287453e794c 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -113,9 +113,9 @@ GLOBAL_DATUM_INIT(contamination_overlay, /image, image('icons/effects/contaminat var/obj/item/organ/internal/eyes/E = get_eyes(no_synthetic = TRUE) if(E) if(prob(20)) to_chat(src, SPAN_DANGER("Your eyes burn!")) - E.damage += 2.5 + E.add_damage(2.5) eye_blurry = min(eye_blurry+1.5,50) - if (prob(max(0,E.damage - 15) + 1) &&!eye_blind) + if (prob(max(0,E.get_damage() - 15) + 1) &&!eye_blind) to_chat(src, SPAN_DANGER("You are blinded!")) eye_blind += 20 diff --git a/code/game/gamemodes/technomancer/spells/mend_organs.dm b/code/game/gamemodes/technomancer/spells/mend_organs.dm index b77536127ea..b57b967d935 100644 --- a/code/game/gamemodes/technomancer/spells/mend_organs.dm +++ b/code/game/gamemodes/technomancer/spells/mend_organs.dm @@ -33,9 +33,10 @@ L.adjust_instability(5) for(var/obj/item/organ/O in H.internal_organs) - if(O.damage > 0) // Fix internal damage + var/organ_damage = O.get_damage() + if(organ_damage > 0) // Fix internal damage O.heal_damage(heal_power / 2) - if(O.damage <= 5 && O.organ_tag == BP_EYES) // Fix eyes + if(organ_damage <= 5 && O.organ_tag == BP_EYES) // Fix eyes H.sdisabilities &= ~BLIND for(var/obj/item/organ/external/O in H.organs) // Fix limbs @@ -45,7 +46,7 @@ for(var/obj/item/organ/E in H.bad_external_organs) // Fix bones var/obj/item/organ/external/affected = E - 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)) affected.status &= ~ORGAN_BROKEN if(affected.tendon_status() & TENDON_CUT) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index a0db4bf11c4..301c7e8bed6 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -853,7 +853,7 @@ GLOBAL_LIST_INIT(slot_flags_enumeration, list( ) eyes.take_damage(rand(3,4)) - if(eyes.damage >= eyes.min_bruised_damage) + if(eyes.get_damage() >= eyes.min_bruised_damage) if(H.stat != DEAD) if(eyes.robotic <= 1) //robot eyes bleeding might be a bit silly to_chat(H, SPAN_DANGER("Your eyes start to bleed profusely!")) @@ -864,7 +864,7 @@ GLOBAL_LIST_INIT(slot_flags_enumeration, list( H.eye_blurry += 10 H.Paralyse(1) H.Weaken(4) - if (eyes.damage >= eyes.min_broken_damage) + if (eyes.get_damage() >= eyes.min_broken_damage) if(H.stat != DEAD) to_chat(H, SPAN_WARNING("You go blind!")) var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD) diff --git a/code/game/objects/items/devices/auto_cpr.dm b/code/game/objects/items/devices/auto_cpr.dm index 0e58484c64e..7fc4975493c 100644 --- a/code/game/objects/items/devices/auto_cpr.dm +++ b/code/game/objects/items/devices/auto_cpr.dm @@ -381,7 +381,7 @@ var/obj/item/organ/internal/lungs/lungs = H.internal_organs_by_name[BP_LUNGS] var/safe_pressure_min = H.species.breath_pressure + 2 - safe_pressure_min *= 1 + rand(1,4) * lungs.damage/lungs.max_damage + safe_pressure_min *= 1 + rand(1,4) * lungs.get_damage()/lungs.max_damage if(!lungs) epp_off() return diff --git a/code/game/objects/items/devices/lighting/flashlight.dm b/code/game/objects/items/devices/lighting/flashlight.dm index dfd410a168f..24aef7caa77 100644 --- a/code/game/objects/items/devices/lighting/flashlight.dm +++ b/code/game/objects/items/devices/lighting/flashlight.dm @@ -250,7 +250,7 @@ return if((H.mutations & XRAY)) to_chat(user, SPAN_NOTICE("\The [H]'s pupils give an eerie glow!")) - if(vision.damage) + if(vision.get_damage()) to_chat(user, SPAN_WARNING("There's visible damage to [H]'s [vision.name]!")) else if(H.eye_blurry) to_chat(user, SPAN_NOTICE("\The [H]'s pupils react slower than normally.")) diff --git a/code/game/objects/structures/machinery/iv_drip.dm b/code/game/objects/structures/machinery/iv_drip.dm index fd739c02141..29bc8a38505 100644 --- a/code/game/objects/structures/machinery/iv_drip.dm +++ b/code/game/objects/structures/machinery/iv_drip.dm @@ -240,7 +240,7 @@ tank_off() return var/safe_pressure_min = breather.species.breath_pressure + 5 - safe_pressure_min *= 1 + rand(1,4) * L.damage/L.max_damage + safe_pressure_min *= 1 + rand(1,4) * L.get_damage()/L.max_damage if(!tank_active) // Activates and sets the kPa to a safe pressure. This keeps from it constantly resetting itself tank.distribute_pressure = safe_pressure_min diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm index cd71d5901a8..cf98d0f362c 100644 --- a/code/modules/events/spontaneous_appendicitis.dm +++ b/code/modules/events/spontaneous_appendicitis.dm @@ -11,4 +11,5 @@ continue A.inflamed = 1 A.update_icon() + START_PROCESSING(SSprocessing, A) break diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 7cd76b21f25..5fd6d2ae318 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -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) diff --git a/code/modules/mob/living/carbon/diona_base.dm b/code/modules/mob/living/carbon/diona_base.dm index 3a5dd9014da..40c71e90175 100644 --- a/code/modules/mob/living/carbon/diona_base.dm +++ b/code/modules/mob/living/carbon/diona_base.dm @@ -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. diff --git a/code/modules/mob/living/carbon/human/damage_menu.dm b/code/modules/mob/living/carbon/human/damage_menu.dm index db6c4b99fa9..6f3f68dda05 100644 --- a/code/modules/mob/living/carbon/human/damage_menu.dm +++ b/code/modules/mob/living/carbon/human/damage_menu.dm @@ -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) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 644e2aba0a2..92eec0ac162 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -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 diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 9a8ab38e981..78afbbd7aad 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -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 diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 5b69458befd..11d9d13c3eb 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -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 diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 73f3e471bee..05bfb478c95 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -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) diff --git a/code/modules/mob/living/carbon/human/species/station/human/human.dm b/code/modules/mob/living/carbon/human/species/station/human/human.dm index 4a0e3f9e44a..c8813fc7be7 100644 --- a/code/modules/mob/living/carbon/human/species/station/human/human.dm +++ b/code/modules/mob/living/carbon/human/species/station/human/human.dm @@ -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]!") diff --git a/code/modules/mob/living/carbon/human/species/station/ipc/ipc.dm b/code/modules/mob/living/carbon/human/species/station/ipc/ipc.dm index 65a8a757ddc..859cec6a1fb 100644 --- a/code/modules/mob/living/carbon/human/species/station/ipc/ipc.dm +++ b/code/modules/mob/living/carbon/human/species/station/ipc/ipc.dm @@ -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"))) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b4faa5b04eb..4f9f23905ef 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -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) diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm index fe5cc3a8415..8c35ef5c634 100644 --- a/code/modules/mob/living/silicon/robot/analyzer.dm +++ b/code/modules/mob/living/silicon/robot/analyzer.dm @@ -107,7 +107,7 @@ if(machine_organ.get_integrity() < 100) to_chat(user, "[machine_organ.name]: Integrity damage detected.") found_damage = TRUE - else if(O.damage) + else if(O.get_damage()) to_chat(user, SPAN_WARNING("[O.name]: Core damage detected.")) found_damage = TRUE if(!found_damage) diff --git a/code/modules/modular_computers/file_system/programs/research/robotics.dm b/code/modules/modular_computers/file_system/programs/research/robotics.dm index 9aab7fc9f1c..75b090fbabf 100644 --- a/code/modules/modular_computers/file_system/programs/research/robotics.dm +++ b/code/modules/modular_computers/file_system/programs/research/robotics.dm @@ -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) diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index a6e31aeb2c0..cbda5acf331 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -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) diff --git a/code/modules/organs/internal/_internal.dm b/code/modules/organs/internal/_internal.dm index 5b0cefffbb8..80355b4a0d4 100644 --- a/code/modules/organs/internal/_internal.dm +++ b/code/modules/organs/internal/_internal.dm @@ -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 diff --git a/code/modules/organs/internal/appendix.dm b/code/modules/organs/internal/appendix.dm index b2114eaa2ee..fb69c319efa 100644 --- a/code/modules/organs/internal/appendix.dm +++ b/code/modules/organs/internal/appendix.dm @@ -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. diff --git a/code/modules/organs/internal/kidneys.dm b/code/modules/organs/internal/kidneys.dm index d23e183e893..4b4c7b724bb 100644 --- a/code/modules/organs/internal/kidneys.dm +++ b/code/modules/organs/internal/kidneys.dm @@ -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 diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index fcb4635d221..4648462e9bf 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -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 diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index c64084cd435..9a0f2a3c238 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -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() diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm index da6d334103d..1c377eecda3 100644 --- a/code/modules/organs/pain.dm +++ b/code/modules/organs/pain.dm @@ -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 diff --git a/code/modules/organs/subtypes/augment/augment.dm b/code/modules/organs/subtypes/augment/augment.dm index f7969b4f3ca..2485eca8746 100644 --- a/code/modules/organs/subtypes/augment/augment.dm +++ b/code/modules/organs/subtypes/augment/augment.dm @@ -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() diff --git a/code/modules/organs/subtypes/augment/augments/emotional_manipulator.dm b/code/modules/organs/subtypes/augment/augments/emotional_manipulator.dm index 5687ff77213..eeb10dd58fa 100644 --- a/code/modules/organs/subtypes/augment/augments/emotional_manipulator.dm +++ b/code/modules/organs/subtypes/augment/augments/emotional_manipulator.dm @@ -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) . = ..() diff --git a/code/modules/organs/subtypes/augment/augments/fluff.dm b/code/modules/organs/subtypes/augment/augments/fluff.dm index 90f093f4719..b6bdcc5d4ae 100644 --- a/code/modules/organs/subtypes/augment/augments/fluff.dm +++ b/code/modules/organs/subtypes/augment/augments/fluff.dm @@ -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]!")) diff --git a/code/modules/organs/subtypes/augment/augments/mind_blanker.dm b/code/modules/organs/subtypes/augment/augments/mind_blanker.dm index b30f660010e..07cd6bec7bb 100644 --- a/code/modules/organs/subtypes/augment/augments/mind_blanker.dm +++ b/code/modules/organs/subtypes/augment/augments/mind_blanker.dm @@ -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) diff --git a/code/modules/organs/subtypes/augment/augments/tesla.dm b/code/modules/organs/subtypes/augment/augments/tesla.dm index 751377c43f8..6457a799fc4 100644 --- a/code/modules/organs/subtypes/augment/augments/tesla.dm +++ b/code/modules/organs/subtypes/augment/augments/tesla.dm @@ -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 diff --git a/code/modules/organs/subtypes/nymph_limbs.dm b/code/modules/organs/subtypes/nymph_limbs.dm index 00d0a0f75d2..d025767dccf 100644 --- a/code/modules/organs/subtypes/nymph_limbs.dm +++ b/code/modules/organs/subtypes/nymph_limbs.dm @@ -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" diff --git a/code/modules/organs/subtypes/parasite/tumours.dm b/code/modules/organs/subtypes/parasite/tumours.dm index 3e78ada1760..0caf2a82596 100644 --- a/code/modules/organs/subtypes/parasite/tumours.dm +++ b/code/modules/organs/subtypes/parasite/tumours.dm @@ -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)) diff --git a/code/modules/psionics/abilities/mend.dm b/code/modules/psionics/abilities/mend.dm index 7132952de2b..1ad6703a00c 100644 --- a/code/modules/psionics/abilities/mend.dm +++ b/code/modules/psionics/abilities/mend.dm @@ -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)) diff --git a/code/modules/psionics/abilities/skinsight.dm b/code/modules/psionics/abilities/skinsight.dm index 204e784ea31..e6c194aa622 100644 --- a/code/modules/psionics/abilities/skinsight.dm +++ b/code/modules/psionics/abilities/skinsight.dm @@ -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 highly irregular.")) - 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].")) diff --git a/code/modules/psionics/complexus/complexus_helpers.dm b/code/modules/psionics/complexus/complexus_helpers.dm index 870e98fe57e..8e41dfc3bb5 100644 --- a/code/modules/psionics/complexus/complexus_helpers.dm +++ b/code/modules/psionics/complexus/complexus_helpers.dm @@ -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) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 5bf16785e34..c61c9d135e2 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -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) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index cd95a15789f..c953e8cb416 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -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) diff --git a/code/modules/spell_system/spells/spell_list/others/generic/mend.dm b/code/modules/spell_system/spells/spell_list/others/generic/mend.dm index d5ce416e045..e70e0f229c4 100644 --- a/code/modules/spell_system/spells/spell_list/others/generic/mend.dm +++ b/code/modules/spell_system/spells/spell_list/others/generic/mend.dm @@ -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.")) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 189b6d37564..90a8beaa4d5 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -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 diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 6d039efea59..14e05665682 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -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 diff --git a/code/modules/tgui/modules/ipc_diagnostic.dm b/code/modules/tgui/modules/ipc_diagnostic.dm index 6b1cf44c67e..1dff03a2bb4 100644 --- a/code/modules/tgui/modules/ipc_diagnostic.dm +++ b/code/modules/tgui/modules/ipc_diagnostic.dm @@ -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) diff --git a/code/modules/tgui/modules/neural_configuration.dm b/code/modules/tgui/modules/neural_configuration.dm index 9dca5f4e27d..71e2c3a03c5 100644 --- a/code/modules/tgui/modules/neural_configuration.dm +++ b/code/modules/tgui/modules/neural_configuration.dm @@ -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 diff --git a/html/changelogs/hellfirejag-kill-organ-processing.yml b/html/changelogs/hellfirejag-kill-organ-processing.yml new file mode 100644 index 00000000000..0b4c1240ffa --- /dev/null +++ b/html/changelogs/hellfirejag-kill-organ-processing.yml @@ -0,0 +1,4 @@ +author: Hellfirejag +delete-after: True +changes: + - refactor: "Refactored Limbs (and some organs) to no longer require constant processing. They now only occupy processor time if they actually need to."