Merge pull request #9477 from Thalpy/tgOrganFixes

[READY] Fixes a few organ code and lets organs freeze based on ambient temperature.
This commit is contained in:
kevinz000
2019-10-16 12:44:34 -07:00
committed by GitHub
18 changed files with 129 additions and 32 deletions
+1 -1
View File
@@ -314,7 +314,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define MAP_MAXZ 6
// Defib stats
#define DEFIB_TIME_LIMIT 960
#define DEFIB_TIME_LIMIT 1500
#define DEFIB_TIME_LOSS 60
// Diagonal movement
+1 -1
View File
@@ -47,4 +47,4 @@
#define ORGAN_FAILING (1<<2) //Failing organs perform damaging effects until replaced or fixed
#define ORGAN_EXTERNAL (1<<3) //Was this organ implanted/inserted/etc, if true will not be removed during species change.
#define ORGAN_VITAL (1<<4) //Currently only the brain
#define ORGAN_NO_SPOIL (1<<5) //Currently only the brain
#define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances
@@ -99,6 +99,25 @@
name = "freezer"
icon_state = "freezer"
//Snowflake organ freezer code
//Order is important, since we check source, we need to do the check whenever we have all the organs in the crate
/obj/structure/closet/crate/freezer/open()
recursive_organ_check(src)
..()
/obj/structure/closet/crate/freezer/close()
..()
recursive_organ_check(src)
/obj/structure/closet/crate/freezer/Destroy()
recursive_organ_check(src)
..()
/obj/structure/closet/crate/freezer/Initialize()
. = ..()
recursive_organ_check(src)
/obj/structure/closet/crate/freezer/blood
name = "blood freezer"
desc = "A freezer containing packs of blood."
+4 -1
View File
@@ -11,6 +11,7 @@
attack_verb = list("attacked", "slapped", "whacked")
///The brain's organ variables are significantly more different than the other organs, with half the decay rate for balance reasons, and twice the maxHealth
decay_factor = STANDARD_ORGAN_DECAY / 4 //30 minutes of decaying to result in a fully damaged brain, since a fast decay rate would be unfun gameplay-wise
healing_factor = STANDARD_ORGAN_HEALING / 2
maxHealth = BRAIN_DAMAGE_DEATH
low_threshold = 45
@@ -247,11 +248,13 @@
to_chat(owner, "<span class='userdanger'>The last spark of life in your brain fizzles out...</span>")
owner.death()
brain_death = TRUE
return
..()
/obj/item/organ/brain/on_death()
if(damage <= BRAIN_DAMAGE_DEATH) //rip
brain_death = FALSE
applyOrganDamage(maxHealth * decay_factor)
..()
/obj/item/organ/brain/applyOrganDamage(var/d, var/maximum = maxHealth)
@@ -1,6 +1,7 @@
/obj/item/organ/alien
icon_state = "xgibmid2"
var/list/alien_powers = list()
organ_flags = ORGAN_NO_SPOIL
/obj/item/organ/alien/Initialize()
. = ..()
-2
View File
@@ -52,13 +52,11 @@
switch(from.pH)
if(11.5 to INFINITY)
to_chat(src, "<span class='warning'>You taste a strong alkaline flavour!</span>")
T.applyOrganDamage(1)
if(8.5 to 11.5)
to_chat(src, "<span class='notice'>You taste a sort of soapy tone in the mixture.</span>")
if(2.5 to 5.5)
to_chat(src, "<span class='notice'>You taste a sort of acid tone in the mixture.</span>")
if(-INFINITY to 2.5)
to_chat(src, "<span class='warning'>You taste a strong acidic flavour!</span>")
T.applyOrganDamage(1)
#undef DEFAULT_TASTE_SENSITIVITY
@@ -104,6 +104,7 @@
var/amount = CLAMP(0.002, 0, N.volume)
N.volume -= amount
St.data["grown_volume"] = St.data["grown_volume"] + added_volume
St.name = "[initial(St.name)] [round(St.data["grown_volume"], 0.1)]u colony"
/datum/chemical_reaction/styptic_powder
name = "Styptic Powder"
+2 -2
View File
@@ -15,7 +15,7 @@
//an incision but with greater bleed, and a 90% base success chance
/datum/surgery_step/incise_heart
name = "incise heart"
implements = list(/obj/item/scalpel = 90, /obj/item/melee/transforming/energy/sword = 45, /obj/item/kitchen/knife = 45,
implements = list(TOOL_SCALPEL = 90, /obj/item/melee/transforming/energy/sword = 45, /obj/item/kitchen/knife = 45,
/obj/item/shard = 25)
time = 16
@@ -74,4 +74,4 @@
"<span class='warning'>[user] screws up, causing blood to spurt out of [H]'s chest profusely!</span>")
H.adjustOrganLoss(ORGAN_SLOT_HEART, 20)
H.bleed_rate += 30
return FALSE
return FALSE
+2 -3
View File
@@ -11,8 +11,7 @@
/datum/surgery_step/embalming
name = "embalming body"
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(/obj/item/reagent_containers/syringe = 100, /obj/item/pen = 30)
implements = list(/obj/item/reagent_containers/syringe = 100, /obj/item/pen = 30)
time = 10
chems_needed = list("drying_agent", "sterilizine")
require_all_chems = FALSE
@@ -28,4 +27,4 @@
/datum/surgery_step/embalming/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] screws up!", "<span class='warning'>You screwed up!</span>")
ADD_TRAIT(target, TRAIT_NOCLONE, MAGIC_TRAIT) //That body is ruined, but still gives miasma
return FALSE
return FALSE
+4 -3
View File
@@ -19,7 +19,7 @@
//repair organs
/datum/surgery_step/graft_synthtissue
name = "graft synthtissue"
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
repeatable = TRUE
time = 75
chems_needed = list("synthtissue")
@@ -61,8 +61,9 @@
target.reagents.remove_reagent("synthtissue", 10)
/datum/surgery_step/graft_synthtissue/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] successfully repairs part of [chosen_organ].", "<span class='notice'>You succeed in repairing parts of [chosen_organ].</span>")
chosen_organ.applyOrganDamage(health_restored)
user.visible_message("[user] successfully grafts synthtissue to [chosen_organ].", "<span class='notice'>You succeed in grafting 10u of the synthflesh to the [chosen_organ].</span>")
chosen_organ.applyOrganDamage(-health_restored)
return TRUE
/datum/surgery_step/graft_synthtissue/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("<span class='warning'>[user] accidentally damages part of [chosen_organ]!</span>", "<span class='warning'>You damage [chosen_organ]! Apply more synthtissue if it's run out.</span>")
+1 -1
View File
@@ -26,7 +26,7 @@
//remove fat
/datum/surgery_step/remove_fat
name = "remove loose fat"
implements = list(/obj/item/retractor = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35)
implements = list(TOOL_RETRACTOR = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35)
time = 32
/datum/surgery_step/remove_fat/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+3 -2
View File
@@ -17,9 +17,10 @@
if(starting_organ)
insert_organ(new starting_organ(src))
/obj/item/autosurgeon/proc/insert_organ(var/obj/item/I)
/obj/item/autosurgeon/proc/insert_organ(var/obj/item/organ/I)
storedorgan = I
I.forceMove(src)
I.organ_flags |= ORGAN_FROZEN //Stops decay
name = "[initial(name)] ([storedorgan.name])"
/obj/item/autosurgeon/attack_self(mob/user)//when the object it used...
@@ -125,4 +126,4 @@
/obj/item/autosurgeon/womb
desc = "A single use autosurgeon that contains a womb. A screwdriver can be used to remove it, but implants can't be placed back in."
uses = 1
starting_organ = /obj/item/organ/genital/womb
starting_organ = /obj/item/organ/genital/womb
+2 -1
View File
@@ -6,7 +6,7 @@
slot = ORGAN_SLOT_HEART
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = 4 * STANDARD_ORGAN_DECAY //designed to fail about 5 minutes after death
decay_factor = 3 * STANDARD_ORGAN_DECAY //designed to fail about 5 minutes after death
low_threshold_passed = "<span class='info'>Prickles of pain appear then die out from within your chest...</span>"
high_threshold_passed = "<span class='warning'>Something inside your chest hurts, and the pain isn't subsiding. You notice yourself breathing far faster than before.</span>"
@@ -61,6 +61,7 @@
return S
/obj/item/organ/heart/on_life()
..()
if(owner.client && beating)
failed = FALSE
var/sound/slowbeat = sound('sound/health/slowbeat.ogg', repeat = TRUE)
+3 -1
View File
@@ -12,10 +12,12 @@
var/operated = FALSE //whether we can still have our damages fixed through surgery
//health
maxHealth = LUNGS_MAX_HEALTH
maxHealth = 3 * STANDARD_ORGAN_THRESHOLD
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = STANDARD_ORGAN_DECAY
high_threshold = 0.6 * LUNGS_MAX_HEALTH //threshold at 180
low_threshold = 0.3 * LUNGS_MAX_HEALTH //threshold at 90
high_threshold_passed = "<span class='warning'>You feel some sort of constriction around your chest as your breathing becomes shallow and rapid.</span>"
now_fixed = "<span class='warning'>Your lungs seem to once again be able to hold air.</span>"
+75 -12
View File
@@ -41,6 +41,9 @@
else
qdel(replaced)
//Hopefully this doesn't cause problems
organ_flags &= ~ORGAN_FROZEN
owner = M
M.internal_organs |= src
M.internal_organs_slot[slot] = src
@@ -64,30 +67,88 @@
A.Remove(M)
START_PROCESSING(SSobj, src)
/obj/item/organ/proc/on_find(mob/living/finder)
return
/obj/item/organ/process()
/obj/item/organ/process() //runs decay when outside of a person AND ONLY WHEN OUTSIDE (i.e. long obj).
on_death() //Kinda hate doing it like this, but I really don't want to call process directly.
/obj/item/organ/proc/on_death() //runs decay when outside of a person
if(organ_flags & (ORGAN_SYNTHETIC | ORGAN_FROZEN | ORGAN_NO_SPOIL))
//Sources; life.dm process_organs
/obj/item/organ/proc/on_death() //Runs when outside AND inside.
decay()
//Applys the slow damage over time decay
/obj/item/organ/proc/decay()
if(!can_decay())
STOP_PROCESSING(SSobj, src)
return
is_cold()
if(organ_flags & ORGAN_FROZEN)
return
applyOrganDamage(maxHealth * decay_factor)
/obj/item/organ/proc/can_decay()
if(CHECK_BITFIELD(organ_flags, ORGAN_NO_SPOIL | ORGAN_SYNTHETIC | ORGAN_FAILING))
return FALSE
return TRUE
//Checks to see if the organ is frozen from temperature
/obj/item/organ/proc/is_cold()
var/freezing_objects = list(/obj/structure/closet/crate/freezer, /obj/structure/closet/secure_closet/freezer, /obj/structure/bodycontainer, /obj/item/autosurgeon)
if(istype(loc, /obj/))//Freezer of some kind, I hope.
if(is_type_in_list(loc, freezing_objects))
if(!(organ_flags & ORGAN_FROZEN))//Incase someone puts them in when cold, but they warm up inside of the thing. (i.e. they have the flag, the thing turns it off, this rights it.)
organ_flags |= ORGAN_FROZEN
return TRUE
return
var/local_temp
if(istype(loc, /turf/))//Only concern is adding an organ to a freezer when the area around it is cold.
var/turf/T = loc
var/datum/gas_mixture/enviro = T.return_air()
local_temp = enviro.temperature
else if(istype(loc, /mob/) && !owner)
var/mob/M = loc
if(is_type_in_list(M.loc, freezing_objects))
if(!(organ_flags & ORGAN_FROZEN))
organ_flags |= ORGAN_FROZEN
return TRUE
var/turf/T = M.loc
var/datum/gas_mixture/enviro = T.return_air()
local_temp = enviro.temperature
if(owner)
//Don't interfere with bodies frozen by structures.
if(is_type_in_list(owner.loc, freezing_objects))
if(!(organ_flags & ORGAN_FROZEN))
organ_flags |= ORGAN_FROZEN
return TRUE
local_temp = owner.bodytemperature
if(!local_temp)//Shouldn't happen but in case
return
if(local_temp < 154)//I have a pretty shaky citation that states -120 allows indefinite cyrostorage
organ_flags |= ORGAN_FROZEN
return TRUE
organ_flags &= ~ORGAN_FROZEN
return FALSE
/obj/item/organ/proc/on_life() //repair organ damage if the organ is not failing
if(!(organ_flags & ORGAN_FAILING))
///Damage decrements by a percent of its maxhealth
var/healing_amount = -(maxHealth * healing_factor)
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's health
healing_amount -= owner.satiety > 0 ? 4 * healing_factor * owner.satiety / MAX_SATIETY : 0
applyOrganDamage(healing_amount) //to FERMI_TWEAK
//Make it so each threshold is stuck.
if(organ_flags & ORGAN_FAILING)
return
if(is_cold())
return
///Damage decrements by a percent of its maxhealth
var/healing_amount = -(maxHealth * healing_factor)
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's health
healing_amount -= owner.satiety > 0 ? 4 * healing_factor * owner.satiety / MAX_SATIETY : 0
applyOrganDamage(healing_amount) //to FERMI_TWEAK
//Make it so each threshold is stuck.
/obj/item/organ/examine(mob/user)
. = ..()
if(!organ_flags & ORGAN_FAILING)
if(organ_flags & ORGAN_FAILING)
if(status == ORGAN_ROBOTIC)
. += "<span class='warning'>[src] seems to be broken!</span>"
return
@@ -177,6 +238,8 @@
return low_threshold_passed
else
organ_flags &= ~ORGAN_FAILING
if(!owner)//Processing is stopped when the organ is dead and outside of someone. This hopefully should restart it if a removed organ is repaired outside of a body.
START_PROCESSING(SSobj, src)
if(prev_damage > low_threshold && damage <= low_threshold)
return low_threshold_cleared
if(prev_damage > high_threshold && damage <= high_threshold)
+1
View File
@@ -17,6 +17,7 @@
low_threshold_cleared = "<span class='info'>The last bouts of pain in your stomach have died out.</span>"
/obj/item/organ/stomach/on_life()
..()
var/datum/reagent/consumable/nutriment/Nutri
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
+4
View File
@@ -23,6 +23,8 @@
/datum/language/aphasia,
/datum/language/slime,
))
healing_factor = STANDARD_ORGAN_HEALING*5 //Fast!!
decay_factor = STANDARD_ORGAN_DECAY/2
/obj/item/organ/tongue/Initialize(mapload)
. = ..()
@@ -209,6 +211,8 @@
phomeme_type = pick(phomeme_types)
/obj/item/organ/tongue/bone/applyOrganDamage(var/d, var/maximum = maxHealth)
if(d < 0)
return
if(!owner)
return
var/target = owner.get_bodypart(BODY_ZONE_HEAD)
@@ -100,7 +100,7 @@
id = "synthtissue"
description = "Synthetic tissue used for grafting onto damaged organs during surgery, or for treating limb damage. Has a very tight growth window between 305-320, any higher and the temperature will cause the cells to die. Additionally, growth time is considerably long, so chemists are encouraged to leave beakers with said reaction ongoing, while they tend to their other duties."
pH = 7.6
metabolization_rate = 0.1
metabolization_rate = 0.05 //Give them time to graft
data = list("grown_volume" = 0, "injected_vol" = 0)
/datum/reagent/synthtissue/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1)
@@ -115,7 +115,7 @@
to_chat(M, "<span class='danger'>You feel your [target] heal! It stings like hell!</span>")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
if(method==INJECT)
data["injected_vol"] = data["injected_vol"] + reac_volume
data["injected_vol"] = reac_volume
..()
/datum/reagent/synthtissue/on_mob_life(mob/living/carbon/C)
@@ -136,6 +136,9 @@
return ..()
if(passed_data["grown_volume"] > data["grown_volume"])
data["grown_volume"] = passed_data["grown_volume"]
if(iscarbon(holder.my_atom))
data["injected_vol"] = data["injected_vol"] + passed_data["injected_vol"]
passed_data["injected_vol"] = 0
..()
/datum/reagent/synthtissue/on_new(passed_data)