mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-27 06:54:18 +01:00
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:
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user