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.
This commit is contained in:
phil235
2016-09-13 20:14:38 +02:00
parent 37944a1100
commit d0a1bb715d
10 changed files with 40 additions and 26 deletions
@@ -6,7 +6,7 @@
if (notransform)
return
if(..())
if(..()) //not dead
// GROW!
if(amount_grown < max_grown)
amount_grown++
+7 -1
View File
@@ -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)))
+5 -3
View File
@@ -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 //
///////////////
-6
View File
@@ -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
+7 -7
View File
@@ -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
+3
View File
@@ -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)
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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("<span class='warning'>[src.cable] rapidly retracts back into its spool.</span>", "<span class='italics'>You hear a click and the sound of wire spooling rapidly.</span>")
@@ -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
@@ -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