From d0a1bb715dc941ca15b266960071003a67737dde Mon Sep 17 00:00:00 2001 From: phil235 Date: Tue, 13 Sep 2016 20:14:38 +0200 Subject: [PATCH] Fixes some potential issues with life(). Ever since we added instantaneous damage calculation a mob can die mid life() (and even be deleted for animals that delete on death, and potential gibbing). This means we need to check if stat is still not DEAD after calling every handle_X proc and before calling the next handle_Y proc that assumes the mob is not dead. (example: human is alive, handle_A() is called and ends up gibbing the human, which qdels it and makes its dna var null; then the life.dm() proc continues and calls handle_B() and assumes the human is still alive, that proc needs to call dna.something and BAM! Runtime!) Also fixes targets_from var of hostile animal not being cleared when mob is deleted. Finally, the automatic forced mob unbuckling when the mob is gibbed is moved to living/Destroy() so that it covers all possible deletions. --- code/modules/mob/living/carbon/alien/larva/life.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 8 +++++++- code/modules/mob/living/carbon/life.dm | 8 +++++--- code/modules/mob/living/death.dm | 6 ------ code/modules/mob/living/life.dm | 14 +++++++------- code/modules/mob/living/living.dm | 3 +++ code/modules/mob/living/silicon/ai/life.dm | 2 +- code/modules/mob/living/silicon/pai/life.dm | 4 ++-- .../mob/living/simple_animal/hostile/hostile.dm | 6 +++++- .../mob/living/simple_animal/simple_animal.dm | 13 +++++++++---- 10 files changed, 40 insertions(+), 26 deletions(-) diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 0f4de4b6890..0ff617d7532 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -6,7 +6,7 @@ if (notransform) return - if(..()) + if(..()) //not dead // GROW! if(amount_grown < max_grown) amount_grown++ diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 0c3b27ba8d1..5d7003106aa 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -29,20 +29,26 @@ if (notransform) return - if(..()) + if(..()) //not dead for(var/datum/mutation/human/HM in dna.mutations) HM.on_life(src) + if(stat != DEAD) //heart attack stuff handle_heart() + if(stat != DEAD) //Stuff jammed in your limbs hurts handle_embedded_objects() + //Update our name based on whether our face is obscured/disfigured name = get_visible_name() dna.species.spec_life(src) // for mutantraces + if(stat != DEAD) + return 1 + /mob/living/carbon/human/calculate_affecting_pressure(pressure) if((wear_suit && (wear_suit.flags & STOPSPRESSUREDMAGE)) && (head && (head.flags & STOPSPRESSUREDMAGE))) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index aa701d7f1b3..aa898296f9a 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -9,11 +9,10 @@ damageoverlaytemp = 0 update_damage_hud() - if(..()) - . = 1 - + if(..()) //not dead handle_blood() + if(stat != DEAD) for(var/X in internal_organs) var/obj/item/organ/O = X O.on_life() @@ -21,6 +20,9 @@ //Updates the number of stored chemicals for powers handle_changeling() + if(stat != DEAD) + return 1 + /////////////// // BREATHING // /////////////// diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 10c9a2a50f8..6695c4a1271 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -3,13 +3,9 @@ if(stat != DEAD) death(1) - if(buckled) - buckled.unbuckle_mob(src,force=1) //to update alien nest overlay, forced because we don't exist anymore - if(!prev_lying) gib_animation() - spill_organs(no_brain, no_organs, no_bodyparts) if(!no_bodyparts) @@ -64,8 +60,6 @@ living_mob_list -= src if(!gibbed) dead_mob_list += src - else if(buckled) - buckled.unbuckle_mob(src,force=1) paralysis = 0 stunned = 0 weakened = 0 diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 5d2c0c48535..19cca48a15b 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -19,21 +19,18 @@ var/datum/gas_mixture/environment = loc.return_air() if(stat != DEAD) - //Breathing, if applicable handle_breathing() - + if(stat != DEAD) //Mutations and radiation handle_mutations_and_radiation() - + if(stat != DEAD) //Chemicals in the body handle_chemicals_in_body() - + if(stat != DEAD) //Random events (vomiting etc) handle_random_events() - . = 1 - //Handle temperature/pressure differences between body and environment if(environment) handle_environment(environment) @@ -48,11 +45,14 @@ if(machine) machine.check_eye(src) - if(stat != DEAD) handle_disabilities() // eye, ear, brain damages + if(stat != DEAD) handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc + if(stat != DEAD) + return 1 + /mob/living/proc/handle_breathing() return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b06fef840ca..74a24079251 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -29,6 +29,9 @@ /mob/living/Destroy() ..() + if(buckled) + buckled.unbuckle_mob(src,force=1) + for(var/mob/living/simple_animal/drone/D in player_list) for(var/image/I in staticOverlays) D.staticOverlays.Remove(I) diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 946f2e04900..c4a68499d21 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -4,7 +4,7 @@ #define POWER_RESTORATION_APC_FOUND 3 /mob/living/silicon/ai/Life() - if (src.stat == DEAD) + if (stat == DEAD) return else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist //Being dead doesn't mean your temperature never changes diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm index 191f28d7c37..f934a959316 100644 --- a/code/modules/mob/living/silicon/pai/life.dm +++ b/code/modules/mob/living/silicon/pai/life.dm @@ -1,7 +1,7 @@ /mob/living/silicon/pai/Life() - if (src.stat == DEAD) + if(stat == DEAD) return - if(src.cable) + if(cable) if(get_dist(src, src.cable) > 1) var/turf/T = get_turf(src.loc) T.visible_message("[src.cable] rapidly retracts back into its spool.", "You hear a click and the sound of wire spooling rapidly.") diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 2f75310ff25..58cd9503ede 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -53,6 +53,10 @@ environment_target_typecache = typecacheof(environment_target_typecache) +/mob/living/simple_animal/hostile/Destroy() + targets_from = null + return ..() + /mob/living/simple_animal/hostile/Life() . = ..() if(!.) //dead @@ -225,7 +229,7 @@ else Goto(target,move_to_delay,minimum_distance) if(target) - if(isturf(targets_from.loc) && target.Adjacent(targets_from)) //If they're next to us, attack + if(targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from)) //If they're next to us, attack AttackingTarget() return 1 return 0 diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index edca0beac1d..0821369f929 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -104,10 +104,14 @@ /mob/living/simple_animal/Life() if(..()) //alive if(!ckey) - handle_automated_movement() - handle_automated_action() - handle_automated_speech() - return 1 + if(stat != DEAD) + handle_automated_movement() + if(stat != DEAD) + handle_automated_action() + if(stat != DEAD) + handle_automated_speech() + if(stat != DEAD) + return 1 /mob/living/simple_animal/updatehealth() ..() @@ -302,6 +306,7 @@ ghostize() stat = DEAD qdel(src) + return else health = 0 icon_state = icon_dead