Files
vgstation13/code/modules/organs/organ_internal.dm
2022-04-18 11:03:05 -05:00

256 lines
7.4 KiB
Plaintext

/****************************************************
INTERNAL ORGANS
****************************************************/
/mob/living/carbon/human/var/list/internal_organs = list()
/datum/organ/internal
var/damage = 0 // amount of damage to the organ
var/min_bruised_damage = 10
var/min_broken_damage = 30
var/parent_organ = LIMB_CHEST
var/organ_type //What organ type it is (lungs, heart) keep it lower case
var/robotic = 0 //For being a robot
var/removed_type //When removed, forms this object.
var/list/transplant_data // Blood DNA and colour of donor
var/rejecting // Is this organ already being rejected?
var/datum/dna/owner_dna
/datum/organ/internal/Destroy()
if(owner && (src in owner.internal_organs))
owner.internal_organs -= src
owner.internal_organs_by_name -= organ_type
var/datum/organ/external/E = owner.organs_by_name[parent_organ] //Fuck this setup
E.internal_organs -= src
owner = null
..()
/datum/organ/internal/Copy()
var/datum/organ/internal/I = ..()
I.damage = damage
I.min_bruised_damage = min_bruised_damage
I.min_broken_damage = min_broken_damage
I.organ_type = organ_type
I.parent_organ = parent_organ
I.robotic = robotic
I.removed_type = removed_type
I.transplant_data = transplant_data
I.rejecting = rejecting
I.owner_dna = owner_dna
return I
/datum/organ/internal/proc/rejuvenate()
damage = 0
germ_level = 0
cancer_stage = 0
/datum/organ/internal/proc/is_bruised()
return damage >= min_bruised_damage
/datum/organ/internal/proc/is_broken()
return damage >= min_broken_damage
/datum/organ/internal/New(mob/living/carbon/human/H)
..()
if(H)
var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
if(E.internal_organs == null)
E.internal_organs = list()
E.internal_organs |= src
H.internal_organs |= src
src.owner = H
/datum/organ/internal/proc/Life()
// Now organs support Life() processes.
return
/datum/organ/internal/process()
//Process infections
if (robotic >= 2 || (owner.species && owner.species.flags & IS_PLANT)) //TODO make robotic internal and external organs separate types of organ instead of a flag
germ_level = 0
return
if(owner.bodytemperature >= 170) //cryo stops germs and cancer from moving and doing their bad stuffs
//** Handle antibiotics and curing infections
handle_antibiotics()
//** Handle the effects of infections
handle_germs()
// Process unsuitable transplants. TODO: consider some kind of
// immunosuppressant that changes transplant data to make it match.
if(transplant_data)
if(!rejecting) //Should this transplant reject?
if(owner.species.name != transplant_data["species"]) //Nope.
rejecting = 1
else if(prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type))
rejecting = 1
else
rejecting++ //Rejection severity increases over time.
if(rejecting % 10 == 0) //Only fire every ten rejection ticks.
switch(rejecting)
if(1 to 50)
take_damage(rand(1,2))
if(51 to 200)
take_damage(rand(2,3))
if(201 to 500)
take_damage(rand(3,4))
owner.reagents.add_reagent(TOXIN, 1)
if(501 to INFINITY)
take_damage(5)
owner.reagents.add_reagent(TOXIN, rand(3,5))
if(cancer_stage)
handle_cancer()
/datum/organ/internal/proc/handle_germs()
var/antibiotics = owner.reagents.get_reagent_amount(SPACEACILLIN)
if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30))
germ_level--
if (germ_level >= INFECTION_LEVEL_ONE/2)
//aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes
if(antibiotics < 5 && prob(round(germ_level/6)))
germ_level++
if (germ_level >= INFECTION_LEVEL_TWO)
var/datum/organ/external/parent = owner.get_organ(parent_organ)
//spread germs
if (antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) ))
parent.germ_level++
if (prob(3)) //about once every 30 seconds
take_damage(1,silent=prob(30))
/datum/organ/internal/handle_cancer()
if(robotic == 2) //This is a fully robotic limb, no cells for cancer to grow from
return 0
var/datum/organ/external/parent = owner.get_organ(parent_organ)
switch(cancer_stage)
if(CANCER_STAGE_SMALL_TUMOR to CANCER_STAGE_LARGE_TUMOR) //Small tumors will not damage your organ, but might flash pain
if(prob(1))
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
if(CANCER_STAGE_LARGE_TUMOR to CANCER_STAGE_METASTASIS) //Large tumors will start damaging your organ and give the owner DNA damage (bodywide, can't go per limb)
if(prob(20))
take_damage(0.25)
if(prob(1))
owner.apply_damage(0.5, CLONE, parent)
if(CANCER_STAGE_METASTASIS to INFINITY) //Metastasis achieved, limb will start breaking down very rapidly, and cancer will spread to all other limbs in short order through bloodstream
if(prob(33))
take_damage(0.25)
if(prob(10))
owner.apply_damage(0.5, CLONE, parent)
if(prob(1))
owner.add_cancer() //Add a new cancerous growth
/datum/organ/internal/proc/take_damage(amount, var/silent=0)
if(!owner)
return
if(src.robotic == 2)
src.damage += (amount * 0.8)
else
src.damage += amount
var/datum/organ/external/parent = owner.get_organ(parent_organ)
if (!silent)
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
/datum/organ/internal/proc/emp_act(severity)
switch(robotic)
if(0)
return
if(1)
switch (severity)
if (1.0)
take_damage(20,0)
return
if (2.0)
take_damage(7,0)
return
if(3.0)
take_damage(3,0)
return
if(2)
switch (severity)
if (1.0)
take_damage(40,0)
return
if (2.0)
take_damage(15,0)
return
if(3.0)
take_damage(10,0)
return
/datum/organ/internal/proc/mechanize() //Being used to make robutt hearts, etc
robotic = 2
/datum/organ/internal/proc/mechassist() //Used to add things like pacemakers, etc
robotic = 1
min_bruised_damage = 15
min_broken_damage = 35
/****************************************************
INTERNAL ORGANS DEFINES
****************************************************/
//All the internal organs without specific code to them are below
//Hopefully this will be filled in soon ?
/datum/organ/internal/brain
name = "brain"
parent_organ = LIMB_HEAD
organ_type = "brain"
removed_type = /obj/item/organ/internal/brain
vital = 1
/datum/organ/internal/brain/ash
removed_type = /obj/item/organ/internal/brain/ash
/datum/organ/internal/brain/slime_core
removed_type = /obj/item/organ/internal/brain/slime_core
/datum/organ/internal/brain/mushroom_brain
removed_type = /obj/item/organ/internal/brain/mushroom
/datum/organ/internal/appendix
name = "appendix"
parent_organ = LIMB_GROIN
organ_type = "appendix"
removed_type = /obj/item/organ/internal/appendix
/datum/organ/internal/proc/remove(var/mob/user, var/quiet=0)
if(!removed_type)
return 0
var/obj/item/organ/internal/removed_organ
if(isatom(removed_type))
removed_organ = removed_type
removed_organ.forceMove(get_turf(user))
removed_type = null
else
removed_organ = new removed_type(get_turf(user))
if(istype(removed_organ))
removed_organ.organ_data = src
if(owner)
removed_organ.had_mind = !isnull(owner.mind)
removed_organ.update()
removed_organ.stabilized = FALSE
return removed_organ
/datum/organ/internal/send_to_past(var/duration)
..()
var/static/list/resettable_vars = list(
"damage",
"robotic")
reset_vars_after_duration(resettable_vars, duration)