mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-15 17:07:44 +01:00
This PR "Gently refactors" organs in preparation for adding in new variant organsas requested by HumanLore. Additionally, it adds in several organs that were requested by Human Lore, as described in: https://docs.google.com/document/d/1SLbll969PyJ_H9J1LP8cmdso9OMozUc8MGOVZkY4HbE/mobilebasic The new augments include: Auxiliary Heart, Platelet Factories, and Subdermal Carpace Additionally, all of the new Galatean Bioaugs have been added to the antag uplink. The bulk of this PR consists of replacing a majority of all the organ "Magic Numbers" with variables which could feasibly be modified by any new kind of organ object. Additionally-- although it's unused in this PR, here's also a new optional boolean for hearts to create a "Fake Pulse", which would be useful in the future for event character shells to be able to fool a pulse check. Finally, the heart systems are configured to use Signals so that arbitrarily any component can introduce their own modifiers to the heart statistics. This PR was requested by Human Lore: <img width="434" height="290" alt="image" src="https://github.com/user-attachments/assets/98236886-1c19-4621-958e-c154ae66f2ad" /> Sprites have been made by @NobleRow
162 lines
5.3 KiB
Plaintext
162 lines
5.3 KiB
Plaintext
/****************************************************
|
|
INTERNAL ORGANS DEFINES
|
|
****************************************************/
|
|
/obj/item/organ/internal
|
|
var/dead_icon // Icon to use when the organ has died.
|
|
var/damage_reduction = 0.5 //modifier for internal organ injury
|
|
var/unknown_pain_location = TRUE // if TRUE, pain messages will point to the parent organ, otherwise it will print the organ name
|
|
var/toxin_type = "undefined"
|
|
var/relative_size = 25 //Used for size calcs
|
|
/// The icon state to overlay on the mob
|
|
var/on_mob_icon
|
|
/// If the icon state has an active overlay
|
|
var/active_overlay = FALSE
|
|
/// If the icon state has an active emissive overlay
|
|
var/active_emissive = FALSE
|
|
var/list/possible_modifications = list("Normal","Assisted","Mechanical") //this is used in the character setup
|
|
|
|
min_broken_damage = 10 //Internal organs are frail, man.
|
|
|
|
/obj/item/organ/internal/Destroy()
|
|
if(owner)
|
|
owner.internal_organs.Remove(src)
|
|
owner.internal_organs_by_name[organ_tag] = null
|
|
owner.internal_organs_by_name -= organ_tag
|
|
while(null in owner.internal_organs)
|
|
owner.internal_organs -= null
|
|
var/obj/item/organ/external/E = owner.organs_by_name[parent_organ]
|
|
if(istype(E)) E.internal_organs -= src
|
|
return ..()
|
|
|
|
/obj/item/organ/internal/replaced(var/mob/living/carbon/human/target, var/obj/item/organ/external/affected)
|
|
if(!istype(target))
|
|
return 0
|
|
|
|
// robotic organs emulate behavior of the equivalent flesh organ of the species
|
|
if(BP_IS_ROBOTIC(src) || !species)
|
|
species = target.species
|
|
|
|
..()
|
|
|
|
STOP_PROCESSING(SSprocessing, src)
|
|
target.internal_organs |= src
|
|
affected.internal_organs |= src
|
|
target.internal_organs_by_name[organ_tag] = src
|
|
return 1
|
|
|
|
/obj/item/organ/internal/die()
|
|
..()
|
|
if((status & ORGAN_DEAD) && dead_icon)
|
|
icon_state = dead_icon
|
|
|
|
/obj/item/organ/internal/proc/surgical_fix(mob/user)
|
|
if(damage > min_broken_damage)
|
|
var/scarring = damage / max_damage
|
|
scarring = 1 - 0.5 * scarring ** 2 // Between ~15 and 50 percent loss.
|
|
var/new_max_dam = FLOOR(scarring * max_damage, 1)
|
|
if(new_max_dam < max_damage)
|
|
to_chat(user, SPAN_WARNING("Not every part of [src] could be saved; some dead tissue had to be removed, making it more susceptible to future damage."))
|
|
set_max_damage(new_max_dam)
|
|
heal_damage(damage)
|
|
|
|
/obj/item/organ/internal/proc/get_scarring_level()
|
|
. = (initial(max_damage) - max_damage)/initial(max_damage)
|
|
|
|
/obj/item/organ/internal/proc/get_scarring_results()
|
|
var/scar_level = get_scarring_level()
|
|
if(scar_level > 0.01)
|
|
. += "[get_wound_severity(get_scarring_level())] scarring"
|
|
|
|
/obj/item/organ/internal/is_usable()
|
|
if(robotize_type)
|
|
var/datum/robolimb/R = GLOB.all_robolimbs[robotize_type]
|
|
if(!R.malfunctioning_check(owner))
|
|
return TRUE
|
|
else
|
|
return ..() && !is_broken()
|
|
|
|
/obj/item/organ/internal/proc/is_damaged()
|
|
return damage > 0 || special_condition()
|
|
|
|
/obj/item/organ/internal/proc/special_condition() // For unique conditions
|
|
return
|
|
|
|
/obj/item/organ/internal/robotize(var/company = PROSTHETIC_UNBRANDED)
|
|
..()
|
|
min_bruised_damage += 5
|
|
min_broken_damage += 10
|
|
|
|
if(company)
|
|
model = company
|
|
var/datum/robolimb/R = GLOB.all_robolimbs[company]
|
|
|
|
if(R)
|
|
if(robotic_sprite)
|
|
icon_state = "[initial(icon_state)]-[R.internal_organ_suffix]"
|
|
|
|
robotize_type = company
|
|
|
|
/obj/item/organ/internal/mechassist()
|
|
..()
|
|
icon_state = "[initial(icon_state)]-assisted"
|
|
|
|
/obj/item/organ/internal/proc/getToxLoss()
|
|
if(BP_IS_ROBOTIC(src))
|
|
return damage * 0.5
|
|
return damage
|
|
|
|
/obj/item/organ/internal/proc/set_max_damage(var/ndamage)
|
|
max_damage = FLOOR(ndamage, 1)
|
|
min_broken_damage = FLOOR(0.75 * max_damage, 1)
|
|
min_bruised_damage = FLOOR(0.25 * max_damage, 1)
|
|
|
|
/obj/item/organ/internal/proc/take_internal_damage(amount, var/silent=0)
|
|
if(BP_IS_ROBOTIC(src))
|
|
damage = between(0, src.damage + (amount * 0.8), max_damage)
|
|
else
|
|
damage = between(0, src.damage + amount, max_damage)
|
|
|
|
//only show this if the organ is not robotic
|
|
if(owner && ORGAN_CAN_FEEL_PAIN(src) && parent_organ && (amount > 5 || prob(10)))
|
|
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
|
|
if(parent && !silent)
|
|
var/degree = ""
|
|
if(is_bruised())
|
|
degree = " a lot"
|
|
if(damage < 5)
|
|
degree = " a bit"
|
|
owner.custom_pain("Something inside your [parent.name] hurts[degree]!", amount, affecting = parent)
|
|
|
|
/obj/item/organ/internal/proc/get_visible_state()
|
|
if(damage > max_damage)
|
|
. = "bits and pieces of a destroyed "
|
|
else if(is_broken())
|
|
. = "broken "
|
|
else if(is_bruised())
|
|
. = "badly damaged "
|
|
else if(damage > 5)
|
|
. = "damaged "
|
|
if(status & ORGAN_DEAD)
|
|
if(can_recover())
|
|
. = "necrotic and debridable [.]"
|
|
else
|
|
. = "necrotic and dead [.]"
|
|
. = "[.][name]"
|
|
|
|
/obj/item/organ/internal/process(seconds_per_tick)
|
|
..()
|
|
if(istype(owner) && (toxin_type in owner.chem_effects))
|
|
take_damage(owner.chem_effects[toxin_type] * seconds_per_tick)
|
|
handle_regeneration(seconds_per_tick)
|
|
tick_surge_damage() //Yes, this is intentional.
|
|
|
|
/obj/item/organ/internal/proc/handle_regeneration(seconds_per_tick)
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
if(!damage || BP_IS_ROBOTIC(src) || !istype(owner) || owner.is_asystole() || (owner.chem_effects[CE_TOXIN] || (toxin_type in owner.chem_effects)))
|
|
return FALSE
|
|
|
|
var/repair_modifier = owner.chem_effects[CE_ORGANREPAIR] || 0.1
|
|
if(damage < repair_modifier*max_damage)
|
|
heal_damage(repair_modifier)
|
|
return TRUE // regeneration is allowed
|