From 7ed2ee82bf13e8e4d97298391c099a7b8050128f Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Thu, 4 Aug 2022 14:11:42 +0100
Subject: [PATCH 01/24] core changes
---
code/datums/components/dullahan.dm | 81 +++++++++++++++++++
code/datums/mutable_appearance.dm | 3 +
.../sprite_accessories/_sprite_accessories.dm | 2 +
.../new_player/sprite_accessories/ears.dm | 1 +
.../sprite_accessories/hair_face.dm | 1 +
.../sprite_accessories/hair_head.dm | 1 +
.../new_player/sprite_accessories/horns.dm | 1 +
.../sprite_accessories/ipc_synths.dm | 1 +
.../new_player/sprite_accessories/snouts.dm | 1 +
.../new_player/sprite_accessories/synthliz.dm | 1 +
.../mob/living/carbon/human/species.dm | 14 +++-
.../mob/living/carbon/human/update_icons.dm | 5 +-
code/modules/surgery/bodyparts/head.dm | 16 ++--
tgstation.dme | 1 +
14 files changed, 120 insertions(+), 9 deletions(-)
create mode 100644 code/datums/components/dullahan.dm
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
new file mode 100644
index 0000000000..ee6d5beef0
--- /dev/null
+++ b/code/datums/components/dullahan.dm
@@ -0,0 +1,81 @@
+/datum/component/dullahan
+ var/obj/item/dullahan_head/dullahan_head
+
+
+/datum/component/dullahan/Initialize()
+ var/mob/living/carbon/human/H = parent
+ if(!H)
+ return
+
+ dullahan_head = new(get_turf(H))
+
+ dullahan_head.name = "[H.name]'s head"
+ dullahan_head.desc = "the decapitated head of [H.name]"
+ dullahan_head.owner = H
+
+ // make sure the brain can't decay or fall out
+ var/obj/item/organ/brain/B = H.getorganslot(ORGAN_SLOT_BRAIN)
+ B.zone = "abstract" // it exists in the ethereal plain
+ B.organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT | ORGAN_VITAL
+
+ // moving the brain's zone means we don't need the head to survive
+ var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD)
+ head.drop_limb()
+ qdel(head)
+
+ dullahan_head.update_appearance()
+
+/obj/item/dullahan_head
+ name = "coders lament"
+ desc = "you shouldn't be reading this"
+ flags_1 = HEAR_1
+ var/mob/living/carbon/human/owner
+ // this is for keeping track of the overlays because you can't read the actual overlays list as it's a special byond var
+ var/list/overlays_standing
+
+// allow the 'fake' head to relay speech back to the mob
+/obj/item/dullahan_head/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
+ if(owner)
+ var/namepart = "[speaker.GetVoice()][speaker.get_alt_name()]"
+ var/hrefpart = ""
+ var/treated_message = lang_treat(speaker, message_language, raw_message, spans, message_mode)
+ var/rendered = "[hrefpart][namepart] [treated_message]"
+
+ if (owner.client?.prefs.chat_on_map && (owner.client.prefs.see_chat_non_mob || ismob(speaker)))
+ owner.create_chat_message(speaker, message_language, raw_message, spans, message_mode)
+ owner.show_message(rendered, MSG_AUDIBLE)
+
+// update head sprite
+/obj/item/dullahan_head/proc/remove_head_overlays()
+ overlays_standing = list()
+ cut_overlays()
+
+/obj/item/dullahan_head/proc/add_head_overlay(var/overlay)
+ overlays_standing += overlay
+ add_overlay(overlay)
+
+/obj/item/dullahan_head/update_appearance()
+ remove_head_overlays()
+ // to do this without duplicating large amounts of code
+ // it's best to regenerate the head, then remove it once we have the overlays we want
+ owner.regenerate_limb(BODY_ZONE_HEAD, TRUE) // don't heal them
+ owner.regenerate_icons() // yes i know it's expensive but do you want me to rewrite our entire overlay system
+ var/obj/item/bodypart/head/head = owner.get_bodypart(BODY_ZONE_HEAD)
+ add_overlay(head.get_limb_icon(FALSE, TRUE, TRUE))
+ for(var/overlay in owner.overlays_standing)
+ if(istype(overlay, /mutable_appearance))
+ var/mutable_appearance/mutable = overlay
+ message_admins("category is [mutable.category] and icon is [mutable.icon_state]")
+ if(mutable.category == "HEAD")
+ add_head_overlay(mutable)
+ else
+ if(islist(overlay))
+ var/list/list_appearances = overlay
+ for(var/overlay2 in list_appearances)
+ if(istype(overlay2, /mutable_appearance))
+ var/mutable_appearance/mutable = overlay2
+ message_admins("category is [mutable.category] and icon is [mutable.icon_state]")
+ if(mutable.category == "HEAD")
+ add_head_overlay(mutable)
+ //head.drop_limb()
+ //qdel(head)
\ No newline at end of file
diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm
index b04f55ef0e..104147ebeb 100644
--- a/code/datums/mutable_appearance.dm
+++ b/code/datums/mutable_appearance.dm
@@ -4,6 +4,9 @@
// Mutable appearances are children of images, just so you know.
+/mutable_appearance
+ var/category // listen i want to store some meta information on mutable appearances don't judge me
+
/mutable_appearance/New()
..()
plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm
index 08ae75d728..964a171e59 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm
@@ -77,6 +77,8 @@
//For soft-restricting markings to species IDs
var/list/recommended_species
+ var/mutable_category // simply do not worry about this value
+
/datum/sprite_accessory/proc/is_not_visible(var/mob/living/carbon/human/H, var/tauric) //return if the accessory shouldn't be shown
return FALSE
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm
index 628a5e53ac..294c3b78f2 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm
@@ -2,6 +2,7 @@
icon = 'icons/mob/mutant_bodyparts.dmi'
mutant_part_string = "ears"
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
+ mutable_category = "HEAD"
/datum/sprite_accessory/ears/is_not_visible(var/mob/living/carbon/human/H, var/tauric)
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm
index f3e179e802..06d4c34f72 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm
@@ -4,6 +4,7 @@
/datum/sprite_accessory/facial_hair
icon = 'icons/mob/hair.dmi'
gender = MALE // barf (unless you're a dorf, dorfs dig chix w/ beards :P)
+ mutable_category = "HEAD"
// please make sure they're sorted alphabetically and categorized
/datum/sprite_accessory/facial_hair/shaved //this is exempt from the alphabetical sort
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm
index e002fa369d..9e868d69c6 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm
@@ -3,6 +3,7 @@
//////////////////////
/datum/sprite_accessory/hair
icon = 'icons/mob/hair.dmi' // default icon for all hairs
+ mutable_category = "HEAD"
// please make sure they're sorted alphabetically and, where needed, categorized
// try to capitalize the names please~
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/horns.dm b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm
index 0d097b24f0..14e340fc2e 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/horns.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm
@@ -2,6 +2,7 @@
icon = 'icons/mob/mutant_bodyparts.dmi'
color_src = HORNCOLOR
relevant_layers = list(HORNS_LAYER)
+ mutable_category = "HEAD"
/datum/sprite_accessory/horns/is_not_visible(var/mob/living/carbon/human/H, var/tauric)
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
index 8bda196faa..f73a4a35a1 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
@@ -6,6 +6,7 @@
icon = 'modular_citadel/icons/mob/ipc_screens.dmi'
color_src = null
relevant_layers = list(BODY_ADJ_LAYER)
+ mutable_category = "HEAD"
/datum/sprite_accessory/screen/blank
name = "Blank"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm
index 75b62e8c0f..aa9ec41dcc 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm
@@ -2,6 +2,7 @@
icon = 'icons/mob/mutant_bodyparts.dmi'
mutant_part_string = "snout"
relevant_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
+ mutable_category = "HEAD"
/datum/sprite_accessory/snouts/is_not_visible(var/mob/living/carbon/human/H, var/tauric)
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm b/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
index 08897ade34..870f4f5ba4 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
@@ -5,6 +5,7 @@
color_src = MUTCOLORS
name = "Synthetic Lizard - Snout"
icon_state = "synthliz_basic"
+ mutable_category = "HEAD"
/datum/sprite_accessory/snouts/mam_snouts/synthliz/synthliz_under
icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi'
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index ddbb23741b..c8cc58c916 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -697,6 +697,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
fhair_file = 'icons/mob/facialhair_extensions.dmi'
var/mutable_appearance/facial_overlay = mutable_appearance(fhair_file, fhair_state, -HAIR_LAYER)
+ facial_overlay.category = "HEAD"
if(!forced_colour)
if(hair_color)
@@ -734,8 +735,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!hair_hidden || dynamic_hair_suffix)
var/mutable_appearance/hair_overlay = mutable_appearance(layer = -HAIR_LAYER)
+ hair_overlay.category = "HEAD"
var/mutable_appearance/gradient_overlay = mutable_appearance(layer = -HAIR_LAYER)
- if(!hair_hidden && !H.getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain
+ gradient_overlay.category = "HEAD"
+ if(!hair_hidden && !H.getorgan(/obj/item/organ/brain) && !H.GetComponent(/datum/component/dullahan)) //Applies the debrained overlay if there is no brain (ignore if they are dullahan)
if(!(NOBLOOD in species_traits))
hair_overlay.icon = 'icons/mob/human_parts.dmi'
hair_overlay.icon_state = "debrained"
@@ -811,6 +814,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
// lipstick
if(H.lip_style && (LIPS in species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/lips.dmi', "lips_[H.lip_style]", -BODY_LAYER)
+ lip_overlay.category = "HEAD"
lip_overlay.color = H.lip_color
if(OFFSET_LIPS in H.dna.species.offset_features)
@@ -822,8 +826,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
// eyes
if(!(NOEYES in species_traits))
var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES)
- if(!has_eyes)
+ if(!has_eyes && !H.GetComponent(/datum/component/dullahan))
standing += mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER)
+ message_admins("EYES MISSING APPLIED 2")
else
var/left_state = DEFAULT_LEFT_EYE_STATE
var/right_state = DEFAULT_RIGHT_EYE_STATE
@@ -832,6 +837,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
right_state = eye_type + "_right_eye"
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER)
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER)
+ left_eye.category = "HEAD"
+ right_eye.category = "HEAD"
if((EYECOLOR in species_traits) && has_eyes)
left_eye.color = "#" + H.left_eye_color
right_eye.color = "#" + H.right_eye_color
@@ -1009,6 +1016,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
for(var/bodypart in relevant_layers[layer])
var/datum/sprite_accessory/S = bodypart
var/mutable_appearance/accessory_overlay = mutable_appearance(S.icon, layer = -layernum)
+ accessory_overlay.category = S.mutable_category
bodypart = S.mutant_part_string || dna_feature_as_text_string[S]
if(S.gender_specific)
@@ -1113,6 +1121,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(S.extra) //apply the extra overlay, if there is one
var/mutable_appearance/extra_accessory_overlay = mutable_appearance(S.icon, layer = -layernum)
+ extra_accessory_overlay.category = S.mutable_category
if(S.gender_specific)
extra_accessory_overlay.icon_state = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]"
else
@@ -1159,6 +1168,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(S.extra2) //apply the extra overlay, if there is one
var/mutable_appearance/extra2_accessory_overlay = mutable_appearance(S.icon, layer = -layernum)
+ extra2_accessory_overlay.category = S.mutable_category
if(S.gender_specific)
extra2_accessory_overlay.icon_state = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]"
else
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index a0620c8990..f225afdd79 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -791,8 +791,9 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
// eyes
if(!(NOEYES in dna.species.species_traits))
var/has_eyes = getorganslot(ORGAN_SLOT_EYES)
- if(!has_eyes)
+ if(!has_eyes && !GetComponent(/datum/component/dullahan))
add_overlay(mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER))
+ message_admins("EYES MISSING APPLIED")
else
var/left_state = DEFAULT_LEFT_EYE_STATE
var/right_state = DEFAULT_RIGHT_EYE_STATE
@@ -803,6 +804,8 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
right_state = eye_type + "_right_eye"
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER)
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER)
+ left_eye.category = "HEAD"
+ right_eye.category = "HEAD"
if((EYECOLOR in dna.species.species_traits) && has_eyes)
left_eye.color = "#" + left_eye_color
right_eye.color = "#" + right_eye_color
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index 8c283f5ebc..7278dc6888 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -134,7 +134,7 @@
I.pixel_y = px_y
add_overlay(standing)
-/obj/item/bodypart/head/get_limb_icon(dropped)
+/obj/item/bodypart/head/get_limb_icon(dropped, ignore_brain = FALSE, ignore_eyes = FALSE)
if(custom_head)
return
cut_overlays()
@@ -152,7 +152,7 @@
. += facial_overlay
//Applies the debrained overlay if there is no brain
- if(!brain)
+ if(!brain && !ignore_brain)
var/image/debrain_overlay = image(layer = -HAIR_LAYER, dir = SOUTH)
if(animal_origin == ALIEN_BODYPART)
debrain_overlay.icon = 'icons/mob/animal_parts.dmi'
@@ -175,12 +175,13 @@
// lipstick
if(lip_style)
- var/image/lips_overlay = image('icons/mob/lips.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH)
+ var/mutable_appearance/lips_overlay = mutable_appearance('icons/mob/lips.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH)
+ lips_overlay.category = "HEAD"
lips_overlay.color = lip_color
. += lips_overlay
// eyes
- if(eyes)
+ if(eyes || ignore_eyes)
var/left_state = DEFAULT_LEFT_EYE_STATE
var/right_state = DEFAULT_RIGHT_EYE_STATE
if(owner && owner.dna.species)
@@ -189,17 +190,20 @@
left_state = eye_type + "_left_eye"
right_state = eye_type + "_right_eye"
if(left_state != DEFAULT_NO_EYE_STATE)
- var/image/left_eye = image('icons/mob/hair.dmi', left_state, -BODY_LAYER, SOUTH)
+ var/mutable_appearance/left_eye = mutable_appearance('icons/mob/hair.dmi', left_state, -BODY_LAYER, SOUTH)
+ left_eye.category = "HEAD"
if(eyes.left_eye_color)
left_eye.color = "#" + eyes.left_eye_color
. += left_eye
if(right_state != DEFAULT_NO_EYE_STATE)
- var/image/right_eye = image('icons/mob/hair.dmi', right_state, -BODY_LAYER, SOUTH)
+ var/mutable_appearance/right_eye = mutable_appearance('icons/mob/hair.dmi', right_state, -BODY_LAYER, SOUTH)
+ right_eye.category = "HEAD"
if(eyes.right_eye_color)
right_eye.color = "#" + eyes.right_eye_color
. += right_eye
else
var/eyes_overlay = image('icons/mob/hair.dmi', "eyes_missing", -BODY_LAYER, SOUTH)
+ message_admins("EYES MISSING ALSO IGNORE EYES IS [ignore_eyes]")
. += eyes_overlay
/obj/item/bodypart/head/monkey
diff --git a/tgstation.dme b/tgstation.dme
index 4fb3920c45..9fd6194e67 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -521,6 +521,7 @@
#include "code\datums\components\combat_mode.dm"
#include "code\datums\components\construction.dm"
#include "code\datums\components\dejavu.dm"
+#include "code\datums\components\dullahan.dm"
#include "code\datums\components\earprotection.dm"
#include "code\datums\components\edible.dm"
#include "code\datums\components\edit_complainer.dm"
From 818e564c9262d9c6331f997c90d671ba43ccd39a Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 5 Aug 2022 15:44:40 +0100
Subject: [PATCH 02/24] stable
---
code/__DEFINES/traits.dm | 2 +
code/datums/accents.dm | 9 +-
code/datums/components/dullahan.dm | 92 +++++++++++++++++--
code/game/objects/structures/mirror.dm | 2 +-
.../mob/living/carbon/human/species.dm | 18 ++--
.../carbon/human/species_types/dullahan.dm | 29 ------
.../mob/living/carbon/human/update_icons.dm | 39 ++++----
.../surgery/bodyparts/dismemberment.dm | 4 +-
code/modules/surgery/bodyparts/head.dm | 5 +-
9 files changed, 125 insertions(+), 75 deletions(-)
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 94ace816ac..d562755083 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -235,6 +235,8 @@
#define TRAIT_BEING_CARRIED "being_carried"
#define TRAIT_GLASS_BONES "glass_bones"
#define TRAIT_PAPER_SKIN "paper_skin"
+//used because it's more reliable than checking for the component
+#define TRAIT_DULLAHAN "dullahan"
// mobility flag traits
// IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it)
diff --git a/code/datums/accents.dm b/code/datums/accents.dm
index d9e073b729..cfd6e873fa 100644
--- a/code/datums/accents.dm
+++ b/code/datums/accents.dm
@@ -94,10 +94,9 @@
/datum/accent/dullahan/modify_speech(list/speech_args, datum/source, mob/living/carbon/owner)
if(owner)
- if(isdullahan(owner))
- var/datum/species/dullahan/D = owner.dna.species
- if(isobj(D.myhead.loc))
- var/obj/O = D.myhead.loc
- O.say(speech_args[SPEECH_MESSAGE])
+ var/datum/component/dullahan/dullahan = owner.GetComponent(/datum/component/dullahan)
+ if(dullahan)
+ if(dullahan.dullahan_head)
+ dullahan.dullahan_head.say(speech_args[SPEECH_MESSAGE])
speech_args[SPEECH_MESSAGE] = ""
return speech_args
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index ee6d5beef0..a3e1335e6b 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -1,30 +1,69 @@
/datum/component/dullahan
var/obj/item/dullahan_head/dullahan_head
-
/datum/component/dullahan/Initialize()
+ . = ..()
+
var/mob/living/carbon/human/H = parent
if(!H)
- return
+ return .
+
+ ADD_TRAIT(H, TRAIT_DULLAHAN, "dullahan_component")
dullahan_head = new(get_turf(H))
dullahan_head.name = "[H.name]'s head"
dullahan_head.desc = "the decapitated head of [H.name]"
dullahan_head.owner = H
+ RegisterSignal(H, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head)
// make sure the brain can't decay or fall out
var/obj/item/organ/brain/B = H.getorganslot(ORGAN_SLOT_BRAIN)
B.zone = "abstract" // it exists in the ethereal plain
B.organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT | ORGAN_VITAL
+ dullahan_head.B = B
+
+ // the eyes get similar treatment
+ var/obj/item/organ/eyes/dullahan/new_eyes = new()
+ var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
+ new_eyes.left_eye_color = E.left_eye_color
+ new_eyes.right_eye_color = E.right_eye_color
+ E.Remove()
+ qdel(E)
+ new_eyes.Insert(H)
+
+ // make sure you handle the tongue correctly, too!
+ var/obj/item/organ/tongue/T = H.getorganslot(ORGAN_SLOT_TONGUE)
+ T.Remove()
+ qdel(T)
+
+ var/obj/item/organ/tongue/dullahan/new_tongue = new()
+ new_tongue.Insert(H)
// moving the brain's zone means we don't need the head to survive
var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD)
head.drop_limb()
qdel(head)
+ H.flags_1 &= ~(HEAR_1)
+
dullahan_head.update_appearance()
+/datum/component/dullahan/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs)
+ excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs.
+
+/obj/item/organ/tongue/dullahan
+ zone = "abstract"
+ initial_accents = list(/datum/accent/dullahan)
+ organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT
+
+/obj/item/organ/eyes/dullahan
+ name = "head vision"
+ desc = "An abstraction."
+ actions_types = list(/datum/action/item_action/organ_action/dullahan)
+ zone = "abstract"
+ tint = INFINITY // used to switch the vision perspective to the head on species_gain().
+
/obj/item/dullahan_head
name = "coders lament"
desc = "you shouldn't be reading this"
@@ -32,6 +71,12 @@
var/mob/living/carbon/human/owner
// this is for keeping track of the overlays because you can't read the actual overlays list as it's a special byond var
var/list/overlays_standing
+ var/obj/item/organ/brain/B
+
+/obj/item/dullahan_head/Destroy()
+ B.Remove()
+ B.forceMove(get_turf(src))
+ . = ..()
// allow the 'fake' head to relay speech back to the mob
/obj/item/dullahan_head/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
@@ -43,7 +88,7 @@
if (owner.client?.prefs.chat_on_map && (owner.client.prefs.see_chat_non_mob || ismob(speaker)))
owner.create_chat_message(speaker, message_language, raw_message, spans, message_mode)
- owner.show_message(rendered, MSG_AUDIBLE)
+ owner.show_message(rendered, "")
// update head sprite
/obj/item/dullahan_head/proc/remove_head_overlays()
@@ -59,13 +104,12 @@
// to do this without duplicating large amounts of code
// it's best to regenerate the head, then remove it once we have the overlays we want
owner.regenerate_limb(BODY_ZONE_HEAD, TRUE) // don't heal them
- owner.regenerate_icons() // yes i know it's expensive but do you want me to rewrite our entire overlay system
+ owner.regenerate_icons(TRUE) // yes i know it's expensive but do you want me to rewrite our entire overlay system, also block recursive calls here by passing in TRUE (it wont go back to call update_appearance this way)
var/obj/item/bodypart/head/head = owner.get_bodypart(BODY_ZONE_HEAD)
add_overlay(head.get_limb_icon(FALSE, TRUE, TRUE))
for(var/overlay in owner.overlays_standing)
if(istype(overlay, /mutable_appearance))
var/mutable_appearance/mutable = overlay
- message_admins("category is [mutable.category] and icon is [mutable.icon_state]")
if(mutable.category == "HEAD")
add_head_overlay(mutable)
else
@@ -74,8 +118,40 @@
for(var/overlay2 in list_appearances)
if(istype(overlay2, /mutable_appearance))
var/mutable_appearance/mutable = overlay2
- message_admins("category is [mutable.category] and icon is [mutable.icon_state]")
if(mutable.category == "HEAD")
add_head_overlay(mutable)
- //head.drop_limb()
- //qdel(head)
\ No newline at end of file
+ head.drop_limb()
+ qdel(head)
+
+/obj/item/dullahan_head/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs)
+ excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs.
+
+/datum/action/item_action/organ_action/dullahan
+ name = "Toggle Perspective"
+ desc = "Switch between seeing normally from your head, or blindly from your body."
+
+/datum/action/item_action/organ_action/dullahan/Trigger()
+ . = ..()
+ var/mob/living/carbon/human/H = owner
+ var/obj/item/organ/eyes/E = owner.getorganslot(ORGAN_SLOT_EYES)
+ if(E)
+ if(E.tint)
+ E.tint = 0
+ else
+ E.tint = INFINITY
+
+ var/datum/component/dullahan/D = H.GetComponent(/datum/component/dullahan)
+ if(D)
+ D.update_vision_perspective()
+
+/datum/component/dullahan/proc/update_vision_perspective()
+ var/mob/living/carbon/human/H = parent
+ if(!H)
+ return .
+ var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
+ if(eyes)
+ H.update_tint()
+ if(eyes.tint)
+ H.reset_perspective(H)
+ else
+ H.reset_perspective(dullahan_head)
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index a70d9d4678..9ff41c4404 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -41,7 +41,7 @@
if(new_style)
H.hair_style = new_style
- H.update_hair()
+ H.update_mutant_bodyparts()
/obj/structure/mirror/examine_status(mob/user)
if(broken)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index c8cc58c916..b73f1da93a 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -345,7 +345,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/obj/item/organ/stomach/stomach = C.getorganslot(ORGAN_SLOT_STOMACH)
var/obj/item/organ/tail/tail = C.getorganslot(ORGAN_SLOT_TAIL)
- var/should_have_brain = TRUE
+ var/should_have_brain = !(HAS_TRAIT(C, TRAIT_DULLAHAN))
var/should_have_heart = !(NOBLOOD in species_traits)
var/should_have_lungs = ((TRAIT_AUXILIARY_LUNGS in inherent_traits) || !(TRAIT_NOBREATH in inherent_traits))
var/should_have_appendix = !(TRAIT_NOHUNGER in inherent_traits)
@@ -803,7 +803,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.apply_overlay(HAIR_LAYER)
-/datum/species/proc/handle_body(mob/living/carbon/human/H)
+/datum/species/proc/handle_body(mob/living/carbon/human/H, block_recursive_calls = FALSE)
H.remove_overlay(BODY_LAYER)
var/list/standing = list()
@@ -825,10 +825,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
// eyes
if(!(NOEYES in species_traits))
- var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES)
- if(!has_eyes && !H.GetComponent(/datum/component/dullahan))
+ var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES) || HAS_TRAIT(H, TRAIT_DULLAHAN) // if they are a dullahan just assume eyes exist
+ if(!has_eyes)
standing += mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER)
- message_admins("EYES MISSING APPLIED 2")
else
var/left_state = DEFAULT_LEFT_EYE_STATE
var/right_state = DEFAULT_RIGHT_EYE_STATE
@@ -899,9 +898,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.overlays_standing[BODY_LAYER] = standing
H.apply_overlay(BODY_LAYER)
- handle_mutant_bodyparts(H)
+ handle_mutant_bodyparts(H, null, block_recursive_calls)
-/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
+/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour, block_recursive_calls = FALSE)
var/list/bodyparts_to_add = mutant_bodyparts.Copy()
H.remove_overlay(BODY_BEHIND_LAYER)
@@ -1216,6 +1215,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.apply_overlay(BODY_FRONT_LAYER)
H.apply_overlay(HORNS_LAYER)
+ if(!block_recursive_calls)
+ var/datum/component/dullahan/D = H.GetComponent(/datum/component/dullahan)
+ if(D && D.dullahan_head)
+ D.dullahan_head.update_appearance()
+
/*
* Equip the outfit required for life. Replaces items currently worn.
*/
diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
index facc3dfd8d..ed06d2be5a 100644
--- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
@@ -82,38 +82,9 @@
decoy_override = TRUE
organ_flags = ORGAN_NO_SPOIL//Do not decay
-/obj/item/organ/tongue/dullahan
- zone = "abstract"
- accents = list(/datum/accent/dullahan)
-
/obj/item/organ/ears/dullahan
zone = "abstract"
-/obj/item/organ/eyes/dullahan
- name = "head vision"
- desc = "An abstraction."
- actions_types = list(/datum/action/item_action/organ_action/dullahan)
- zone = "abstract"
- tint = INFINITY // used to switch the vision perspective to the head on species_gain().
-
-/datum/action/item_action/organ_action/dullahan
- name = "Toggle Perspective"
- desc = "Switch between seeing normally from your head, or blindly from your body."
-
-/datum/action/item_action/organ_action/dullahan/Trigger()
- . = ..()
- var/obj/item/organ/eyes/dullahan/DE = target
- if(DE.tint)
- DE.tint = 0
- else
- DE.tint = INFINITY
-
- if(ishuman(owner))
- var/mob/living/carbon/human/H = owner
- if(isdullahan(H))
- var/datum/species/dullahan/D = H.dna.species
- D.update_vision_perspective(H)
-
/obj/item/dullahan_relay
name = "dullahan relay"
var/mob/living/owner
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index f225afdd79..db0b4ddfac 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -58,14 +58,14 @@ There are several things that need to be remembered:
dna.species.handle_hair(src)
//used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body.
-/mob/living/carbon/human/proc/update_mutant_bodyparts()
+/mob/living/carbon/human/proc/update_mutant_bodyparts(block_recursive_calls = FALSE)
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
- dna.species.handle_mutant_bodyparts(src)
+ dna.species.handle_mutant_bodyparts(src, null, block_recursive_calls)
-/mob/living/carbon/human/update_body(update_genitals = FALSE)
+/mob/living/carbon/human/update_body(update_genitals = FALSE, block_recursive_calls = FALSE)
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
remove_overlay(BODY_LAYER)
- dna.species.handle_body(src)
+ dna.species.handle_body(src, block_recursive_calls)
..()
if(update_genitals)
update_genitals()
@@ -75,24 +75,24 @@ There are several things that need to be remembered:
/* --------------------------------------- */
//For legacy support.
-/mob/living/carbon/human/regenerate_icons()
+/mob/living/carbon/human/regenerate_icons(block_recursive_calls = FALSE)
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
if(!..())
icon_render_key = null //invalidate bodyparts cache
- update_body(TRUE)
+ update_body(TRUE, block_recursive_calls)
update_hair()
- update_inv_w_uniform()
+ update_inv_w_uniform(block_recursive_calls)
update_inv_wear_id()
update_inv_gloves()
update_inv_glasses()
update_inv_ears()
update_inv_shoes()
update_inv_s_store()
- update_inv_wear_mask()
- update_inv_head()
+ update_inv_wear_mask(block_recursive_calls)
+ update_inv_head(block_recursive_calls)
update_inv_belt()
update_inv_back()
- update_inv_wear_suit()
+ update_inv_wear_suit(block_recursive_calls)
update_inv_pockets()
update_inv_neck()
update_transform()
@@ -123,7 +123,7 @@ There are several things that need to be remembered:
apply_overlay(ANTAG_LAYER)
-/mob/living/carbon/human/update_inv_w_uniform()
+/mob/living/carbon/human/update_inv_w_uniform(block_recursive_calls = FALSE)
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
remove_overlay(UNIFORM_LAYER)
@@ -173,7 +173,7 @@ There are several things that need to be remembered:
overlays_standing[UNIFORM_LAYER] = uniform_overlay
apply_overlay(UNIFORM_LAYER)
- update_mutant_bodyparts()
+ update_mutant_bodyparts(block_recursive_calls)
/mob/living/carbon/human/update_inv_wear_id()
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
@@ -349,7 +349,7 @@ There are several things that need to be remembered:
overlays_standing[SUIT_STORE_LAYER] = s_store_overlay
apply_overlay(SUIT_STORE_LAYER)
-/mob/living/carbon/human/update_inv_head()
+/mob/living/carbon/human/update_inv_head(block_recursive_calls = FALSE)
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
remove_overlay(HEAD_LAYER)
@@ -387,7 +387,7 @@ There are several things that need to be remembered:
head_overlay.pixel_y += dna.species.offset_features[OFFSET_HEAD][2]
overlays_standing[HEAD_LAYER] = head_overlay
apply_overlay(HEAD_LAYER)
- update_mutant_bodyparts()
+ update_mutant_bodyparts(block_recursive_calls)
/mob/living/carbon/human/update_inv_belt()
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
@@ -411,7 +411,7 @@ There are several things that need to be remembered:
overlays_standing[BELT_LAYER] = belt_overlay
apply_overlay(BELT_LAYER)
-/mob/living/carbon/human/update_inv_wear_suit()
+/mob/living/carbon/human/update_inv_wear_suit(block_recursive_calls = FALSE)
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
remove_overlay(SUIT_LAYER)
@@ -471,7 +471,7 @@ There are several things that need to be remembered:
suit_overlay = center_image(suit_overlay, dimension_x, dimension_y)
overlays_standing[SUIT_LAYER] = suit_overlay
update_hair()
- update_mutant_bodyparts()
+ update_mutant_bodyparts(block_recursive_calls)
apply_overlay(SUIT_LAYER)
@@ -498,7 +498,7 @@ There are several things that need to be remembered:
update_observer_view(r_store)
-/mob/living/carbon/human/update_inv_wear_mask()
+/mob/living/carbon/human/update_inv_wear_mask(block_recursive_calls = FALSE)
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
remove_overlay(FACEMASK_LAYER)
@@ -537,7 +537,7 @@ There are several things that need to be remembered:
mask_overlay.pixel_y += dna.species.offset_features[OFFSET_FACEMASK][2]
overlays_standing[FACEMASK_LAYER] = mask_overlay
apply_overlay(FACEMASK_LAYER)
- update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout
+ update_mutant_bodyparts(block_recursive_calls) //e.g. upgate needed because mask now hides lizard snout
/mob/living/carbon/human/update_inv_back()
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
@@ -791,9 +791,8 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
// eyes
if(!(NOEYES in dna.species.species_traits))
var/has_eyes = getorganslot(ORGAN_SLOT_EYES)
- if(!has_eyes && !GetComponent(/datum/component/dullahan))
+ if(!has_eyes && !HAS_TRAIT(src, TRAIT_DULLAHAN))
add_overlay(mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER))
- message_admins("EYES MISSING APPLIED")
else
var/left_state = DEFAULT_LEFT_EYE_STATE
var/right_state = DEFAULT_RIGHT_EYE_STATE
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 6b5b4a14aa..96b9290239 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -142,7 +142,7 @@
update_icon_dropped()
C.update_health_hud() //update the healthdoll
- C.update_body()
+ C.update_body(FALSE, TRUE) // block recursive calls because we dont want to crash, i.e. don't tell a dullahan to update when dropping its limb
C.update_hair()
C.update_mobility()
@@ -370,7 +370,7 @@
update_disabled()
C.updatehealth()
- C.update_body()
+ C.update_body(FALSE, TRUE) // again block recursive calls because dullahans will try update their icons by regenerating their head
C.update_hair()
C.update_damage_overlays()
C.update_mobility()
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index 7278dc6888..ea43740093 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -134,7 +134,7 @@
I.pixel_y = px_y
add_overlay(standing)
-/obj/item/bodypart/head/get_limb_icon(dropped, ignore_brain = FALSE, ignore_eyes = FALSE)
+/obj/item/bodypart/head/get_limb_icon(dropped, ignore_brain = FALSE)
if(custom_head)
return
cut_overlays()
@@ -181,7 +181,7 @@
. += lips_overlay
// eyes
- if(eyes || ignore_eyes)
+ if(eyes || ignore_brain)
var/left_state = DEFAULT_LEFT_EYE_STATE
var/right_state = DEFAULT_RIGHT_EYE_STATE
if(owner && owner.dna.species)
@@ -203,7 +203,6 @@
. += right_eye
else
var/eyes_overlay = image('icons/mob/hair.dmi', "eyes_missing", -BODY_LAYER, SOUTH)
- message_admins("EYES MISSING ALSO IGNORE EYES IS [ignore_eyes]")
. += eyes_overlay
/obj/item/bodypart/head/monkey
From b05f6e221d9893d6383bc2caeb64c322cf6c406c Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 5 Aug 2022 18:06:49 +0100
Subject: [PATCH 03/24] MIGRATIONS DELETIONS AND QUIRKS OH MY
---
code/__DEFINES/is_helpers.dm | 1 -
code/datums/components/dullahan.dm | 6 +
code/datums/traits/neutral.dm | 9 ++
code/modules/client/preferences_savefile.dm | 14 +-
.../carbon/human/species_types/dullahan.dm | 136 ------------------
5 files changed, 28 insertions(+), 138 deletions(-)
delete mode 100644 code/modules/mob/living/carbon/human/species_types/dullahan.dm
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index cfd2cebbd0..640079e9b8 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -74,7 +74,6 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
#define iscatperson(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/felinid))
#define isethereal(A) (is_species(A, /datum/species/ethereal))
#define isvampire(A) (is_species(A,/datum/species/vampire))
-#define isdullahan(A) (is_species(A, /datum/species/dullahan))
#define ismush(A) (is_species(A, /datum/species/mush))
#define isshadow(A) (is_species(A, /datum/species/shadow))
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index a3e1335e6b..5e0658be39 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -47,8 +47,14 @@
H.flags_1 &= ~(HEAR_1)
+ RegisterSignal(dullahan_head, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner)
+
dullahan_head.update_appearance()
+/datum/component/dullahan/proc/include_owner(datum/source, list/processing_list, list/hearers)
+ if(!QDELETED(parent))
+ hearers += parent
+
/datum/component/dullahan/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs)
excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs.
diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm
index aebe6ec7fa..8f7043c715 100644
--- a/code/datums/traits/neutral.dm
+++ b/code/datums/traits/neutral.dm
@@ -186,3 +186,12 @@
value = 0
medical_record_text = "Patient should not come into contact with sodium."
mob_trait = TRAIT_SALT_SENSITIVE
+
+/datum/quirk/dullahan
+ name = "Dullahan"
+ desc = "Your head is detached from your body."
+ value = 0
+ medical_record_text = "Patient seems to have some kind of spatial link with their decapitated head."
+
+/datum/quirk/dullahan/post_add()
+ quirk_holder.AddComponent(/datum/component/dullahan)
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 249dbba45f..b4a8952675 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
-#define SAVEFILE_VERSION_MAX 55
+#define SAVEFILE_VERSION_MAX 56
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -358,6 +358,18 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(length(old_flavor_text) && !length(features["feature_flavor_text"]))
features["feature_flavor_text"] = old_flavor_text
+ // hey what happened to 55
+
+ // dullahans as a species cease to exist
+ if(current_version < 56)
+ var/species_id = S["species"]
+ if(species_id = SPECIES_DULLAHAN)
+ S["species"] = SPECIES_HUMAN
+ if(islist(S["all_quirks"])
+ S["all_quirks"] += "Dullahan"
+ else
+ S["all_quirks"] = list("Dullahan")
+
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return
diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
deleted file mode 100644
index ed06d2be5a..0000000000
--- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm
+++ /dev/null
@@ -1,136 +0,0 @@
-/datum/species/dullahan
- name = "Dullahan"
- id = SPECIES_DULLAHAN
- default_color = "FFFFFF"
- species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE)
- inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
- mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "deco_wings" = "None")
- use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
- mutant_brain = /obj/item/organ/brain/dullahan
- mutanteyes = /obj/item/organ/eyes/dullahan
- mutanttongue = /obj/item/organ/tongue/dullahan
- mutantears = /obj/item/organ/ears/dullahan
- blacklisted = TRUE
- limbs_id = SPECIES_HUMAN
- skinned_type = /obj/item/stack/sheet/animalhide/human
- has_field_of_vision = FALSE //Too much of a trouble, their vision is already bound to their severed head.
- species_category = SPECIES_CATEGORY_UNDEAD
- var/pumpkin = FALSE
- wings_icons = SPECIES_WINGS_SKELETAL //seems suitable for an undead.
-
- var/obj/item/dullahan_relay/myhead
-
-/datum/species/dullahan/pumpkin
- name = "Pumpkin Head Dullahan"
- id = "pumpkindullahan"
- pumpkin = TRUE
-
-/datum/species/dullahan/check_roundstart_eligible()
- if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
- return TRUE
- return ..()
-
-/datum/species/dullahan/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
- . = ..()
- H.flags_1 &= ~(HEAR_1)
- var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD)
- if(head)
- if(pumpkin)//Pumpkinhead!
- head.animal_origin = 100
- head.icon = 'icons/obj/clothing/hats.dmi'
- head.icon_state = "hardhat1_pumpkin_j"
- head.custom_head = TRUE
- head.drop_limb()
- if(!QDELETED(head)) //drop_limb() deletes the limb if it's no drop location and dummy humans used for rendering icons are located in nullspace. Do the math.
- head.throwforce = 25
- myhead = new /obj/item/dullahan_relay (head, H)
- H.put_in_hands(head)
- var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
- for(var/datum/action/item_action/organ_action/OA in E.actions)
- OA.Trigger()
-
-/datum/species/dullahan/on_species_loss(mob/living/carbon/human/H)
- H.flags_1 |= HEAR_1
- H.reset_perspective(H)
- if(myhead)
- var/obj/item/dullahan_relay/DR = myhead
- myhead = null
- DR.owner = null
- qdel(DR)
- H.regenerate_limb(BODY_ZONE_HEAD,FALSE)
- ..()
-
-/datum/species/dullahan/spec_life(mob/living/carbon/human/H)
- if(QDELETED(myhead))
- myhead = null
- H.gib()
- var/obj/item/bodypart/head/head2 = H.get_bodypart(BODY_ZONE_HEAD)
- if(head2)
- myhead = null
- H.gib()
-
-/datum/species/dullahan/proc/update_vision_perspective(mob/living/carbon/human/H)
- var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
- if(eyes)
- H.update_tint()
- if(eyes.tint)
- H.reset_perspective(H)
- else
- H.reset_perspective(myhead)
-
-/obj/item/organ/brain/dullahan
- decoy_override = TRUE
- organ_flags = ORGAN_NO_SPOIL//Do not decay
-
-/obj/item/organ/ears/dullahan
- zone = "abstract"
-
-/obj/item/dullahan_relay
- name = "dullahan relay"
- var/mob/living/owner
- flags_1 = HEAR_1
-
-/obj/item/dullahan_relay/Initialize(mapload, mob/living/carbon/human/new_owner)
- . = ..()
- if(!new_owner)
- return INITIALIZE_HINT_QDEL
- owner = new_owner
- START_PROCESSING(SSobj, src)
- RegisterSignal(owner, COMSIG_MOB_CLICKED_SHIFT_ON, .proc/examinate_check)
- RegisterSignal(src, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner)
- RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head)
- RegisterSignal(owner, COMSIG_LIVING_REVIVE, .proc/retrieve_head)
-
-/obj/item/dullahan_relay/proc/examinate_check(mob/source, atom/target)
- if(source.client.eye == src)
- return COMPONENT_ALLOW_EXAMINATE
-
-/obj/item/dullahan_relay/proc/include_owner(datum/source, list/processing_list, list/hearers)
- if(!QDELETED(owner))
- hearers += owner
-
-/obj/item/dullahan_relay/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs)
- excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs.
-
-//Retrieving the owner's head for better ahealing.
-/obj/item/dullahan_relay/proc/retrieve_head(datum/source, full_heal, admin_revive)
- if(admin_revive)
- var/obj/item/bodypart/head/H = loc
- var/turf/T = get_turf(owner)
- if(H && istype(H) && T && !(H in owner.GetAllContents()))
- H.forceMove(T)
-
-/obj/item/dullahan_relay/process()
- if(!istype(loc, /obj/item/bodypart/head) || QDELETED(owner))
- . = PROCESS_KILL
- qdel(src)
-
-/obj/item/dullahan_relay/Destroy()
- if(!QDELETED(owner))
- var/mob/living/carbon/human/H = owner
- if(isdullahan(H))
- var/datum/species/dullahan/D = H.dna.species
- D.myhead = null
- owner.gib()
- owner = null
- ..()
From b4330b2f3d2e5f35cd2c72a3525f07c945c6b32f Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 5 Aug 2022 18:19:22 +0100
Subject: [PATCH 04/24] GOODBYE SPECIES, HELLO COMPONENT
---
code/datums/components/dullahan.dm | 22 +++++++++++++++++++
code/datums/dna.dm | 15 +++++--------
code/datums/wounds/slash.dm | 2 +-
code/game/machinery/recycler.dm | 2 +-
code/modules/client/preferences_savefile.dm | 4 ++--
code/modules/holiday/halloween/jacqueen.dm | 20 +----------------
code/modules/mob/living/carbon/human/human.dm | 3 ---
.../mob/living/carbon/human/species.dm | 4 ++--
code/modules/projectiles/projectile/magic.dm | 2 +-
tgstation.dme | 1 -
10 files changed, 36 insertions(+), 39 deletions(-)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index 5e0658be39..b39726082a 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -161,3 +161,25 @@
H.reset_perspective(H)
else
H.reset_perspective(dullahan_head)
+
+/datum/component/dullahan/Destroy()
+ UnregisterSignal(parent, COMSIG_LIVING_REGENERATE_LIMBS)
+ qdel(dullahan_head)
+ REMOVE_TRAIT(parent, TRAIT_DULLAHAN, "dullahan_component")
+
+ // work out what organs to give them based on their species
+ if(ishuman(parent))
+ var/mob/living/carbon/human/H = parent
+ var/obj/item/organ/eyes/new_eyes = new H.dna.species.mutant_eyes()
+ var/obj/item/organ/brain/new_brain = new H.dna.species.mutant_brain()
+ var/obj/item/organ/eyes/old_eyes = H.getorganslot(ORGAN_SLOT_EYES)
+ var/obj/item/organ/brain/old_brain = H.getorganslot(ORGAN_SLOT_BRAIN)
+
+ old_brain.Remove(TRUE,TRUE)
+ QDEL_NULL(old_brain)
+ new_brain.Insert(C, TRUE, TRUE)
+
+ old_eyes.Remove(TRUE,TRUE)
+ QDEL_NULL(old_eyes)
+ new_eyes.Insert(C, TRUE, TRUE)
+ . = ..()
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 5619a09f05..bb2dab8033 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -717,16 +717,13 @@
death()
petrify(INFINITY)
if(3)
- if(prob(90))
- var/obj/item/bodypart/BP = get_bodypart(pick(BODY_ZONE_CHEST,BODY_ZONE_HEAD))
- if(BP)
- BP.dismember()
- else
- unequip_everything()
- drop_all_held_items()
- gib()
+ var/obj/item/bodypart/BP = get_bodypart(pick(BODY_ZONE_CHEST,BODY_ZONE_HEAD))
+ if(BP)
+ BP.dismember()
else
- set_species(/datum/species/dullahan)
+ unequip_everything()
+ drop_all_held_items()
+ gib()
/datum/dna/proc/update_body_size(old_size)
if(!holder || features["body_size"] == old_size)
diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm
index 6a631ab8f4..68740e78ab 100644
--- a/code/datums/wounds/slash.dm
+++ b/code/datums/wounds/slash.dm
@@ -177,7 +177,7 @@
if(isinsect(victim) || iscatperson(victim) || ismammal(victim) || isdwarf(victim) || ismonkey(victim)) // Yep you can lick monkeys.
user.reagents.add_reagent(/datum/reagent/hairball, 2)
- else if(ishumanbasic(victim) || isflyperson(victim) || islizard(victim) || isdullahan(victim))
+ else if(ishumanbasic(victim) || isflyperson(victim) || islizard(victim) || HAS_TRAIT(victim, TRAIT_DULLAHAN))
user.reagents.add_reagent(/datum/reagent/hairball, 1)
if(blood_flow > minimum_flow)
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index c1dac389bf..c561170af4 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -119,7 +119,7 @@
if(istype(AM, /obj/item))
var/obj/item/bodypart/head/as_head = AM
var/obj/item/mmi/as_mmi = AM
- if(istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /obj/item/dullahan_relay))
+ if(istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /obj/item/dullahan_head))
living_detected = living_detected ? living_detected : AM
nom += AM
else if(isliving(AM))
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index b4a8952675..3a7e52e706 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -363,9 +363,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
// dullahans as a species cease to exist
if(current_version < 56)
var/species_id = S["species"]
- if(species_id = SPECIES_DULLAHAN)
+ if(species_id == SPECIES_DULLAHAN)
S["species"] = SPECIES_HUMAN
- if(islist(S["all_quirks"])
+ if(islist(S["all_quirks"]))
S["all_quirks"] += "Dullahan"
else
S["all_quirks"] = list("Dullahan")
diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm
index 77187532f9..66ae3dce4b 100644
--- a/code/modules/holiday/halloween/jacqueen.dm
+++ b/code/modules/holiday/halloween/jacqueen.dm
@@ -219,23 +219,11 @@
/mob/living/simple_animal/jacq/proc/treat(mob/living/carbon/C, gender)
visible_message("[src] gives off a glowing smile, \"What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.\"")
jacqrunes("What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.", C)
- var/choices_reward = list("Object - 3 candies", "Potion - 2 candies", "Jacqueline Tracker - 2 candies", "Plushie - 1 candy", "Can I get to know you instead?", "Become a pumpkinhead dullahan (perma) - 4 candies")
+ var/choices_reward = list("Object - 3 candies", "Potion - 2 candies", "Jacqueline Tracker - 2 candies", "Plushie - 1 candy", "Can I get to know you instead?")
var/choice_reward = input(usr, "Trick or Treat?", "Trick or Treat?") in choices_reward
//rewards
switch(choice_reward)
- if("Become a pumpkinhead dullahan (perma) - 4 candies")
- if(!take_candies(C, 4))
- visible_message("[src] raises an eyebrown, \"It's 4 candies for that [gender]! Thems the rules!\"")
- jacqrunes("It's 4 candies for that [gender]! Thems the rules!", C)
- return
- visible_message("[src] waves their arms around, \"Off comes your head, a pumpkin taking it's stead!\"")
- jacqrunes("Off comes your head, a pumpkin taking it's stead!", C)
- C.reagents.add_reagent(/datum/reagent/mutationtoxin/pumpkinhead, 5)
- sleep(20)
- poof()
- return
-
if("Object - 3 candies")
if(!take_candies(C, 3))
visible_message("[src] raises an eyebrown, \"It's 3 candies per trinket [gender]! Thems the rules!\"")
@@ -688,12 +676,6 @@
else
..()
-/datum/reagent/mutationtoxin/pumpkinhead
- name = "Pumpkin head mutation toxin"
- race = /datum/species/dullahan/pumpkin
- mutationtext = "The pain subsides. You feel your head roll off your shoulders... and you smell pumpkin."
- //I couldn't get the replace head sprite with a pumpkin to work so, it is what it is.
-
/mob/living/simple_animal/jacq/proc/check_candies(mob/living/carbon/C)
var/invs = C.get_contents()
var/candy_count = 0
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index c60e4c6cb2..b81863e932 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -954,9 +954,6 @@
/mob/living/carbon/human/species/corporate
race = /datum/species/corporate
-/mob/living/carbon/human/species/dullahan
- race = /datum/species/dullahan
-
/mob/living/carbon/human/species/felinid
race = /datum/species/human/felinid
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index b73f1da93a..77ad6c7d5a 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -345,11 +345,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/obj/item/organ/stomach/stomach = C.getorganslot(ORGAN_SLOT_STOMACH)
var/obj/item/organ/tail/tail = C.getorganslot(ORGAN_SLOT_TAIL)
- var/should_have_brain = !(HAS_TRAIT(C, TRAIT_DULLAHAN))
+ var/should_have_brain = !(HAS_TRAIT(C, TRAIT_DULLAHAN)) // do not mess with a dullahans brain
var/should_have_heart = !(NOBLOOD in species_traits)
var/should_have_lungs = ((TRAIT_AUXILIARY_LUNGS in inherent_traits) || !(TRAIT_NOBREATH in inherent_traits))
var/should_have_appendix = !(TRAIT_NOHUNGER in inherent_traits)
- var/should_have_eyes = TRUE
+ var/should_have_eyes = !(HAS_TRAIT(C, TRAIT_DULLAHAN)) // .. or their eyes
var/should_have_ears = TRUE
var/should_have_tongue = TRUE
var/should_have_liver = !(NOLIVER in species_traits)
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 9761881067..2959666a4c 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -37,7 +37,7 @@
return BULLET_ACT_BLOCK
if(iscarbon(target))
var/mob/living/carbon/C = target
- if(!is_species(C, /datum/species/dullahan)) //No accidental instagibbing dullahans please
+ if(HAS_TRAIT(C, TRAIT_DULLAHAN)) //No accidental instagibbing dullahans please
C.regenerate_limbs()
C.regenerate_organs()
if(target.revive(full_heal = 1))
diff --git a/tgstation.dme b/tgstation.dme
index 9fd6194e67..ca7d9ebda1 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2696,7 +2696,6 @@
#include "code\modules\mob\living\carbon\human\species_types\arachnid.dm"
#include "code\modules\mob\living\carbon\human\species_types\bugmen.dm"
#include "code\modules\mob\living\carbon\human\species_types\corporate.dm"
-#include "code\modules\mob\living\carbon\human\species_types\dullahan.dm"
#include "code\modules\mob\living\carbon\human\species_types\dwarves.dm"
#include "code\modules\mob\living\carbon\human\species_types\ethereal.dm"
#include "code\modules\mob\living\carbon\human\species_types\felinid.dm"
From a397402a2e6b8de9466c7f1c3e0913d24b91895a Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 5 Aug 2022 18:19:43 +0100
Subject: [PATCH 05/24] local man can't spell
---
code/datums/components/dullahan.dm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index b39726082a..2c34c3d1d1 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -177,9 +177,9 @@
old_brain.Remove(TRUE,TRUE)
QDEL_NULL(old_brain)
- new_brain.Insert(C, TRUE, TRUE)
+ new_brain.Insert(H, TRUE, TRUE)
old_eyes.Remove(TRUE,TRUE)
QDEL_NULL(old_eyes)
- new_eyes.Insert(C, TRUE, TRUE)
+ new_eyes.Insert(H, TRUE, TRUE)
. = ..()
From 6410c942445eef8096c08cc75e303764dcac5b62 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 5 Aug 2022 20:58:27 +0100
Subject: [PATCH 06/24] Update dullahan.dm
---
code/datums/components/dullahan.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index 2c34c3d1d1..d362af99e4 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -170,7 +170,7 @@
// work out what organs to give them based on their species
if(ishuman(parent))
var/mob/living/carbon/human/H = parent
- var/obj/item/organ/eyes/new_eyes = new H.dna.species.mutant_eyes()
+ var/obj/item/organ/eyes/new_eyes = new H.dna.species.mutanteyes()
var/obj/item/organ/brain/new_brain = new H.dna.species.mutant_brain()
var/obj/item/organ/eyes/old_eyes = H.getorganslot(ORGAN_SLOT_EYES)
var/obj/item/organ/brain/old_brain = H.getorganslot(ORGAN_SLOT_BRAIN)
From fdd66a2b104883f5e92461d0e3328a4a45a2895e Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 5 Aug 2022 21:48:55 +0100
Subject: [PATCH 07/24] gib people after their head is destroyed
---
code/datums/components/dullahan.dm | 2 ++
1 file changed, 2 insertions(+)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index d362af99e4..c340b1ed0a 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -82,6 +82,8 @@
/obj/item/dullahan_head/Destroy()
B.Remove()
B.forceMove(get_turf(src))
+ var/mob/living/human/H = parent
+ H.gib()
. = ..()
// allow the 'fake' head to relay speech back to the mob
From d49b6d0779c531577be60bf87e72e0bc541b2d32 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 5 Aug 2022 22:22:29 +0100
Subject: [PATCH 08/24] ae
---
code/datums/components/dullahan.dm | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index c340b1ed0a..ce6c1e7eb7 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -82,8 +82,7 @@
/obj/item/dullahan_head/Destroy()
B.Remove()
B.forceMove(get_turf(src))
- var/mob/living/human/H = parent
- H.gib()
+ owner.gib()
. = ..()
// allow the 'fake' head to relay speech back to the mob
From 276143f5132524c6eda5f4e5e5faa6d6eab4933e Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 7 Aug 2022 23:17:49 +0100
Subject: [PATCH 09/24] Update dullahan.dm
---
code/datums/components/dullahan.dm | 38 +++++++++++++-----------------
1 file changed, 17 insertions(+), 21 deletions(-)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index ce6c1e7eb7..9401d3d3d0 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -19,17 +19,19 @@
// make sure the brain can't decay or fall out
var/obj/item/organ/brain/B = H.getorganslot(ORGAN_SLOT_BRAIN)
- B.zone = "abstract" // it exists in the ethereal plain
- B.organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT | ORGAN_VITAL
- dullahan_head.B = B
+ if(B)
+ B.zone = "abstract" // it exists in the ethereal plain
+ B.organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT | ORGAN_VITAL
+ dullahan_head.B = B
// the eyes get similar treatment
var/obj/item/organ/eyes/dullahan/new_eyes = new()
var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
- new_eyes.left_eye_color = E.left_eye_color
- new_eyes.right_eye_color = E.right_eye_color
- E.Remove()
- qdel(E)
+ if(E)
+ new_eyes.left_eye_color = E.left_eye_color
+ new_eyes.right_eye_color = E.right_eye_color
+ E.Remove()
+ qdel(E)
new_eyes.Insert(H)
// make sure you handle the tongue correctly, too!
@@ -40,10 +42,16 @@
var/obj/item/organ/tongue/dullahan/new_tongue = new()
new_tongue.Insert(H)
+ // uh, eyes!
+ var/obj/item/organ/ears/dullahan_ears = H.getorganslot(ORGAN_SLOT_EARS)
+ if(dullahan_ears)
+ dullahan_ears.zone = "abstract"
+
// moving the brain's zone means we don't need the head to survive
var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD)
- head.drop_limb()
- qdel(head)
+ if(head)
+ head.drop_limb()
+ qdel(head)
H.flags_1 &= ~(HEAR_1)
@@ -85,18 +93,6 @@
owner.gib()
. = ..()
-// allow the 'fake' head to relay speech back to the mob
-/obj/item/dullahan_head/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
- if(owner)
- var/namepart = "[speaker.GetVoice()][speaker.get_alt_name()]"
- var/hrefpart = ""
- var/treated_message = lang_treat(speaker, message_language, raw_message, spans, message_mode)
- var/rendered = "[hrefpart][namepart] [treated_message]"
-
- if (owner.client?.prefs.chat_on_map && (owner.client.prefs.see_chat_non_mob || ismob(speaker)))
- owner.create_chat_message(speaker, message_language, raw_message, spans, message_mode)
- owner.show_message(rendered, "")
-
// update head sprite
/obj/item/dullahan_head/proc/remove_head_overlays()
overlays_standing = list()
From 783d22b2d2f964904464fa3f7564fd8840df3639 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 7 Aug 2022 23:38:38 +0100
Subject: [PATCH 10/24] some more additions
---
.../mob/dead/new_player/sprite_accessories/alienpeople.dm | 1 +
code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm | 1 +
code/modules/mob/dead/new_player/sprite_accessories/caps.dm | 1 +
.../modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm | 1 +
4 files changed, 4 insertions(+)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm
index 3972bdc2c3..9a7108af4c 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm
@@ -48,6 +48,7 @@
icon = 'modular_citadel/icons/mob/xeno_parts_greyscale.dmi'
mutant_part_string = "xhead"
relevant_layers = list(BODY_ADJ_LAYER)
+ category = "HEAD"
/datum/sprite_accessory/xeno_head/is_not_visible(var/mob/living/carbon/human/H, var/tauric)
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm b/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm
index 460b41f0d9..f16e751cc6 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm
@@ -49,6 +49,7 @@
relevant_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
mutant_part_string = "mandibles"
color_src = 0
+ category = "HEAD"
/datum/sprite_accessory/arachnid_mandibles/none
name = "None"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/caps.dm b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm
index d974672490..2e8416fbb5 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/caps.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm
@@ -2,6 +2,7 @@
icon = 'icons/mob/mutant_bodyparts.dmi'
color_src = HAIR
relevant_layers = list(BODY_ADJ_LAYER)
+ category = "HEAD"
/datum/sprite_accessory/caps/round
name = "Round"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
index f73a4a35a1..8a50091e73 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
@@ -134,6 +134,7 @@
relevant_layers = list(BODY_ADJ_LAYER)
recommended_species = list("ipc")
mutant_part_string = "ipc_antenna"
+ category = "HEAD"
/datum/sprite_accessory/antenna/none
name = "None"
From 7df374a1f5cc539e336059b322fe672266bcfe0d Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 7 Aug 2022 23:51:02 +0100
Subject: [PATCH 11/24] IPC PLEASE
---
.../mob/dead/new_player/sprite_accessories/ipc_synths.dm | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
index 8a50091e73..ee6d8b3ceb 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
@@ -8,6 +8,10 @@
relevant_layers = list(BODY_ADJ_LAYER)
mutable_category = "HEAD"
+/datum/sprite_accessory/screen/is_not_visible(var/mob/living/carbon/human/H, var/tauric)
+ var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
+ return (HD == null) // it's not visible if head is null
+
/datum/sprite_accessory/screen/blank
name = "Blank"
icon_state = "blank"
From 671e5dd8726d34ae7210fc524f7a01b2084e4751 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 7 Aug 2022 23:53:08 +0100
Subject: [PATCH 12/24] oh shit oh fuck
---
.../mob/dead/new_player/sprite_accessories/alienpeople.dm | 2 +-
code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm | 2 +-
code/modules/mob/dead/new_player/sprite_accessories/caps.dm | 2 +-
.../mob/dead/new_player/sprite_accessories/ipc_synths.dm | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm
index 9a7108af4c..ba334d2934 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm
@@ -48,7 +48,7 @@
icon = 'modular_citadel/icons/mob/xeno_parts_greyscale.dmi'
mutant_part_string = "xhead"
relevant_layers = list(BODY_ADJ_LAYER)
- category = "HEAD"
+ mutable_category = "HEAD"
/datum/sprite_accessory/xeno_head/is_not_visible(var/mob/living/carbon/human/H, var/tauric)
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm b/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm
index f16e751cc6..cd032b6a2a 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm
@@ -49,7 +49,7 @@
relevant_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
mutant_part_string = "mandibles"
color_src = 0
- category = "HEAD"
+ mutable_category = "HEAD"
/datum/sprite_accessory/arachnid_mandibles/none
name = "None"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/caps.dm b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm
index 2e8416fbb5..5b30591d07 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/caps.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm
@@ -2,7 +2,7 @@
icon = 'icons/mob/mutant_bodyparts.dmi'
color_src = HAIR
relevant_layers = list(BODY_ADJ_LAYER)
- category = "HEAD"
+ mutable_category = "HEAD"
/datum/sprite_accessory/caps/round
name = "Round"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
index ee6d8b3ceb..ec5c6ea792 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
@@ -138,7 +138,7 @@
relevant_layers = list(BODY_ADJ_LAYER)
recommended_species = list("ipc")
mutant_part_string = "ipc_antenna"
- category = "HEAD"
+ mutable_category = "HEAD"
/datum/sprite_accessory/antenna/none
name = "None"
From b5e70ba0080f35c104570b0fcb67a4aaf98408a1 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Mon, 8 Aug 2022 00:08:13 +0100
Subject: [PATCH 13/24] we do a little fix
---
code/modules/client/preferences.dm | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 8a9f122f43..409916da30 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -3357,6 +3357,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
wheels.setDir(spawn_chair.dir)
wheels.buckle_mob(character)
+ var/datum/component/dullahan/dullahan = character.GetComponent(/datum/component/dullahan)
+ // if you ready up, quirks are assigned first, very stupid
+ if(dullahan && dullahan.dullahan_head)
+ dullahan.dullahan_head.name = "[character.name]'s head"
+ dullahan.dullahan_head.desc = "the decapitated head of [character.name]"
/datum/preferences/proc/get_default_name(name_id)
switch(name_id)
From 9a8c356f2436a8a2424cf57b894c971f37841f96 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Mon, 8 Aug 2022 00:17:56 +0100
Subject: [PATCH 14/24] slightly better
---
code/datums/components/dullahan.dm | 5 +++--
code/modules/client/preferences.dm | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index 9401d3d3d0..09c65600f1 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -12,8 +12,9 @@
dullahan_head = new(get_turf(H))
- dullahan_head.name = "[H.name]'s head"
- dullahan_head.desc = "the decapitated head of [H.name]"
+ if(length(H.name))
+ dullahan_head.name = "[H.name]'s head"
+ dullahan_head.desc = "the decapitated head of [H.name]"
dullahan_head.owner = H
RegisterSignal(H, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 409916da30..3d08998a82 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -3359,7 +3359,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
wheels.buckle_mob(character)
var/datum/component/dullahan/dullahan = character.GetComponent(/datum/component/dullahan)
// if you ready up, quirks are assigned first, very stupid
- if(dullahan && dullahan.dullahan_head)
+ if(dullahan && dullahan.dullahan_head && length(dullahan_head.name))
dullahan.dullahan_head.name = "[character.name]'s head"
dullahan.dullahan_head.desc = "the decapitated head of [character.name]"
From a2f4ea39af4bb41cd2d622c1d575d66f0f37e8e4 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Mon, 8 Aug 2022 00:29:20 +0100
Subject: [PATCH 15/24] attempted fix at the ready-up issue
---
code/modules/client/preferences.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 3d08998a82..1e3c1defd4 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -3359,7 +3359,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
wheels.buckle_mob(character)
var/datum/component/dullahan/dullahan = character.GetComponent(/datum/component/dullahan)
// if you ready up, quirks are assigned first, very stupid
- if(dullahan && dullahan.dullahan_head && length(dullahan_head.name))
+ if(dullahan && dullahan.dullahan_head && length(dullahan.dullahan_head.name))
dullahan.dullahan_head.name = "[character.name]'s head"
dullahan.dullahan_head.desc = "the decapitated head of [character.name]"
From 529ada40efe7b981354fa799c9005a12fa491641 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Mon, 8 Aug 2022 16:36:15 +0100
Subject: [PATCH 16/24] auto retry
---
code/datums/components/dullahan.dm | 15 ++++++++++++---
code/modules/client/preferences.dm | 5 -----
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index 09c65600f1..b3b2c44a63 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -12,9 +12,8 @@
dullahan_head = new(get_turf(H))
- if(length(H.name))
- dullahan_head.name = "[H.name]'s head"
- dullahan_head.desc = "the decapitated head of [H.name]"
+ update_name()
+
dullahan_head.owner = H
RegisterSignal(H, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head)
@@ -60,6 +59,16 @@
dullahan_head.update_appearance()
+/datum/component/dullahan/proc/update_name(retries = 0)
+ if(retries > 3)
+ return FALSE
+ var/mob/living/carbon/human/H = parent
+ if(length(H.name))
+ dullahan_head.name = "[H.name]'s head"
+ dullahan_head.desc = "the decapitated head of [H.name]"
+ return TRUE
+ addtimer(CALLBACK(src, .proc/update_name, retries + 1), 2 SECONDS)
+
/datum/component/dullahan/proc/include_owner(datum/source, list/processing_list, list/hearers)
if(!QDELETED(parent))
hearers += parent
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 1e3c1defd4..8a9f122f43 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -3357,11 +3357,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
wheels.setDir(spawn_chair.dir)
wheels.buckle_mob(character)
- var/datum/component/dullahan/dullahan = character.GetComponent(/datum/component/dullahan)
- // if you ready up, quirks are assigned first, very stupid
- if(dullahan && dullahan.dullahan_head && length(dullahan.dullahan_head.name))
- dullahan.dullahan_head.name = "[character.name]'s head"
- dullahan.dullahan_head.desc = "the decapitated head of [character.name]"
/datum/preferences/proc/get_default_name(name_id)
switch(name_id)
From a9f77d9344e1443753835119f716d34a315507bd Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Mon, 8 Aug 2022 16:38:02 +0100
Subject: [PATCH 17/24] let it retry for up to a minute
---
code/datums/components/dullahan.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index b3b2c44a63..053fe2ff11 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -60,7 +60,7 @@
dullahan_head.update_appearance()
/datum/component/dullahan/proc/update_name(retries = 0)
- if(retries > 3)
+ if(retries > 30)
return FALSE
var/mob/living/carbon/human/H = parent
if(length(H.name))
From 8ee01d0bc4eeabd8d45c9ce25a83fdb6010a452b Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Tue, 9 Aug 2022 11:08:52 +0100
Subject: [PATCH 18/24] Update dullahan.dm
---
code/datums/components/dullahan.dm | 1 +
1 file changed, 1 insertion(+)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index 053fe2ff11..7d35b2d874 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -96,6 +96,7 @@
// this is for keeping track of the overlays because you can't read the actual overlays list as it's a special byond var
var/list/overlays_standing
var/obj/item/organ/brain/B
+ w_class = WEIGHT_CLASS_BULKY
/obj/item/dullahan_head/Destroy()
B.Remove()
From e71686d8acdf53f1c4d37970c188604935b48099 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Tue, 9 Aug 2022 11:59:10 +0100
Subject: [PATCH 19/24] fixes
---
code/__DEFINES/_flags/item_flags.dm | 2 +-
code/datums/components/dullahan.dm | 7 +++++++
code/modules/surgery/organs/organ_internal.dm | 3 +++
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/code/__DEFINES/_flags/item_flags.dm b/code/__DEFINES/_flags/item_flags.dm
index 529499127d..d28cb80bab 100644
--- a/code/__DEFINES/_flags/item_flags.dm
+++ b/code/__DEFINES/_flags/item_flags.dm
@@ -51,4 +51,4 @@
#define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances
#define ORGAN_NO_DISMEMBERMENT (1<<6) //Immune to disembowelment.
#define ORGAN_EDIBLE (1<<7) //is a snack? :D
-#define ORGAN_SYNTHETIC_EMP (1<<6) //Synthetic organ affected by an EMP. Deteriorates over time.
+#define ORGAN_SYNTHETIC_EMP (1<<8) //Synthetic organ affected by an EMP. Deteriorates over time.
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index 7d35b2d874..944f99c028 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -87,6 +87,7 @@
actions_types = list(/datum/action/item_action/organ_action/dullahan)
zone = "abstract"
tint = INFINITY // used to switch the vision perspective to the head on species_gain().
+ organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT
/obj/item/dullahan_head
name = "coders lament"
@@ -180,8 +181,10 @@
var/mob/living/carbon/human/H = parent
var/obj/item/organ/eyes/new_eyes = new H.dna.species.mutanteyes()
var/obj/item/organ/brain/new_brain = new H.dna.species.mutant_brain()
+ var/obj/item/organ/tongue/new_tongue = new H.dna.species.mutanttongue()
var/obj/item/organ/eyes/old_eyes = H.getorganslot(ORGAN_SLOT_EYES)
var/obj/item/organ/brain/old_brain = H.getorganslot(ORGAN_SLOT_BRAIN)
+ var/obj/item/organ/tongue/old_tongue = H.getorganslot(ORGAN_SLOT_TONGUE)
old_brain.Remove(TRUE,TRUE)
QDEL_NULL(old_brain)
@@ -190,4 +193,8 @@
old_eyes.Remove(TRUE,TRUE)
QDEL_NULL(old_eyes)
new_eyes.Insert(H, TRUE, TRUE)
+
+ old_tongue.Remove(TRUE,TRUE)
+ QDEL_NULL(old_tongue)
+ new_tongue.Insert(H, TRUE, TRUE)
. = ..()
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index d4a2663374..2c9b9b99d4 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -103,6 +103,7 @@
is_cold()
if(organ_flags & ORGAN_FROZEN)
return
+ message_admins("fuck you we're killing [owner]")
applyOrganDamage(maxHealth * decay_factor * (seconds * 0.5))
/obj/item/organ/proc/can_decay()
@@ -155,6 +156,7 @@
if(organ_flags & ORGAN_FAILING || !owner)
return FALSE
if(organ_flags & ORGAN_SYNTHETIC_EMP) //Synthetic organ has been emped, is now failing.
+ message_admins("emp go brrr")
applyOrganDamage(maxHealth * decay_factor)
return FALSE
if(organ_flags & ORGAN_SYNTHETIC)
@@ -165,6 +167,7 @@
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's satiety
healing_amount -= owner.satiety > 0 ? 4 * (maxHealth * healing_factor) * (owner.satiety / MAX_SATIETY) : 0
if(healing_amount)
+ message_admins("we um are healing")
applyOrganDamage(healing_amount) //to FERMI_TWEAK
return TRUE
From 835323bdbcb9aa3c8ce0eeb137857799c125b19a Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Tue, 9 Aug 2022 12:07:09 +0100
Subject: [PATCH 20/24] neurine fixes your traumas, yo!
---
.../reagents/chemistry/reagents/medicine_reagents.dm | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 0a78af67b2..a5fbead7cb 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -1081,6 +1081,13 @@
else
B.gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
+/datum/reagent/medicine/neurine/reaction_obj(obj/O, reac_volume)
+ if(istype(O, /obj/item/dullahan_head))
+ var/obj/item/dullahan_head/head = O
+ if(head.B)
+ head.B.applyOrganDamage(-20)
+ if(head.owner)
+ head.owner.cure_trauma_type(resilience = TRAUMA_RESILIENCE_SURGERY)
/datum/reagent/medicine/neurine/on_mob_life(mob/living/carbon/C)
if(holder.has_reagent(/datum/reagent/consumable/ethanol/neurotoxin))
From 5d925412b1134dc5ef78babfed23a24be072fa70 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Tue, 9 Aug 2022 16:37:39 +0100
Subject: [PATCH 21/24] Update organ_internal.dm
---
code/modules/surgery/organs/organ_internal.dm | 3 ---
1 file changed, 3 deletions(-)
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 2c9b9b99d4..d4a2663374 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -103,7 +103,6 @@
is_cold()
if(organ_flags & ORGAN_FROZEN)
return
- message_admins("fuck you we're killing [owner]")
applyOrganDamage(maxHealth * decay_factor * (seconds * 0.5))
/obj/item/organ/proc/can_decay()
@@ -156,7 +155,6 @@
if(organ_flags & ORGAN_FAILING || !owner)
return FALSE
if(organ_flags & ORGAN_SYNTHETIC_EMP) //Synthetic organ has been emped, is now failing.
- message_admins("emp go brrr")
applyOrganDamage(maxHealth * decay_factor)
return FALSE
if(organ_flags & ORGAN_SYNTHETIC)
@@ -167,7 +165,6 @@
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's satiety
healing_amount -= owner.satiety > 0 ? 4 * (maxHealth * healing_factor) * (owner.satiety / MAX_SATIETY) : 0
if(healing_amount)
- message_admins("we um are healing")
applyOrganDamage(healing_amount) //to FERMI_TWEAK
return TRUE
From b260794e54db91f11ce3380e52711db25ec56268 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Wed, 10 Aug 2022 16:37:21 +0100
Subject: [PATCH 22/24] Update dullahan.dm
---
code/datums/components/dullahan.dm | 58 +++++++++++++++++-------------
1 file changed, 33 insertions(+), 25 deletions(-)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index 944f99c028..6b18f7f6c1 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -100,9 +100,10 @@
w_class = WEIGHT_CLASS_BULKY
/obj/item/dullahan_head/Destroy()
- B.Remove()
- B.forceMove(get_turf(src))
- owner.gib()
+ if(owner)
+ B.Remove()
+ B.forceMove(get_turf(src))
+ owner.gib()
. = ..()
// update head sprite
@@ -115,28 +116,31 @@
add_overlay(overlay)
/obj/item/dullahan_head/update_appearance()
- remove_head_overlays()
- // to do this without duplicating large amounts of code
- // it's best to regenerate the head, then remove it once we have the overlays we want
- owner.regenerate_limb(BODY_ZONE_HEAD, TRUE) // don't heal them
- owner.regenerate_icons(TRUE) // yes i know it's expensive but do you want me to rewrite our entire overlay system, also block recursive calls here by passing in TRUE (it wont go back to call update_appearance this way)
- var/obj/item/bodypart/head/head = owner.get_bodypart(BODY_ZONE_HEAD)
- add_overlay(head.get_limb_icon(FALSE, TRUE, TRUE))
- for(var/overlay in owner.overlays_standing)
- if(istype(overlay, /mutable_appearance))
- var/mutable_appearance/mutable = overlay
- if(mutable.category == "HEAD")
- add_head_overlay(mutable)
- else
- if(islist(overlay))
- var/list/list_appearances = overlay
- for(var/overlay2 in list_appearances)
- if(istype(overlay2, /mutable_appearance))
- var/mutable_appearance/mutable = overlay2
- if(mutable.category == "HEAD")
- add_head_overlay(mutable)
- head.drop_limb()
- qdel(head)
+ if(owner && !HAS_TRAIT(owner, TRAIT_HUMAN_NO_RENDER))
+ remove_head_overlays()
+ // to do this without duplicating large amounts of code
+ // it's best to regenerate the head, then remove it once we have the overlays we want
+ owner.regenerate_limb(BODY_ZONE_HEAD, TRUE) // don't heal them
+ owner.cut_overlays()
+ owner.regenerate_icons(TRUE) // yes i know it's expensive but do you want me to rewrite our entire overlay system, also block recursive calls here by passing in TRUE (it wont go back to call update_appearance this way)
+ var/obj/item/bodypart/head/head = owner.get_bodypart(BODY_ZONE_HEAD)
+ if(head)
+ add_overlay(head.get_limb_icon(FALSE, TRUE, TRUE))
+ for(var/overlay in owner.overlays_standing)
+ if(istype(overlay, /mutable_appearance))
+ var/mutable_appearance/mutable = overlay
+ if(mutable.category == "HEAD")
+ add_head_overlay(mutable)
+ else
+ if(islist(overlay))
+ var/list/list_appearances = overlay
+ for(var/overlay2 in list_appearances)
+ if(istype(overlay2, /mutable_appearance))
+ var/mutable_appearance/mutable = overlay2
+ if(mutable.category == "HEAD")
+ add_head_overlay(mutable)
+ head.drop_limb()
+ qdel(head)
/obj/item/dullahan_head/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs)
excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs.
@@ -173,6 +177,7 @@
/datum/component/dullahan/Destroy()
UnregisterSignal(parent, COMSIG_LIVING_REGENERATE_LIMBS)
+ dullahan_head.owner = null
qdel(dullahan_head)
REMOVE_TRAIT(parent, TRAIT_DULLAHAN, "dullahan_component")
@@ -186,6 +191,9 @@
var/obj/item/organ/brain/old_brain = H.getorganslot(ORGAN_SLOT_BRAIN)
var/obj/item/organ/tongue/old_tongue = H.getorganslot(ORGAN_SLOT_TONGUE)
+ H.regenerate_limb(BODY_ZONE_HEAD, TRUE)
+ H.reset_perspective(H)
+
old_brain.Remove(TRUE,TRUE)
QDEL_NULL(old_brain)
new_brain.Insert(H, TRUE, TRUE)
From 325d467ac580f9bba7741eebf333314469bf821a Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sat, 13 Aug 2022 18:45:25 +0100
Subject: [PATCH 23/24] Update mirror.dm
---
code/game/objects/structures/mirror.dm | 1 +
1 file changed, 1 insertion(+)
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index 9ff41c4404..ffb48ce633 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -42,6 +42,7 @@
H.hair_style = new_style
H.update_mutant_bodyparts()
+ H.update_hair()
/obj/structure/mirror/examine_status(mob/user)
if(broken)
From b7673e234fc001ee47f8e35c267ab6ae12c879a8 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 9 Dec 2022 13:30:10 +0000
Subject: [PATCH 24/24] add no hunger no breath
---
code/datums/components/dullahan.dm | 2 ++
1 file changed, 2 insertions(+)
diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm
index 6b18f7f6c1..973f06a61e 100644
--- a/code/datums/components/dullahan.dm
+++ b/code/datums/components/dullahan.dm
@@ -9,6 +9,8 @@
return .
ADD_TRAIT(H, TRAIT_DULLAHAN, "dullahan_component")
+ ADD_TRAIT(H, TRAIT_NOHUNGER, "dullahan_component_no_hunger")
+ ADD_TRAIT(H, TRAIT_NOBREATH, "dullahan_component_no_breath")
dullahan_head = new(get_turf(H))