diff --git a/code/datums/components/defibrillator.dm b/code/datums/components/defibrillator.dm
index 32144f9279e..b2b244e98ac 100644
--- a/code/datums/components/defibrillator.dm
+++ b/code/datums/components/defibrillator.dm
@@ -242,7 +242,7 @@
busy = FALSE
return
- if(target.stat != DEAD)
+ if(target.stat != DEAD && !HAS_TRAIT(target, TRAIT_FAKEDEATH))
user.visible_message("[defib_ref] buzzes: Patient is not in a valid state. Operation aborted.")
playsound(get_turf(defib_ref), 'sound/machines/defib_failed.ogg', 50, 0)
SEND_SIGNAL(parent, COMSIG_DEFIB_ABORTED, user, target, should_cause_harm)
@@ -262,6 +262,8 @@
// run through some quick failure states after shocking.
+ var/obj/item/organ/internal/brain/brain_org = target.get_organ_slot("brain")
+
if(tplus > tlimit || (!target.get_int_organ(/obj/item/organ/internal/heart || !target.get_int_organ(/obj/item/organ/internal/brain/slime))))
user.visible_message("[defib_ref] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.")
defib_success = FALSE
@@ -274,13 +276,16 @@
else if (target.blood_volume < BLOOD_VOLUME_SURVIVE)
user.visible_message("[defib_ref] buzzes: Resuscitation failed - Patient blood volume critically low.")
defib_success = FALSE
+ else if(!istype(brain_org)) // so things like headless clings don't get outed
+ user.visible_message("[defib_ref] buzzes: Resuscitation failed - No brain detected within patient.")
+ defib_success = FALSE
else if(ghost)
if(!ghost.can_reenter_corpse) // DNR or AntagHUD
user.visible_message("[defib_ref] buzzes: Resuscitation failed - No electrical brain activity detected.")
else
user.visible_message("[defib_ref] buzzes: Resuscitation failed - Patient's brain is unresponsive. Further attempts may succeed.")
defib_success = FALSE
- else if(HAS_TRAIT(target, TRAIT_BADDNA) || (signal_result & COMPONENT_BLOCK_DEFIB)) // these are a bit more arbitrary
+ else if((signal_result & COMPONENT_BLOCK_DEFIB) || HAS_TRAIT(target, TRAIT_FAKEDEATH) || HAS_TRAIT(target, TRAIT_BADDNA)) // these are a bit more arbitrary
user.visible_message("[defib_ref] buzzes: Resuscitation failed.")
defib_success = FALSE
diff --git a/code/datums/diseases/advance/symptoms/beard.dm b/code/datums/diseases/advance/symptoms/beard.dm
index d2c9819e098..b3eaaba83cc 100644
--- a/code/datums/diseases/advance/symptoms/beard.dm
+++ b/code/datums/diseases/advance/symptoms/beard.dm
@@ -31,6 +31,8 @@ BONUS
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
+ if(!istype(head_organ))
+ return
switch(A.stage)
if(1, 2)
to_chat(H, "Your chin itches.")
diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm
index 2a6b0ba5bac..917ccbf14f6 100644
--- a/code/datums/diseases/advance/symptoms/shedding.dm
+++ b/code/datums/diseases/advance/symptoms/shedding.dm
@@ -26,23 +26,26 @@ BONUS
/datum/symptom/shedding/Activate(datum/disease/advance/A)
..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- to_chat(M, "[pick("Your scalp itches.", "Your skin feels flakey.")]")
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(NO_HAIR in H.dna.species.species_traits)
- return // Hair can't fall out if you don't have any
- var/obj/item/organ/external/head/head_organ = H.get_organ("head")
- switch(A.stage)
- if(3, 4)
- if(!(head_organ.h_style == "Bald") && !(head_organ.h_style == "Balding Hair"))
- to_chat(H, "Your hair starts to fall out in clumps...")
- addtimer(CALLBACK(src, PROC_REF(change_hair), H, head_organ, null, "Balding Hair"), 5 SECONDS)
- if(5)
- if(!(head_organ.f_style == "Shaved") || !(head_organ.h_style == "Bald"))
- to_chat(H, "Your hair starts to fall out in clumps...")
- addtimer(CALLBACK(src, PROC_REF(change_hair), H, head_organ, "Shaved", "Bald"), 5 SECONDS)
+ if(!prob(SYMPTOM_ACTIVATION_PROB))
+ return
+ if(!ishuman(A.affected_mob))
+ return
+ var/mob/living/carbon/human/H = A.affected_mob
+ var/obj/item/organ/external/head/head_organ = H.get_organ("head")
+ if(!istype(head_organ))
+ return
+ to_chat(H, "[pick("Your scalp itches.", "Your skin feels flakey.")]")
+ if(NO_HAIR in H.dna.species.species_traits)
+ return // Hair can't fall out if you don't have any
+ switch(A.stage)
+ if(3, 4)
+ if(head_organ.h_style != "Bald" && head_organ.h_style != "Balding Hair")
+ to_chat(H, "Your hair starts to fall out in clumps...")
+ addtimer(CALLBACK(src, PROC_REF(change_hair), H, head_organ, null, "Balding Hair"), 5 SECONDS)
+ if(5)
+ if((head_organ.f_style != "Shaved") || (head_organ.h_style != "Bald"))
+ to_chat(H, "Your hair starts to fall out in clumps...")
+ addtimer(CALLBACK(src, PROC_REF(change_hair), H, head_organ, "Shaved", "Bald"), 5 SECONDS)
/datum/symptom/shedding/proc/change_hair(mob/living/carbon/human/H, obj/item/organ/external/head/head_organ, f_style, h_style)
if(!H || !head_organ)
diff --git a/code/game/dna/mutations/powers.dm b/code/game/dna/mutations/powers.dm
index b23c12d8874..b1860da7d95 100644
--- a/code/game/dna/mutations/powers.dm
+++ b/code/game/dna/mutations/powers.dm
@@ -766,58 +766,60 @@
if(new_eyes)
M.change_eye_color(new_eyes)
- //Alt heads.
- if(head_organ.dna.species.bodyflags & HAS_ALT_HEADS)
- var/list/valid_alt_heads = M.generate_valid_alt_heads()
- var/new_alt_head = input("Please select alternate head", "Character Generation", head_organ.alt_head) as null|anything in valid_alt_heads
- if(new_alt_head)
- M.change_alt_head(new_alt_head)
+ if(istype(head_organ))
+ //Alt heads.
+ if(head_organ.dna.species.bodyflags & HAS_ALT_HEADS)
+ var/list/valid_alt_heads = M.generate_valid_alt_heads()
+ var/new_alt_head = input("Please select alternate head", "Character Generation", head_organ.alt_head) as null|anything in valid_alt_heads
+ if(new_alt_head)
+ M.change_alt_head(new_alt_head)
- // hair
- var/list/valid_hairstyles = M.generate_valid_hairstyles()
- var/new_style = input("Please select hair style", "Character Generation", head_organ.h_style) as null|anything in valid_hairstyles
+ // hair
+ var/list/valid_hairstyles = M.generate_valid_hairstyles()
+ var/new_style = input("Please select hair style", "Character Generation", head_organ.h_style) as null|anything in valid_hairstyles
- // if new style selected (not cancel)
- if(new_style)
- M.change_hair(new_style)
+ // if new style selected (not cancel)
+ if(new_style)
+ M.change_hair(new_style)
- var/new_hair = input("Please select hair color.", "Character Generation", head_organ.hair_colour) as null|color
- if(new_hair)
- M.change_hair_color(new_hair)
-
- var/datum/sprite_accessory/hair_style = GLOB.hair_styles_public_list[head_organ.h_style]
- if(hair_style.secondary_theme && !hair_style.no_sec_colour)
- new_hair = input("Please select secondary hair color.", "Character Generation", head_organ.sec_hair_colour) as null|color
+ var/new_hair = input("Please select hair color.", "Character Generation", head_organ.hair_colour) as null|color
if(new_hair)
- M.change_hair_color(new_hair, 1)
+ M.change_hair_color(new_hair)
- // facial hair
- var/list/valid_facial_hairstyles = M.generate_valid_facial_hairstyles()
- new_style = input("Please select facial style", "Character Generation", head_organ.f_style) as null|anything in valid_facial_hairstyles
+ var/datum/sprite_accessory/hair_style = GLOB.hair_styles_public_list[head_organ.h_style]
+ if(hair_style.secondary_theme && !hair_style.no_sec_colour)
+ new_hair = input("Please select secondary hair color.", "Character Generation", head_organ.sec_hair_colour) as null|color
+ if(new_hair)
+ M.change_hair_color(new_hair, TRUE)
- if(new_style)
- M.change_facial_hair(new_style)
+ // facial hair
+ var/list/valid_facial_hairstyles = M.generate_valid_facial_hairstyles()
+ new_style = input("Please select facial style", "Character Generation", head_organ.f_style) as null|anything in valid_facial_hairstyles
- var/new_facial = input("Please select facial hair color.", "Character Generation", head_organ.facial_colour) as null|color
- if(new_facial)
- M.change_facial_hair_color(new_facial)
+ if(new_style)
+ M.change_facial_hair(new_style)
- var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[head_organ.f_style]
- if(facial_hair_style.secondary_theme && !facial_hair_style.no_sec_colour)
- new_facial = input("Please select secondary facial hair color.", "Character Generation", head_organ.sec_facial_colour) as null|color
+ var/new_facial = input("Please select facial hair color.", "Character Generation", head_organ.facial_colour) as null|color
if(new_facial)
- M.change_facial_hair_color(new_facial, 1)
+ M.change_facial_hair_color(new_facial)
- //Head accessory.
- if(head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY)
- var/list/valid_head_accessories = M.generate_valid_head_accessories()
- var/new_head_accessory = input("Please select head accessory style", "Character Generation", head_organ.ha_style) as null|anything in valid_head_accessories
- if(new_head_accessory)
- M.change_head_accessory(new_head_accessory)
+ var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[head_organ.f_style]
+ if(facial_hair_style.secondary_theme && !facial_hair_style.no_sec_colour)
+ new_facial = input("Please select secondary facial hair color.", "Character Generation", head_organ.sec_facial_colour) as null|color
+ if(new_facial)
+ M.change_facial_hair_color(new_facial, TRUE)
+
+ //Head accessory.
+ if(head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY)
+ var/list/valid_head_accessories = M.generate_valid_head_accessories()
+ var/new_head_accessory = input("Please select head accessory style", "Character Generation", head_organ.ha_style) as null|anything in valid_head_accessories
+ if(new_head_accessory)
+ M.change_head_accessory(new_head_accessory)
+
+ var/new_head_accessory_colour = input("Please select head accessory colour.", "Character Generation", head_organ.headacc_colour) as null|color
+ if(new_head_accessory_colour)
+ M.change_head_accessory_color(new_head_accessory_colour)
- var/new_head_accessory_colour = input("Please select head accessory colour.", "Character Generation", head_organ.headacc_colour) as null|color
- if(new_head_accessory_colour)
- M.change_head_accessory_color(new_head_accessory_colour)
//Body accessory.
if((M.dna.species.tail && M.dna.species.bodyflags & (HAS_TAIL)) || (M.dna.species.wing && M.dna.species.bodyflags & (HAS_WING)))
@@ -827,16 +829,18 @@
if(new_body_accessory)
M.change_body_accessory(new_body_accessory)
- //Head markings.
- if(M.dna.species.bodyflags & HAS_HEAD_MARKINGS)
- var/list/valid_head_markings = M.generate_valid_markings("head")
- var/new_marking = input("Please select head marking style", "Character Generation", M.m_styles["head"]) as null|anything in valid_head_markings
- if(new_marking)
- M.change_markings(new_marking, "head")
+ if(istype(head_organ))
+ //Head markings.
+ if(M.dna.species.bodyflags & HAS_HEAD_MARKINGS)
+ var/list/valid_head_markings = M.generate_valid_markings("head")
+ var/new_marking = input("Please select head marking style", "Character Generation", M.m_styles["head"]) as null|anything in valid_head_markings
+ if(new_marking)
+ M.change_markings(new_marking, "head")
+
+ var/new_marking_colour = input("Please select head marking colour.", "Character Generation", M.m_colours["head"]) as null|color
+ if(new_marking_colour)
+ M.change_marking_color(new_marking_colour, "head")
- var/new_marking_colour = input("Please select head marking colour.", "Character Generation", M.m_colours["head"]) as null|color
- if(new_marking_colour)
- M.change_marking_color(new_marking_colour, "head")
//Body markings.
if(M.dna.species.bodyflags & HAS_BODY_MARKINGS)
var/list/valid_body_markings = M.generate_valid_markings("body")
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 86497f5eefa..81d9c394637 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -229,7 +229,7 @@
var/occupantData[0]
if(occupant)
occupantData["name"] = occupant.name
- occupantData["stat"] = occupant.stat
+ occupantData["stat"] = HAS_TRAIT(occupant, TRAIT_FAKEDEATH) ? DEAD : occupant.stat
occupantData["health"] = occupant.health
occupantData["maxHealth"] = occupant.maxHealth
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index eed6f6627ba..8e6268ed726 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -786,7 +786,7 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
visible_message("[user] headbutts the airlock.")
var/obj/item/organ/external/affecting = H.get_organ("head")
H.Weaken(10 SECONDS)
- if(affecting.receive_damage(10, 0))
+ if(istype(affecting) && affecting.receive_damage(10, 0))
H.UpdateDamageIcon()
else
visible_message("[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.")
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index d9530d82408..d746c74242f 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -597,7 +597,8 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
if(!eyes) // should still get stabbed in the head
var/obj/item/organ/external/head/head = H.bodyparts_by_name["head"]
- head.receive_damage(rand(10,14), 1)
+ if(head)
+ head.receive_damage(rand(10, 14), 1)
return
eyes.receive_damage(rand(3,4), 1)
if(eyes.damage >= eyes.min_bruised_damage)
@@ -615,7 +616,7 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
if(M.stat != 2)
to_chat(M, "You go blind!")
var/obj/item/organ/external/affecting = H.get_organ("head")
- if(affecting.receive_damage(7))
+ if(istype(affecting) && affecting.receive_damage(7))
H.UpdateDamageIcon()
else
M.take_organ_damage(7)
diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm
index 7fb532cb501..90dd8b77f83 100644
--- a/code/game/objects/items/weapons/cosmetics.dm
+++ b/code/game/objects/items/weapons/cosmetics.dm
@@ -111,6 +111,9 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/head/C = H.get_organ("head")
+ if(!istype(C))
+ to_chat(user, "There's nothing to cut, [M] [M.p_are()] missing [M.p_their()] head!")
+ return ..()
var/datum/robolimb/robohead = GLOB.all_robolimbs[C.model]
if(user.zone_selected == "mouth")
if(!get_location_accessible(H, "mouth"))
diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm
index 7cf73d16f01..afc917a9667 100644
--- a/code/game/objects/items/weapons/scissors.dm
+++ b/code/game/objects/items/weapons/scissors.dm
@@ -28,6 +28,9 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/head/C = H.get_organ("head")
+ if(!C)
+ to_chat(user, "[M] doesn't have a head!")
+ return
//facial hair
var/f_new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in H.generate_valid_facial_hairstyles()
//handle normal hair
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index 3cded3b9768..5569410cf9e 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -122,7 +122,7 @@
if(!QDELETED(H) && air_contents && air_contents.return_pressure() >= 1000)
var/obj/item/organ/external/head/head = H.get_organ("head")
- head.disfigure()
+ head?.disfigure()
H.inflate_gib()
return OBLITERATION
diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm
index 9540ab7932a..676c3f7786f 100644
--- a/code/game/objects/structures/guillotine.dm
+++ b/code/game/objects/structures/guillotine.dm
@@ -108,7 +108,7 @@
var/obj/item/organ/external/head/head = H.get_organ("head")
- if(QDELETED(head))
+ if(QDELETED(head) || !istype(head))
blade_status = GUILLOTINE_BLADE_DROPPED
icon_state = "guillotine"
return
diff --git a/code/modules/antagonists/changeling/datum_changeling.dm b/code/modules/antagonists/changeling/datum_changeling.dm
index a86d183dbf5..6c1fd388bb4 100644
--- a/code/modules/antagonists/changeling/datum_changeling.dm
+++ b/code/modules/antagonists/changeling/datum_changeling.dm
@@ -111,6 +111,17 @@
for(var/power_type in innate_powers)
give_power(new power_type, L)
+ RegisterSignal(L, COMSIG_MOB_DEATH, PROC_REF(on_death))
+
+ var/mob/living/carbon/C = L
+
+ if(!istype(C))
+ return
+
+ // Brains are optional for changelings.
+ var/obj/item/organ/internal/brain/ling_brain = C.get_organ_slot("brain")
+ ling_brain?.decoy_brain = TRUE
+
/datum/antagonist/changeling/remove_innate_effects(mob/living/mob_override)
var/mob/living/L = ..()
if(!ishuman(L))
@@ -120,6 +131,7 @@
L.hud_used.lingchemdisplay.invisibility = 101
L.remove_language("Changeling")
remove_unnatural_languages(L)
+ UnregisterSignal(L, COMSIG_MOB_DEATH)
// If there's a mob_override, this is a body transfer, and therefore we should only remove their powers from the old body.
if(mob_override)
for(var/datum/action/changeling/power in acquired_powers)
@@ -128,6 +140,16 @@
else
respec(FALSE)
+ var/mob/living/carbon/C = L
+
+ if(!istype(C))
+ return
+
+ // If they get de-clinged, make sure they can't just chop their own head off for the hell of it
+ var/obj/item/organ/internal/brain/former_ling_brain = C.get_organ_slot("brain")
+ if(former_ling_brain && former_ling_brain.decoy_brain != initial(former_ling_brain.decoy_brain))
+ former_ling_brain.decoy_brain = FALSE
+
/*
* Always absorb X amount of genomes, plus random traitor objectives.
* If they have two objectives as well as absorb, they must survive rather than escape.
@@ -400,5 +422,18 @@
return FALSE
return TRUE
+/datum/antagonist/changeling/proc/on_death(mob/living/L, gibbed)
+ SIGNAL_HANDLER
+ if(QDELETED(L) || gibbed) // they were probably incinerated or gibbed, no coming back from that.
+ return
+ var/mob/living/carbon/human/H = L
+ if(!istype(H))
+ return
+
+ if(!H.get_organ_slot("brain"))
+ to_chat(L, "The brain is a useless organ to us, we are able to regenerate!")
+ else
+ to_chat(L, "While our current form may be lifeless, this is not the end for us as we can still regenerate!")
+
/proc/ischangeling(mob/M)
return M.mind?.has_antag_datum(/datum/antagonist/changeling)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
index e95dbe17534..361051f3e8d 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
@@ -91,7 +91,7 @@
return 0
var/mob/living/carbon/human/C = G.affecting
var/obj/item/organ/external/head/head = C.get_organ("head")
- if(!head)
+ if(!istype(head))
to_chat(user, "This person doesn't have a head!")
return 0
C.visible_message("[user] dunks [C]'s face into [src]!", \
diff --git a/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm b/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm
index 82ae915fa04..ecf8850c546 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm
@@ -51,7 +51,7 @@
return 0
var/mob/living/carbon/human/C = G.affecting
var/obj/item/organ/external/head/head = C.get_organ("head")
- if(!head)
+ if(!istype(head))
to_chat(user, "This person doesn't have a head!")
return 0
C.visible_message("[user] bashes [C]'s head in [src]'s door!", \
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index 793440bb760..5e57fda2546 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -10,13 +10,14 @@
gender = new_gender
- var/datum/sprite_accessory/hair/current_hair = GLOB.hair_styles_full_list[H.h_style]
- if(current_hair.gender != NEUTER && current_hair.gender != gender)
- reset_head_hair()
+ if(istype(H))
+ var/datum/sprite_accessory/hair/current_hair = GLOB.hair_styles_full_list[H.h_style]
+ if(current_hair.gender != NEUTER && current_hair.gender != gender)
+ reset_head_hair()
- var/datum/sprite_accessory/hair/current_fhair = GLOB.facial_hair_styles_list[H.f_style]
- if(current_fhair.gender != NEUTER && current_fhair.gender != gender)
- reset_facial_hair()
+ var/datum/sprite_accessory/hair/current_fhair = GLOB.facial_hair_styles_list[H.f_style]
+ if(current_fhair.gender != NEUTER && current_fhair.gender != gender)
+ reset_facial_hair()
if(update_dna)
update_dna()
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 662d842bcf6..8358d5fc245 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -361,10 +361,9 @@
msg += "Medical records: \[View\] \[Add comment\]\n"
if(print_flavor_text() && !skipface)
- if(get_organ("head"))
- var/obj/item/organ/external/head/H = get_organ("head")
- if(!(H.status & ORGAN_DISFIGURED))
- msg += "[print_flavor_text()]\n"
+ var/obj/item/organ/external/head/H = get_organ("head")
+ if(H && !(H.status & ORGAN_DISFIGURED))
+ msg += "[print_flavor_text()]\n"
msg += "*---------*"
if(pose)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 2928f79caa2..2d1bc194aec 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1393,32 +1393,33 @@
//Handle default hair/head accessories for created mobs.
var/obj/item/organ/external/head/H = get_organ("head")
- if(dna.species.default_hair)
- H.h_style = dna.species.default_hair
- else
- H.h_style = "Bald"
- if(dna.species.default_fhair)
- H.f_style = dna.species.default_fhair
- else
- H.f_style = "Shaved"
- if(dna.species.default_headacc)
- H.ha_style = dna.species.default_headacc
- else
- H.ha_style = "None"
+ if(istype(H))
+ if(dna.species.default_hair)
+ H.h_style = dna.species.default_hair
+ else
+ H.h_style = "Bald"
+ if(dna.species.default_fhair)
+ H.f_style = dna.species.default_fhair
+ else
+ H.f_style = "Shaved"
+ if(dna.species.default_headacc)
+ H.ha_style = dna.species.default_headacc
+ else
+ H.ha_style = "None"
- if(dna.species.default_hair_colour)
- //Apply colour.
- H.hair_colour = dna.species.default_hair_colour
- else
- H.hair_colour = "#000000"
- if(dna.species.default_fhair_colour)
- H.facial_colour = dna.species.default_fhair_colour
- else
- H.facial_colour = "#000000"
- if(dna.species.default_headacc_colour)
- H.headacc_colour = dna.species.default_headacc_colour
- else
- H.headacc_colour = "#000000"
+ if(dna.species.default_hair_colour)
+ //Apply colour.
+ H.hair_colour = dna.species.default_hair_colour
+ else
+ H.hair_colour = "#000000"
+ if(dna.species.default_fhair_colour)
+ H.facial_colour = dna.species.default_fhair_colour
+ else
+ H.facial_colour = "#000000"
+ if(dna.species.default_headacc_colour)
+ H.headacc_colour = dna.species.default_headacc_colour
+ else
+ H.headacc_colour = "#000000"
m_styles = DEFAULT_MARKING_STYLES //Wipes out markings, setting them all to "None".
m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings.
@@ -1525,6 +1526,8 @@
/mob/living/carbon/human/proc/get_eye_shine() //Referenced cult constructs for shining in the dark. Needs to be above lighting effects such as shading.
var/obj/item/organ/external/head/head_organ = get_organ("head")
+ if(!istype(head_organ))
+ return
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style]
var/icon/hair = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
var/mutable_appearance/MA = mutable_appearance(get_icon_difference(get_eyecon(), hair), layer = ABOVE_LIGHTING_LAYER)
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 5d45ce51925..d569186ca97 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -64,6 +64,10 @@
if(sponge)
return min(sponge.damage,maxHealth*2)
else
+ if(ischangeling(src))
+ // if a changeling has no brain, they have no brain damage.
+ return 0
+
return 200
else
return 0
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index 5808f42bfca..26a61e7cfa9 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -847,7 +847,7 @@
if(radiation > RAD_MOB_HAIRLOSS)
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
- if(!head_organ || (NO_HAIR in species_traits))
+ if(!istype(head_organ) || (NO_HAIR in species_traits))
return
if(prob(15) && head_organ.h_style != "Bald")
to_chat(H, "Your hair starts to fall out in clumps...")
@@ -1019,4 +1019,4 @@ It'll return null if the organ doesn't correspond, so include null checks when u
return H.skin_colour
else
var/obj/item/organ/external/head/HD = H.get_organ("head")
- return HD.hair_colour
+ return HD?.hair_colour
diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm
index 4a4143c7fbb..49fba255d19 100644
--- a/code/modules/mob/living/carbon/human/species/machine.dm
+++ b/code/modules/mob/living/carbon/human/species/machine.dm
@@ -103,7 +103,7 @@
/datum/species/machine/handle_death(gibbed, mob/living/carbon/human/H)
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
- if(!head_organ)
+ if(!istype(head_organ))
return
head_organ.h_style = "Bald"
head_organ.f_style = "Shaved"
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 2c557e34b9f..96612c49dc1 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -306,7 +306,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
markings_standing.Blend(b_marking_s, ICON_OVERLAY)
//Head markings.
var/obj/item/organ/external/head/head_organ = get_organ("head")
- if(head_organ && m_styles["head"]) //If the head is destroyed, forget the head markings. This prevents floating optical markings on decapitated IPCs, for example.
+ if(istype(head_organ) && m_styles["head"]) //If the head is destroyed, forget the head markings. This prevents floating optical markings on decapitated IPCs, for example.
var/head_marking = m_styles["head"]
var/datum/sprite_accessory/head_marking_style = GLOB.marking_styles_list[head_marking]
if(head_marking_style && head_marking_style.species_allowed && (head_organ.dna.species.name in head_marking_style.species_allowed))
@@ -325,7 +325,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
remove_overlay(HEAD_ACC_OVER_LAYER)
var/obj/item/organ/external/head/head_organ = get_organ("head")
- if(!head_organ)
+ if(!istype(head_organ))
return
//masks and helmets can obscure our head accessory
@@ -360,7 +360,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
remove_overlay(HAIR_LAYER)
var/obj/item/organ/external/head/O = get_organ("head")
- if(!O)
+ if(!istype(O))
return
if((head?.flags & BLOCKHAIR) || (wear_mask?.flags & BLOCKHAIR))
@@ -445,7 +445,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
remove_overlay(FHAIR_OVER_LAYER)
var/obj/item/organ/external/head/head_organ = get_organ("head")
- if(!head_organ)
+ if(!istype(head_organ))
return
//masks and helmets can obscure our facial hair, unless we're a synthetic
@@ -987,7 +987,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
if(wear_mask && (istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory)))
if(!(slot_wear_mask in check_obscured_slots()))
var/obj/item/organ/external/head/head_organ = get_organ("head")
- if(!head_organ)
+ if(!istype(head_organ))
return // Nothing to update here
var/datum/sprite_accessory/alt_heads/alternate_head
if(head_organ.alt_head && head_organ.alt_head != "None")
diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm
index 5db4febebd9..65ef17b0997 100644
--- a/code/modules/mob/living/carbon/superheroes.dm
+++ b/code/modules/mob/living/carbon/superheroes.dm
@@ -220,7 +220,7 @@
SSticker.mode.greyshirts += target.mind
target.set_species(/datum/species/human)
var/obj/item/organ/external/head/head_organ = target.get_organ("head")
- if(head_organ)
+ if(istype(head_organ))
head_organ.h_style = "Bald"
head_organ.f_style = "Shaved"
target.s_tone = 35
diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm
index dfc1723315f..e112fce4017 100644
--- a/code/modules/reagents/chemistry/reagents/misc.dm
+++ b/code/modules/reagents/chemistry/reagents/misc.dm
@@ -355,6 +355,8 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
+ if(!istype(head_organ))
+ return ..()
head_organ.facial_colour = rand_hex_color()
head_organ.sec_facial_colour = rand_hex_color()
head_organ.hair_colour = rand_hex_color()
@@ -376,6 +378,8 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
+ if(!istype(head_organ))
+ return ..()
head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.name)
head_organ.f_style = random_facial_hair_style(H.gender, head_organ.dna.species.name)
H.update_hair()
@@ -395,6 +399,8 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
+ if(!istype(head_organ))
+ return ..()
var/datum/sprite_accessory/tmp_hair_style = GLOB.hair_styles_full_list["Very Long Hair"]
var/datum/sprite_accessory/tmp_facial_hair_style = GLOB.facial_hair_styles_list["Very Long Beard"]
diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm
index c39d7912c05..40c6eb97134 100644
--- a/code/modules/reagents/chemistry/reagents/toxins.dm
+++ b/code/modules/reagents/chemistry/reagents/toxins.dm
@@ -297,7 +297,7 @@
H.take_organ_damage(5, 10)
H.emote("scream")
var/obj/item/organ/external/affecting = H.get_organ("head")
- if(affecting)
+ if(istype(affecting))
affecting.disfigure()
else
H.take_organ_damage(5, 10)
@@ -340,7 +340,7 @@
if(volume > 9)
if(!H.wear_mask && !H.head)
var/obj/item/organ/external/affecting = H.get_organ("head")
- if(affecting)
+ if(istype(affecting))
affecting.disfigure()
H.adjustFireLoss(min(max(8, (volume - 5) * 3), 75))
H.emote("scream")
@@ -380,7 +380,7 @@
return
if(volume >= 50 && prob(75))
var/obj/item/organ/external/affecting = H.get_organ("head")
- if(affecting)
+ if(istype(affecting))
affecting.disfigure()
H.adjustBruteLoss(5)
H.adjustFireLoss(15)
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/surgery/organs/brain.dm
similarity index 88%
rename from code/modules/mob/living/carbon/brain/brain_item.dm
rename to code/modules/surgery/organs/brain.dm
index c2d1235ba6b..7b8720eab14 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/surgery/organs/brain.dm
@@ -18,6 +18,9 @@
var/mmi_icon = 'icons/obj/assemblies.dmi'
var/mmi_icon_state = "mmi_full"
+ /// If it's a fake brain without a mob assigned that should still be treated like a real brain.
+ var/decoy_brain = FALSE
+
/obj/item/organ/internal/brain/xeno
name = "xenomorph brain"
desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?"
@@ -48,12 +51,12 @@
/obj/item/organ/internal/brain/examine(mob/user) // -- TLE
. = ..()
- if(brainmob && brainmob.client)//if thar be a brain inside... the brain.
+ if(brainmob && brainmob.client) //if thar be a brain inside... the brain
. += "You can feel the small spark of life still left in this one."
else
. += "This one seems particularly lifeless. Perhaps it will regain some of its luster later.."
-/obj/item/organ/internal/brain/remove(mob/living/user,special = 0)
+/obj/item/organ/internal/brain/remove(mob/living/user, special = 0)
if(dna)
name = "[dna.real_name]'s [initial(name)]"
@@ -61,27 +64,30 @@
var/obj/item/organ/internal/brain/B = src
if(!special)
- if(owner.mind && !non_primary)//don't transfer if the owner does not have a mind.
+ if(owner.mind && !non_primary && !decoy_brain)//don't transfer if the owner does not have a mind.
B.transfer_identity(user)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
H.update_hair()
-
+
owner.thought_bubble_image = initial(owner.thought_bubble_image)
. = ..()
-/obj/item/organ/internal/brain/insert(mob/living/target,special = 0)
+/obj/item/organ/internal/brain/insert(mob/living/target, special = 0)
name = "[initial(name)]"
- var/brain_already_exists = 0
+ var/brain_already_exists = FALSE
if(ishuman(target)) // No more IPC multibrain shenanigans
if(target.get_int_organ(/obj/item/organ/internal/brain))
- brain_already_exists = 1
+ brain_already_exists = TRUE
var/mob/living/carbon/human/H = target
H.update_hair()
+ if(ischangeling(target))
+ decoy_brain = TRUE
+
if(!brain_already_exists)
if(brainmob)
if(target.key)
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index a3d0c884a8d..6fa711e6180 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -301,7 +301,7 @@
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
- var/obj/item/organ/external/head/head_organ = H.get_organ("head")
+ var/obj/item/organ/external/head/head_organ = H.get_organ("head") // damn well better have a head if you have a beard
if(!(head_organ.h_style == "Very Long Hair" || head_organ.h_style == "Mohawk"))
if(prob(10))
head_organ.h_style = "Mohawk"
diff --git a/paradise.dme b/paradise.dme
index 4f8735b57fc..fe21625f385 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1959,7 +1959,6 @@
#include "code\modules\mob\living\carbon\alien\special\facehugger.dm"
#include "code\modules\mob\living\carbon\brain\brain.dm"
#include "code\modules\mob\living\carbon\brain\brain_emote.dm"
-#include "code\modules\mob\living\carbon\brain\brain_item.dm"
#include "code\modules\mob\living\carbon\brain\death.dm"
#include "code\modules\mob\living\carbon\brain\life.dm"
#include "code\modules\mob\living\carbon\brain\login.dm"
@@ -2538,6 +2537,7 @@
#include "code\modules\surgery\organs\autosurgeon.dm"
#include "code\modules\surgery\organs\blood.dm"
#include "code\modules\surgery\organs\body_egg.dm"
+#include "code\modules\surgery\organs\brain.dm"
#include "code\modules\surgery\organs\ears.dm"
#include "code\modules\surgery\organs\eyes.dm"
#include "code\modules\surgery\organs\heart.dm"