From b909582c8fc251b7fc6c182b1493782537bf2d80 Mon Sep 17 00:00:00 2001 From: mistakenot4892 Date: Sun, 19 Oct 2025 21:45:49 +1100 Subject: [PATCH] Moving undead into a modpack. --- code/modules/mob/living/human/death.dm | 13 -- code/modules/mob/living/human/human.dm | 33 ----- .../mob/living/human/human_appearance_head.dm | 10 -- code/modules/mob/living/human/human_damage.dm | 17 +-- code/modules/mob/living/human/human_organs.dm | 13 -- code/modules/organs/external/_external.dm | 10 +- code/modules/organs/organ.dm | 4 +- mods/content/fantasy/datum/overrides.dm | 11 -- mods/content/undead/_undead.dm | 2 + mods/content/undead/_undead.dme | 12 ++ .../undead => content/undead/mods}/undead.dm | 0 .../undead/mods}/undead_skeleton.dm | 0 .../undead/mods}/undead_zombie.dm | 0 mods/content/undead/overrides.dm | 134 ++++++++++++++++++ mods/content/undead/skillset.dm | 2 + mods/content/undead/traits.dm | 4 + mods/pyrelight/_pyrelight.dme | 3 - mods/pyrelight/undead/_undead.dm | 27 ---- mods/~compatibility/patches/fantasy.dm | 6 +- .../patches/fantasy/undead_fantasy.dm | 9 ++ nebula.dme | 1 - 21 files changed, 178 insertions(+), 133 deletions(-) create mode 100644 mods/content/undead/_undead.dm create mode 100644 mods/content/undead/_undead.dme rename mods/{pyrelight/undead => content/undead/mods}/undead.dm (100%) rename mods/{pyrelight/undead => content/undead/mods}/undead_skeleton.dm (100%) rename mods/{pyrelight/undead => content/undead/mods}/undead_zombie.dm (100%) create mode 100644 mods/content/undead/overrides.dm create mode 100644 mods/content/undead/skillset.dm create mode 100644 mods/content/undead/traits.dm delete mode 100644 mods/pyrelight/undead/_undead.dm create mode 100644 mods/~compatibility/patches/fantasy/undead_fantasy.dm diff --git a/code/modules/mob/living/human/death.dm b/code/modules/mob/living/human/death.dm index 06d33a1e66aa..b19a6a2c8573 100644 --- a/code/modules/mob/living/human/death.dm +++ b/code/modules/mob/living/human/death.dm @@ -1,7 +1,5 @@ /mob/living/human/gib(do_gibs = TRUE) var/turf/my_turf = get_turf(src) - if(do_gibs && has_trait(/decl/trait/undead, TRAIT_LEVEL_MODERATE)) - do_gibs = FALSE . = ..(do_gibs) if(.) for(var/obj/item/organ/I in get_internal_organs()) @@ -18,15 +16,10 @@ E.throw_at(get_edge_target_turf(E, pick(global.alldirs)), rand(1,3), THROWFORCE_GIBS) /mob/living/human/get_death_message(gibbed) - if(has_trait(/decl/trait/undead, TRAIT_LEVEL_MODERATE)) - return "crumbles and falls apart!" if(get_config_value(/decl/config/toggle/health_show_human_death_message)) return species.get_species_death_message(src) || "seizes up and falls limp..." return ..() -/mob/living/human/get_self_death_message(gibbed) - return has_trait(/decl/trait/undead, TRAIT_LEVEL_MODERATE) ? "You have crumbled." : ..() - /mob/living/human/death(gibbed) if(!(. = ..())) return @@ -43,12 +36,6 @@ if(SSticker.mode) SSticker.mode.check_win() - if(!QDELETED(src) && !gibbed && has_trait(/decl/trait/undead, TRAIT_LEVEL_MODERATE)) - gib() - -/mob/living/human/get_gibber_type() - return has_trait(/decl/trait/undead, TRAIT_LEVEL_MODERATE) ? null : ..() - /mob/living/human/physically_destroyed(var/skip_qdel, var/droplimb_type = DISMEMBER_METHOD_BLUNT) for(var/obj/item/organ/external/limb in get_external_organs()) if(!limb.parent_organ) // don't dismember root diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index 91fe3f114b19..fad1ca169d4e 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -1121,16 +1121,6 @@ var/temp_inc = max(min(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), exposed_temperature - bodytemperature), 0) bodytemperature += temp_inc -/mob/living/human/need_breathe() - return has_trait(/decl/trait/undead) ? FALSE : ..() - -// Undead don't get hungry/thirsty (except for brains) -/mob/living/human/get_nutrition() - return has_trait(/decl/trait/undead) ? get_max_nutrition() : ..() - -/mob/living/human/get_hydration() - return has_trait(/decl/trait/undead) ? get_max_hydration() : ..() - /mob/living/human/currently_has_skin() return currently_has_meat() @@ -1146,29 +1136,6 @@ /mob/living/human/get_attack_telegraph_delay() return client ? 0 : DEFAULT_ATTACK_COOLDOWN -/mob/living/human/set_status_condition(condition, amount) - if(has_trait(/decl/trait/undead)) - var/static/list/ignore_status_conditions = list( - STAT_BLIND, - STAT_DEAF, - STAT_CONFUSE, - STAT_DIZZY, - STAT_JITTER, - STAT_STUTTER, - STAT_SLUR, - STAT_ASLEEP, - STAT_DRUGGY, - STAT_DROWSY, - STAT_BLURRY, - STAT_BLIND, - STAT_TINNITUS, - STAT_DEAF - ) - if(condition in ignore_status_conditions) - return - - . = ..() - /mob/living/human/isSynthetic() if(isnull(full_prosthetic)) robolimb_count = 0 diff --git a/code/modules/mob/living/human/human_appearance_head.dm b/code/modules/mob/living/human/human_appearance_head.dm index ad631c88e56f..f5ed43182da9 100644 --- a/code/modules/mob/living/human/human_appearance_head.dm +++ b/code/modules/mob/living/human/human_appearance_head.dm @@ -3,18 +3,8 @@ // Eyes! TODO, make these a marking. /mob/living/human/get_eye_colour() - // Force an evil red glow for undead mobs. - if(stat == CONSCIOUS && has_trait(/decl/trait/undead)) - return COLOR_RED return _eye_colour -/mob/living/human/death(gibbed) - . = ..() - if(!QDELETED(src) && has_trait(/decl/trait/undead)) - var/obj/item/organ/external/head/head = get_organ(BP_HEAD) - head.glowing_eyes = initial(head.glowing_eyes) - update_eyes() - /mob/living/human/set_eye_colour(var/new_color, var/skip_update = FALSE) if((. = ..())) _eye_colour = new_color diff --git a/code/modules/mob/living/human/human_damage.dm b/code/modules/mob/living/human/human_damage.dm index 72e1546c7db1..d1d64b56f8a7 100644 --- a/code/modules/mob/living/human/human_damage.dm +++ b/code/modules/mob/living/human/human_damage.dm @@ -1,11 +1,4 @@ /mob/living/human/get_life_damage_types() - if(has_trait(/decl/trait/undead)) - // Undead human mobs use brute and burn damage instead of brain damage, a la simplemobs. - var/static/list/life_damage_types = list( - BURN, - BRUTE - ) - return life_damage_types var/static/list/brain_life_damage_types = list( BRAIN ) @@ -146,13 +139,9 @@ return 0 /mob/living/human/setOxyLoss(var/amount) - if(has_trait(/decl/trait/undead)) - return take_damage(amount - get_damage(OXY), OXY) /mob/living/human/adjustOxyLoss(var/damage, var/do_update_health = TRUE) - if(has_trait(/decl/trait/undead)) - return . = FALSE if(need_breathe()) var/obj/item/organ/internal/lungs/breathe_organ = get_organ(get_bodytype().breathing_organ, /obj/item/organ/internal/lungs) @@ -163,7 +152,7 @@ ..(do_update_health = FALSE) // Oxyloss cannot directly kill humans /mob/living/human/getToxLoss() - if((species.species_flags & SPECIES_FLAG_NO_POISON) || isSynthetic() || has_trait(/decl/trait/undead)) + if((species.species_flags & SPECIES_FLAG_NO_POISON) || isSynthetic()) return 0 var/amount = 0 for(var/obj/item/organ/internal/I in get_internal_organs()) @@ -171,13 +160,13 @@ return amount /mob/living/human/setToxLoss(var/amount) - if(!(species.species_flags & SPECIES_FLAG_NO_POISON) && !isSynthetic() || has_trait(/decl/trait/undead)) + if(!(species.species_flags & SPECIES_FLAG_NO_POISON) && !isSynthetic()) take_damage(get_damage(TOX)-amount, TOX) // TODO: better internal organ damage procs. /mob/living/human/adjustToxLoss(var/amount, var/do_update_health = TRUE) - if((species.species_flags & SPECIES_FLAG_NO_POISON) || isSynthetic() || has_trait(/decl/trait/undead)) + if((species.species_flags & SPECIES_FLAG_NO_POISON) || isSynthetic()) return var/heal = amount < 0 diff --git a/code/modules/mob/living/human/human_organs.dm b/code/modules/mob/living/human/human_organs.dm index da7a70ca52c9..1b4884758d9c 100644 --- a/code/modules/mob/living/human/human_organs.dm +++ b/code/modules/mob/living/human/human_organs.dm @@ -156,25 +156,12 @@ LAZYDISTINCTADD(bad_external_organs, E) /mob/living/human/proc/check_vital_organ_missing() - // Undead don't care about missing internal organs. - if(has_trait(/decl/trait/undead)) - return FALSE return get_bodytype()?.check_vital_organ_missing(src) -/mob/living/human/should_have_organ(organ_to_check) - // It might be nice to have eyes etc. matter for zombies, but as all organs are dead it won't work currently. - return has_trait(/decl/trait/undead) ? FALSE : ..() - /mob/living/human/proc/process_internal_organs() - if(has_trait(/decl/trait/undead)) - return for(var/obj/item/organ/I in internal_organs) I.Process() -/mob/living/human/get_vision_organ_tag() - // Where we're going, we don't need eyes. - return has_trait(/decl/trait/undead) ? null : ..() - // Takes care of organ related updates, such as broken and missing limbs /mob/living/human/proc/handle_organs() diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 953a5c3e112f..8a632db3af25 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -725,16 +725,18 @@ This function completely restores a damaged organ to perfect condition. /obj/item/organ/external/is_broken() return ((status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !splinted)) +/obj/item/organ/external/proc/check_status_flags_for_process() + if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_MUTATED|ORGAN_DISLOCATED|ORGAN_DEAD)) + return TRUE + return FALSE + //Determines if we even need to process this organ. /obj/item/organ/external/proc/need_process() if(length(ailments)) return TRUE - if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_MUTATED|ORGAN_DISLOCATED)) - return TRUE - - if((status & ORGAN_DEAD) && !owner?.has_trait(/decl/trait/undead)) + if(check_status_flags_for_process()) return TRUE if((brute_dam || burn_dam) && !BP_IS_PROSTHETIC(src)) //Robot limbs don't autoheal and thus don't need to process when damaged diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index aaba6d3012b7..00c13e68f262 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -443,9 +443,7 @@ return bodytype && !(bodytype.body_flags & BODY_FLAG_NO_PAIN) && !(status & ORGAN_DEAD) /obj/item/organ/proc/is_usable() - . = !(status & (ORGAN_CUT_AWAY|ORGAN_MUTATED)) - if(. && (status & ORGAN_DEAD)) - return owner?.has_trait(/decl/trait/undead) + return !(status & (ORGAN_CUT_AWAY|ORGAN_MUTATED|ORGAN_DEAD)) /obj/item/organ/proc/can_recover() return (max_damage > 0) && !(status & ORGAN_DEAD) || death_time >= REALTIMEOFDAY - ORGAN_RECOVERY_THRESHOLD diff --git a/mods/content/fantasy/datum/overrides.dm b/mods/content/fantasy/datum/overrides.dm index 872d69c051c2..da96ea085c32 100644 --- a/mods/content/fantasy/datum/overrides.dm +++ b/mods/content/fantasy/datum/overrides.dm @@ -65,14 +65,3 @@ /obj/item/remains/robot ) return spawnable_choices - -// Overrides to populate the dungeon with undead. -/obj/random/hostile/dungeon/spawn_choices() - var/static/list/spawnable_choices = list( - /mob/living/human/zombie = 1, - /mob/living/human/skeleton = 2, - /mob/living/human/zombie/hnoll = 1, - /mob/living/human/skeleton/hnoll = 2 - ) - return spawnable_choices - diff --git a/mods/content/undead/_undead.dm b/mods/content/undead/_undead.dm new file mode 100644 index 000000000000..37cb87794289 --- /dev/null +++ b/mods/content/undead/_undead.dm @@ -0,0 +1,2 @@ +/decl/modpack/undead + name = "Undead Content" \ No newline at end of file diff --git a/mods/content/undead/_undead.dme b/mods/content/undead/_undead.dme new file mode 100644 index 000000000000..2068815dbd2f --- /dev/null +++ b/mods/content/undead/_undead.dme @@ -0,0 +1,12 @@ +#ifndef MODPACK_UNDEAD +#define MODPACK_UNDEAD +// BEGIN_INCLUDE +#include "_undead.dm" +#include "overrides.dm" +#include "skillset.dm" +#include "traits.dm" +#include "mods\undead.dm" +#include "mods\undead_skeleton.dm" +#include "mods\undead_zombie.dm" +// END_INCLUDE +#endif diff --git a/mods/pyrelight/undead/undead.dm b/mods/content/undead/mods/undead.dm similarity index 100% rename from mods/pyrelight/undead/undead.dm rename to mods/content/undead/mods/undead.dm diff --git a/mods/pyrelight/undead/undead_skeleton.dm b/mods/content/undead/mods/undead_skeleton.dm similarity index 100% rename from mods/pyrelight/undead/undead_skeleton.dm rename to mods/content/undead/mods/undead_skeleton.dm diff --git a/mods/pyrelight/undead/undead_zombie.dm b/mods/content/undead/mods/undead_zombie.dm similarity index 100% rename from mods/pyrelight/undead/undead_zombie.dm rename to mods/content/undead/mods/undead_zombie.dm diff --git a/mods/content/undead/overrides.dm b/mods/content/undead/overrides.dm new file mode 100644 index 000000000000..2925d7b3e01d --- /dev/null +++ b/mods/content/undead/overrides.dm @@ -0,0 +1,134 @@ +/mob/living/can_feel_pain(var/check_organ) + return !has_trait(/decl/trait/undead) && ..() + +/mob/living/human/get_gibber_type() // To avoid skeletons causing gibs. + return has_trait(/decl/trait/undead, TRAIT_LEVEL_MODERATE) ? null : ..() + +/mob/living/human/ssd_check() + if(has_trait(/decl/trait/undead)) + return FALSE + return ..() + +/mob/living/human/get_movement_delay(travel_dir) + . = ..() + if(has_trait(/decl/trait/undead)) + var/static/default_walk_delay = get_config_value(/decl/config/num/movement_walk) + . = max(., default_walk_delay) + +/mob/living/human/get_attack_telegraph_delay() + if(has_trait(/decl/trait/undead)) + return (0.6 SECONDS) + return ..() + +/mob/living/human/get_self_death_message(gibbed) + return has_trait(/decl/trait/undead, TRAIT_LEVEL_MODERATE) ? "You have crumbled." : ..() + +/mob/living/human/get_death_message(gibbed) + if(has_trait(/decl/trait/undead, TRAIT_LEVEL_MODERATE)) + return "crumbles and falls apart!" + return ..() + +/mob/living/human/death(gibbed) + . = ..() + if(stat == DEAD && !QDELETED(src) && !gibbed && has_trait(/decl/trait/undead, TRAIT_LEVEL_MODERATE)) + gib() + +/mob/living/human/get_eye_colour() + // Force an evil red glow for undead mobs. + if(stat == CONSCIOUS && has_trait(/decl/trait/undead)) + return COLOR_RED + return ..() + +/mob/living/human/death(gibbed) + . = ..() + if(!QDELETED(src) && has_trait(/decl/trait/undead)) + var/obj/item/organ/external/head/head = get_organ(BP_HEAD) + head.glowing_eyes = initial(head.glowing_eyes) + update_eyes() + +/mob/living/human/get_life_damage_types() + if(has_trait(/decl/trait/undead)) + // Undead human mobs use brute and burn damage instead of brain damage, a la simplemobs. + var/static/list/life_damage_types = list( + BURN, + BRUTE + ) + return life_damage_types + return ..() + +/mob/living/human/getOxyLoss(var/amount) + return has_trait(/decl/trait/undead) ? 0 : ..() + +/mob/living/human/setOxyLoss(var/amount) + return has_trait(/decl/trait/undead) ? 0 : ..() + +/mob/living/human/adjustOxyLoss(var/damage, var/do_update_health = TRUE) + return has_trait(/decl/trait/undead) ? 0 : ..() + +/mob/living/human/getToxLoss() + return has_trait(/decl/trait/undead) ? 0 : ..() + +/mob/living/human/setToxLoss(var/amount) + return has_trait(/decl/trait/undead) ? 0 : ..() + +/mob/living/human/adjustToxLoss(var/amount, var/do_update_health = TRUE) + return has_trait(/decl/trait/undead) ? 0 : ..() + +/mob/living/human/proc/check_vital_organ_missing() + return !has_trait(/decl/trait/undead) && ..() + +/mob/living/human/proc/process_internal_organs() + return has_trait(/decl/trait/undead) ? null : ..() + +/mob/living/human/should_have_organ(organ_to_check) + // It might be nice to have eyes etc. matter for zombies, but as all organs are dead it won't work currently. + return has_trait(/decl/trait/undead) ? FALSE : ..() + +/mob/living/human/get_vision_organ_tag() + // Where we're going, we don't need eyes. + return has_trait(/decl/trait/undead) ? null : ..() + +/mob/living/human/need_breathe() + return has_trait(/decl/trait/undead) ? FALSE : ..() + +// Undead don't get hungry/thirsty (except for brains) +/mob/living/human/get_nutrition() + return has_trait(/decl/trait/undead) ? get_max_nutrition() : ..() + +/mob/living/human/get_hydration() + return has_trait(/decl/trait/undead) ? get_max_hydration() : ..() + +// Overrides to handle dead flag separately. +/obj/item/organ/is_usable() + . = !(status & (ORGAN_CUT_AWAY|ORGAN_MUTATED)) + if(. && (status & ORGAN_DEAD)) + return owner?.has_trait(/decl/trait/undead) + +/obj/item/organ/external/check_status_flags_for_process() + if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_MUTATED|ORGAN_DISLOCATED)) + return TRUE + if((status & ORGAN_DEAD) && !owner?.has_trait(/decl/trait/undead)) + return TRUE + return FALSE + +/mob/living/human/set_status_condition(condition, amount) + if(has_trait(/decl/trait/undead)) + var/static/list/ignore_status_conditions = list( + STAT_BLIND, + STAT_DEAF, + STAT_CONFUSE, + STAT_DIZZY, + STAT_JITTER, + STAT_STUTTER, + STAT_SLUR, + STAT_ASLEEP, + STAT_DRUGGY, + STAT_DROWSY, + STAT_BLURRY, + STAT_BLIND, + STAT_TINNITUS, + STAT_DEAF + ) + if(condition in ignore_status_conditions) + return + . = ..() diff --git a/mods/content/undead/skillset.dm b/mods/content/undead/skillset.dm new file mode 100644 index 000000000000..479d7cfe5505 --- /dev/null +++ b/mods/content/undead/skillset.dm @@ -0,0 +1,2 @@ +/datum/skillset/undead + default_value = SKILL_BASIC diff --git a/mods/content/undead/traits.dm b/mods/content/undead/traits.dm new file mode 100644 index 000000000000..06d4f34e9572 --- /dev/null +++ b/mods/content/undead/traits.dm @@ -0,0 +1,4 @@ +/decl/trait/undead + name = "Undead" + description = "Your body is dead, but remains animated through some supernatural force." + levels = list(TRAIT_LEVEL_MINOR, TRAIT_LEVEL_MODERATE) // Moderate means skeleton, minor means zombie. diff --git a/mods/pyrelight/_pyrelight.dme b/mods/pyrelight/_pyrelight.dme index 8310c9ab4569..ffb1b4057f8e 100644 --- a/mods/pyrelight/_pyrelight.dme +++ b/mods/pyrelight/_pyrelight.dme @@ -20,8 +20,5 @@ #include "plants\plants_fruit_template.dm" #include "plants\fruit_subtypes\nightweave.dm" #include "plants\plant_subtypes\nightweave.dm" -#include "undead\undead.dm" -#include "undead\undead_skeleton.dm" -#include "undead\undead_zombie.dm" #endif // END_INCLUDE diff --git a/mods/pyrelight/undead/_undead.dm b/mods/pyrelight/undead/_undead.dm deleted file mode 100644 index e71e26b89f52..000000000000 --- a/mods/pyrelight/undead/_undead.dm +++ /dev/null @@ -1,27 +0,0 @@ -// This is included in main code due to the invasive overrides needed in human life processing. -/decl/trait/undead - name = "Undead" - description = "Your body is dead, but remains animated through some supernatural force." - levels = list(TRAIT_LEVEL_MINOR, TRAIT_LEVEL_MODERATE) // Moderate means skeleton, minor means zombie. - -/mob/living/human/ssd_check() - if(has_trait(/decl/trait/undead)) - return FALSE - return ..() - -/mob/living/human/get_movement_delay(travel_dir) - . = ..() - if(has_trait(/decl/trait/undead)) - var/static/default_walk_delay = get_config_value(/decl/config/num/movement_walk) - . = max(., default_walk_delay) - -/mob/living/can_feel_pain(var/check_organ) - return !has_trait(/decl/trait/undead) && ..() - -/mob/living/human/get_attack_telegraph_delay() - if(has_trait(/decl/trait/undead)) - return (0.6 SECONDS) - return ..() - -/datum/skillset/undead - default_value = SKILL_BASIC diff --git a/mods/~compatibility/patches/fantasy.dm b/mods/~compatibility/patches/fantasy.dm index b0abba63bcd4..201ed3bfc435 100644 --- a/mods/~compatibility/patches/fantasy.dm +++ b/mods/~compatibility/patches/fantasy.dm @@ -10,4 +10,8 @@ #ifdef MODPACK_BLACKSMITHY #include "fantasy/forging_fantasy.dm" -#endif \ No newline at end of file +#endif + +#ifdef MODPACK_UNDEAD +#include "fantasy/undead_fantasy.dm" +#endif diff --git a/mods/~compatibility/patches/fantasy/undead_fantasy.dm b/mods/~compatibility/patches/fantasy/undead_fantasy.dm new file mode 100644 index 000000000000..a71f865785ce --- /dev/null +++ b/mods/~compatibility/patches/fantasy/undead_fantasy.dm @@ -0,0 +1,9 @@ +// Overrides to populate the dungeon with undead. +/obj/random/hostile/dungeon/spawn_choices() + var/static/list/spawnable_choices = list( + /mob/living/human/zombie = 1, + /mob/living/human/skeleton = 2, + /mob/living/human/zombie/hnoll = 1, + /mob/living/human/skeleton/hnoll = 2 + ) + return spawnable_choices diff --git a/nebula.dme b/nebula.dme index 1e1672c99e86..a5e98fd7ea57 100644 --- a/nebula.dme +++ b/nebula.dme @@ -4092,7 +4092,6 @@ #include "maps\~mapsystem\maps_unit_testing.dm" #include "maps\~unit_tests\unit_testing.dm" #include "mods\_modpack.dm" -#include "mods\pyrelight\undead\_undead.dm" #include "mods\~compatibility\~compatibility.dm" #include "~code\global_init.dm" // END_INCLUDE