From 7b2c8e58ffb8f50eb3dda68b987a7def56cf188f Mon Sep 17 00:00:00 2001
From: Fermi <>
Date: Mon, 14 Oct 2019 13:23:39 +0100
Subject: [PATCH] Fixes freezing and ghost rider
---
code/__DEFINES/misc.dm | 2 +-
code/__DEFINES/obj_flags.dm | 2 +-
.../structures/crates_lockers/crates.dm | 19 +++++
code/modules/mob/living/brain/brain_item.dm | 5 +-
.../modules/mob/living/carbon/alien/organs.dm | 1 +
code/modules/mob/living/taste.dm | 2 -
code/modules/surgery/organs/autosurgeon.dm | 5 +-
code/modules/surgery/organs/organ_internal.dm | 83 ++++++++++++++++---
code/modules/surgery/organs/tongue.dm | 2 +
9 files changed, 103 insertions(+), 18 deletions(-)
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index ba5e105041..4beff367c5 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -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
diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm
index ba8d229f12..1917d73a1b 100644
--- a/code/__DEFINES/obj_flags.dm
+++ b/code/__DEFINES/obj_flags.dm
@@ -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
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 6caa7d834b..23703c7891 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -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."
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 41a8944015..4192c2235b 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -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, "The last spark of life in your brain fizzles out...")
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)
diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm
index 155f203708..df1be454ee 100644
--- a/code/modules/mob/living/carbon/alien/organs.dm
+++ b/code/modules/mob/living/carbon/alien/organs.dm
@@ -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()
. = ..()
diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm
index 8b0c54653c..e4d1aa94a5 100644
--- a/code/modules/mob/living/taste.dm
+++ b/code/modules/mob/living/taste.dm
@@ -52,13 +52,11 @@
switch(from.pH)
if(11.5 to INFINITY)
to_chat(src, "You taste a strong alkaline flavour!")
- T.applyOrganDamage(1)
if(8.5 to 11.5)
to_chat(src, "You taste a sort of soapy tone in the mixture.")
if(2.5 to 5.5)
to_chat(src, "You taste a sort of acid tone in the mixture.")
if(-INFINITY to 2.5)
to_chat(src, "You taste a strong acidic flavour!")
- T.applyOrganDamage(1)
#undef DEFAULT_TASTE_SENSITIVITY
diff --git a/code/modules/surgery/organs/autosurgeon.dm b/code/modules/surgery/organs/autosurgeon.dm
index 2cc5c554c6..27bf575627 100644
--- a/code/modules/surgery/organs/autosurgeon.dm
+++ b/code/modules/surgery/organs/autosurgeon.dm
@@ -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
\ No newline at end of file
+ starting_organ = /obj/item/organ/genital/womb
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 4ff22c35d8..a32616c711 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -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,26 +67,82 @@
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(CHECK_MULTIPLE_BITFIELDS(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(organ_flags & ORGAN_NO_SPOIL)
+ return FALSE
+ if(organ_flags & ORGAN_SYNTHETIC)
+ return FALSE
+ if((organ_flags & ORGAN_FAILING) || damage >= maxHealth)
+ return FALSE
+ return TRUE
+
+//Checks to see if the organ is frozen from temperature
+/obj/item/organ/proc/is_cold()
+ if(istype(loc, /obj/))//Freezer of some kind, I hope.
+ if(istype(loc, /obj/structure/closet/crate/freezer) || istype(loc, /obj/structure/closet/secure_closet/freezer) || istype(loc, /obj/structure/bodycontainer))
+ 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
+
+ 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
+
+ if(istype(loc, /mob/))
+ var/mob/M = loc
+ var/turf/T = M.loc
+ var/datum/gas_mixture/enviro = T.return_air()
+ local_temp = enviro.temperature
+
+ else if(owner)
+ //Don't interfere with bodies frozen by structures.
+ if(istype(owner.loc, /obj/structure/closet/crate/freezer) || istype(owner.loc, /obj/structure/closet/secure_closet/freezer) || istype(owner.loc, /obj/structure/bodycontainer))
+ 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
+ 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)
. = ..()
@@ -177,6 +236,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)
diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm
index fa6f3ce93b..cee20dddee 100644
--- a/code/modules/surgery/organs/tongue.dm
+++ b/code/modules/surgery/organs/tongue.dm
@@ -211,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)