Files
Aurora.3/code/modules/organs/internal/_internal.dm
T
VMSolidusandGitHub 2e939e4d9b Galatean BioAugments (#21013)
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
2025-08-04 12:29:41 +00:00

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