/**************************************************** 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)