From f92c67adf0783f42179c3961fff5dad96a8fa9c5 Mon Sep 17 00:00:00 2001 From: Darius <5933805+LeDrascol@users.noreply.github.com> Date: Tue, 14 Feb 2023 12:14:11 -0500 Subject: [PATCH 1/6] Initial implementation of zombie quirk Adds the new quirk 'Postmortem Flesh', which replicates the effects of zombie races. The associated zombie races are disabled as a result. --- code/__SPLURTCODE/DEFINES/traits.dm | 1 + modular_splurt/code/datums/traits/neutral.dm | 131 ++++++++++++++++++ .../carbon/human/species_types/zombies2.dm | 10 ++ .../code/modules/movespeed/modifiers/mobs.dm | 4 + tgstation.dme | 1 + 5 files changed, 147 insertions(+) create mode 100644 modular_splurt/code/modules/movespeed/modifiers/mobs.dm diff --git a/code/__SPLURTCODE/DEFINES/traits.dm b/code/__SPLURTCODE/DEFINES/traits.dm index 4dcb8e375bca..2ab293497828 100644 --- a/code/__SPLURTCODE/DEFINES/traits.dm +++ b/code/__SPLURTCODE/DEFINES/traits.dm @@ -27,3 +27,4 @@ #define TRAIT_NUDIST "Nudist" #define TRAIT_CLOTH_EATER "cloth_eater" #define TRAIT_WEREWOLF "Werewolf" +#define TRAIT_UNDEAD_QUIRK "quirk_zombie" diff --git a/modular_splurt/code/datums/traits/neutral.dm b/modular_splurt/code/datums/traits/neutral.dm index 5fdca5e6f58e..4245dd139dd9 100644 --- a/modular_splurt/code/datums/traits/neutral.dm +++ b/modular_splurt/code/datums/traits/neutral.dm @@ -678,3 +678,134 @@ var/obj/item/clothing/mask/gas/cosmetic/gasmask = new(get_turf(quirk_holder)) // Uses a custom gas mask H.equip_to_slot(gasmask, ITEM_SLOT_MASK) H.regenerate_icons() + +/datum/quirk/zombie + name = "Postmortem Flesh" + desc = "You've been freed from the mortal coil, and passed on to become a zombie! Your body rapidly regenerates, and can't be put into critical condition. However, you won't be able to cheat death a second time..." + value = 0 + medical_record_text = "Scans indicate the patient to be deceased." + mob_trait = TRAIT_UNDEAD_QUIRK + gain_text = span_notice("Your flesh rots and burns as it clings to life.") + lose_text = span_warning("The mortal coil binds you once again.") + processing_quirk = TRUE + + // Amount of damage to heal + var/regen_amount = -3 + +/datum/quirk/zombie/add() + // Define quirk mob + var/mob/living/carbon/human/quirk_mob = quirk_holder + + // Add quirk traits, based on zombie race + ADD_TRAIT(quirk_mob,TRAIT_EASYDISMEMBER,TRAIT_UNDEAD_QUIRK) + ADD_TRAIT(quirk_mob,TRAIT_LIMBATTACHMENT,TRAIT_UNDEAD_QUIRK) + ADD_TRAIT(quirk_mob,TRAIT_NOBREATH,TRAIT_UNDEAD_QUIRK) + ADD_TRAIT(quirk_mob,TRAIT_FAKEDEATH,TRAIT_UNDEAD_QUIRK) + ADD_TRAIT(quirk_mob,TRAIT_NOSOFTCRIT,TRAIT_UNDEAD_QUIRK) + ADD_TRAIT(quirk_mob,TRAIT_NOHARDCRIT,TRAIT_UNDEAD_QUIRK) + ADD_TRAIT(quirk_mob,TRAIT_NOCLONE,TRAIT_UNDEAD_QUIRK) + ADD_TRAIT(quirk_mob,TRAIT_NOMARROW,TRAIT_UNDEAD_QUIRK) + + // Check for halloween + if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) + // Add holiday traits + ADD_TRAIT(quirk_mob, TRAIT_NODEATH,TRAIT_UNDEAD_QUIRK) + + // Double regeneration rate + regen_amount *= 2 + + // Not halloween + else + // Add speed reduction + quirk_mob.add_movespeed_modifier(/datum/movespeed_modifier/undead_quirk_speedmod, TRUE) + + // Add undead biotype + quirk_mob.mob_biotypes |= MOB_UNDEAD + + // Set screwy health HUD + quirk_mob.set_screwyhud(SCREWYHUD_HEALTHY) + + // Define infection organ + var/obj/item/organ/undead_infection/organ_infection = quirk_mob.getorganslot(ORGAN_SLOT_ZOMBIE) + + // Check if zombie organ exists + if(!organ_infection) + // Create and insert organ + organ_infection = new() + organ_infection.Insert(quirk_mob) + +/datum/quirk/zombie/post_add() + // Check for halloween + if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) + // Display notice message + to_chat(quirk_holder, span_alert("The spooky season has empowered you with the ability to avoid death forever! Nothing can stop you now!")) + +/datum/quirk/zombie/remove() + // Define quirk mob + var/mob/living/carbon/human/quirk_mob = quirk_holder + + // Define infection organ + var/obj/item/organ/undead_infection/organ_infection = quirk_mob.getorganslot(ORGAN_SLOT_ZOMBIE) + + // Check if zombie organ exists + if(organ_infection) + // Remove organ + organ_infection.Remove() + + // Remove quirk traits + REMOVE_TRAIT(quirk_mob,TRAIT_EASYDISMEMBER,TRAIT_UNDEAD_QUIRK) + REMOVE_TRAIT(quirk_mob,TRAIT_LIMBATTACHMENT,TRAIT_UNDEAD_QUIRK) + REMOVE_TRAIT(quirk_mob,TRAIT_NOBREATH,TRAIT_UNDEAD_QUIRK) + REMOVE_TRAIT(quirk_mob,TRAIT_FAKEDEATH,TRAIT_UNDEAD_QUIRK) + REMOVE_TRAIT(quirk_mob,TRAIT_NOSOFTCRIT,TRAIT_UNDEAD_QUIRK) + REMOVE_TRAIT(quirk_mob,TRAIT_NOMARROW,TRAIT_UNDEAD_QUIRK) + REMOVE_TRAIT(quirk_mob,TRAIT_NOCLONE,TRAIT_UNDEAD_QUIRK) + REMOVE_TRAIT(quirk_mob,TRAIT_NODEATH,TRAIT_UNDEAD_QUIRK) + + // Remove undead biotype + quirk_mob.mob_biotypes -= MOB_UNDEAD + + // Remove speed reduction + quirk_mob.remove_movespeed_modifier(/datum/movespeed_modifier/undead_quirk_speedmod, TRUE) + + // Remove screwy health HUD + quirk_mob.set_screwyhud(SCREWYHUD_NONE) + +/datum/quirk/zombie/on_process() + // Define quirk mob + var/mob/living/carbon/human/quirk_mob = quirk_holder + + // Check if quick holder is damaged + if(quirk_mob.health >= quirk_mob.maxHealth) + return + + // Check for sufficient blood + if(quirk_mob.blood_volume <= BLOOD_VOLUME_SURVIVE) + return + + // Define initial health + var/health_start = quirk_mob.health + + // Check for brute damage + if(quirk_mob.getBruteLoss()) + // Remove brute damage + quirk_mob.adjustBruteLoss(regen_amount) + + // Check for burn damage + if(quirk_mob.getFireLoss()) + // Remove burn damage + quirk_mob.adjustFireLoss(regen_amount) + + // Check for toxin damage + if(quirk_mob.getToxLoss()) + // Remove toxin damage + quirk_mob.adjustToxLoss(regen_amount) + + // Check for cellular damage + if(quirk_mob.getCloneLoss()) + // Remove toxin damage + quirk_mob.adjustCloneLoss(regen_amount) + + // Remove blood as compensation for healing + // Value is determined by amount healed + quirk_mob.blood_volume -= (quirk_mob.health - health_start) diff --git a/modular_splurt/code/modules/mob/living/carbon/human/species_types/zombies2.dm b/modular_splurt/code/modules/mob/living/carbon/human/species_types/zombies2.dm index e812380fbc60..789b0bc4ecb7 100644 --- a/modular_splurt/code/modules/mob/living/carbon/human/species_types/zombies2.dm +++ b/modular_splurt/code/modules/mob/living/carbon/human/species_types/zombies2.dm @@ -415,3 +415,13 @@ icon_state = "pill5" color = "#830000" list_reagents = list(/datum/reagent/draughtofundeath = 1) + +// Block round-start selection for zombies +/datum/species/mammal/undead/check_roundstart_eligible() + return FALSE + +/datum/species/insect/undead/check_roundstart_eligible() + return FALSE + +/datum/species/lizard/undead/check_roundstart_eligible() + return FALSE diff --git a/modular_splurt/code/modules/movespeed/modifiers/mobs.dm b/modular_splurt/code/modules/movespeed/modifiers/mobs.dm new file mode 100644 index 000000000000..d871ced74641 --- /dev/null +++ b/modular_splurt/code/modules/movespeed/modifiers/mobs.dm @@ -0,0 +1,4 @@ +/datum/movespeed_modifier/undead_quirk_speedmod + multiplicative_slowdown = 1.4 + blacklisted_movetypes = FLOATING|FLYING + flags = IGNORE_NOSLOW diff --git a/tgstation.dme b/tgstation.dme index b07269057e2e..dc0810790796 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4720,6 +4720,7 @@ #include "modular_splurt\code\modules\mob\living\simple_animal\hostile\megafauna\blood_drunk_miner.dm" #include "modular_splurt\code\modules\mob\living\simple_animal\hostile\megafauna\king_of_goats.dm" #include "modular_splurt\code\modules\mob\living\simple_animal\hostile\megafauna\sand.dm" +#include "modular_splurt\code\modules\movespeed\modifiers\mobs.dm" #include "modular_splurt\code\modules\paperwork\pen.dm" #include "modular_splurt\code\modules\photography\photos\album.dm" #include "modular_splurt\code\modules\photography\photos\photo.dm" From 68e5364f8946be25df8b464a29b797040a1fd507 Mon Sep 17 00:00:00 2001 From: Darius <5933805+LeDrascol@users.noreply.github.com> Date: Tue, 14 Feb 2023 12:27:17 -0500 Subject: [PATCH 2/6] Zombie quirk organ handling tweaks Moves the organ replacement code for the 'Postmortem Flesh' quirk from `add()` to `on_spawn()` , and adds support for the zombie tongue. --- modular_splurt/code/datums/traits/neutral.dm | 25 +++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/modular_splurt/code/datums/traits/neutral.dm b/modular_splurt/code/datums/traits/neutral.dm index 4245dd139dd9..cd25fa524796 100644 --- a/modular_splurt/code/datums/traits/neutral.dm +++ b/modular_splurt/code/datums/traits/neutral.dm @@ -725,20 +725,29 @@ // Set screwy health HUD quirk_mob.set_screwyhud(SCREWYHUD_HEALTHY) - // Define infection organ - var/obj/item/organ/undead_infection/organ_infection = quirk_mob.getorganslot(ORGAN_SLOT_ZOMBIE) +/datum/quirk/zombie/post_add() + // Check for halloween + if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) + // Display notice message + to_chat(quirk_holder, span_alert("The spooky season has empowered you with the ability to avoid death forever! Nothing can stop you now!")) + +/datum/quirk/zombie/on_spawn() + // Get organ target: Infection + var/obj/item/organ/undead_infection/organ_infection = quirk_holder.getorganslot(ORGAN_SLOT_ZOMBIE) // Check if zombie organ exists if(!organ_infection) // Create and insert organ organ_infection = new() - organ_infection.Insert(quirk_mob) + organ_infection.Insert(quirk_holder) -/datum/quirk/zombie/post_add() - // Check for halloween - if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) - // Display notice message - to_chat(quirk_holder, span_alert("The spooky season has empowered you with the ability to avoid death forever! Nothing can stop you now!")) + // Get organ target: Tongue + var/obj/item/organ/tongue/old_tongue = quirk_holder.getorganslot(ORGAN_SLOT_TONGUE) + var/obj/item/organ/tongue/zombie/new_tongue = new + + // Replace tongue + qdel(old_tongue) + new_tongue.Insert(quirk_holder) /datum/quirk/zombie/remove() // Define quirk mob From 2f60c5827b6dacd2ff6d4069695c6c47176a0212 Mon Sep 17 00:00:00 2001 From: Darius <5933805+LeDrascol@users.noreply.github.com> Date: Tue, 14 Feb 2023 12:37:22 -0500 Subject: [PATCH 3/6] Prevent runtime for zombie quirk removal Checks if the quirk mob exists before attempting to remove the zombie quirk, to prevent errors with invalid organs. This issue could occur when the mob is gibbed. --- modular_splurt/code/datums/traits/neutral.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modular_splurt/code/datums/traits/neutral.dm b/modular_splurt/code/datums/traits/neutral.dm index cd25fa524796..b7ba75e637dc 100644 --- a/modular_splurt/code/datums/traits/neutral.dm +++ b/modular_splurt/code/datums/traits/neutral.dm @@ -753,6 +753,10 @@ // Define quirk mob var/mob/living/carbon/human/quirk_mob = quirk_holder + // Check if quirk mob still exists + if(!istype(quirk_mob)) + return + // Define infection organ var/obj/item/organ/undead_infection/organ_infection = quirk_mob.getorganslot(ORGAN_SLOT_ZOMBIE) From 949405cdcbc6fc89506022b301019773b34220aa Mon Sep 17 00:00:00 2001 From: Darius <5933805+LeDrascol@users.noreply.github.com> Date: Tue, 14 Feb 2023 12:52:28 -0500 Subject: [PATCH 4/6] Add quirk blacklist entries for zombie quirk Adds blacklisted quirk entries for Postmortem Flesh to prevent mechanical conflicts and potential exploits. --- .../subsystem/processing/quirks.dm | 28 +++++++++++++++++++ tgstation.dme | 1 + 2 files changed, 29 insertions(+) create mode 100644 modular_splurt/code/controllers/subsystem/processing/quirks.dm diff --git a/modular_splurt/code/controllers/subsystem/processing/quirks.dm b/modular_splurt/code/controllers/subsystem/processing/quirks.dm new file mode 100644 index 000000000000..e32519d33b1c --- /dev/null +++ b/modular_splurt/code/controllers/subsystem/processing/quirks.dm @@ -0,0 +1,28 @@ +// Add incompatible quirks +/datum/controller/subsystem/processing/quirks/Initialize(timeofday) + . = ..() + + // Prevent incompatible quirks + LAZYADD(quirk_blacklist, list( + // BLOCKED: Mechanic + // Zombies can't regenerate blood + list("Postmortem Flesh","Polycythemia vera"), + + // BLOCKED: Mechanic + // Zombies are slower and clumsier + list("Postmortem Flesh","Freerunning"), + list("Postmortem Flesh","Light Step"), + list("Postmortem Flesh","Quick Step"), + + // BLOCKED: Mechanic + // Zombies can't evaluate wounds properly + list("Postmortem Flesh","Self-Aware"), + + // BLOCKED: Mechanic + // Zombies are already cold blooded + list("Postmortem Flesh","Cold-blooded"), + + // BLOCKED: Mechanic + // Zombies already can't be cloned + list("Postmortem Flesh","DNC Order"), + )) diff --git a/tgstation.dme b/tgstation.dme index dc0810790796..b895b0555294 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4302,6 +4302,7 @@ #include "modular_splurt\code\controllers\subsystem\redbot.dm" #include "modular_splurt\code\controllers\subsystem\ticker.dm" #include "modular_splurt\code\controllers\subsystem\processing\station.dm" +#include "modular_splurt\code\controllers\subsystem\processing\quirks.dm" #include "modular_splurt\code\datums\ai_laws.dm" #include "modular_splurt\code\datums\bark.dm" #include "modular_splurt\code\datums\dna.dm" From bbcb06af67840ca181347cc78b58ed2100938ce4 Mon Sep 17 00:00:00 2001 From: Darius <5933805+LeDrascol@users.noreply.github.com> Date: Tue, 14 Feb 2023 13:20:23 -0500 Subject: [PATCH 5/6] Zombie quirk balance improvements This commit does the following - Adds a 60 tick cooldown to regeneration - - Reduced by half during halloween - Adds support for on-demand quirk processing - Increases quirk cost from 0 to 2 - Increases halloween regeneration bonus from 2x to 3x - Reduces regeneration rate from 3 to 2 --- modular_splurt/code/datums/traits/neutral.dm | 40 +++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/modular_splurt/code/datums/traits/neutral.dm b/modular_splurt/code/datums/traits/neutral.dm index b7ba75e637dc..0f320c4decc0 100644 --- a/modular_splurt/code/datums/traits/neutral.dm +++ b/modular_splurt/code/datums/traits/neutral.dm @@ -682,15 +682,21 @@ /datum/quirk/zombie name = "Postmortem Flesh" desc = "You've been freed from the mortal coil, and passed on to become a zombie! Your body rapidly regenerates, and can't be put into critical condition. However, you won't be able to cheat death a second time..." - value = 0 + value = 2 medical_record_text = "Scans indicate the patient to be deceased." mob_trait = TRAIT_UNDEAD_QUIRK gain_text = span_notice("Your flesh rots and burns as it clings to life.") lose_text = span_warning("The mortal coil binds you once again.") - processing_quirk = TRUE + processing_quirk = FALSE // Don't process by default // Amount of damage to heal - var/regen_amount = -3 + var/regen_amount = -2 + + // Time in ticks after taking damage before regenerating + var/regen_delay = 60 + + // Cooldown before regeneration can occur + var/regen_cooldown /datum/quirk/zombie/add() // Define quirk mob @@ -708,11 +714,14 @@ // Check for halloween if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) - // Add holiday traits + // Prevent dying by traditional means ADD_TRAIT(quirk_mob, TRAIT_NODEATH,TRAIT_UNDEAD_QUIRK) // Double regeneration rate - regen_amount *= 2 + regen_amount *= 3 + + // Half cooldown time + regen_delay *= 0.5 // Not halloween else @@ -725,6 +734,9 @@ // Set screwy health HUD quirk_mob.set_screwyhud(SCREWYHUD_HEALTHY) + // Add register signal for taking damage + RegisterSignal(quirk_holder, COMSIG_MOB_APPLY_DAMAGE, .proc/set_damage_cooldown, TRUE) + /datum/quirk/zombie/post_add() // Check for halloween if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) @@ -784,12 +796,21 @@ // Remove screwy health HUD quirk_mob.set_screwyhud(SCREWYHUD_NONE) + // Remove signal for taking damage + UnregisterSignal(quirk_holder, COMSIG_MOB_APPLY_DAMAGE) + /datum/quirk/zombie/on_process() + // Check cooldown time + if(regen_cooldown > world.time) + return + // Define quirk mob var/mob/living/carbon/human/quirk_mob = quirk_holder // Check if quick holder is damaged if(quirk_mob.health >= quirk_mob.maxHealth) + // Stop processing and return + STOP_PROCESSING(SSquirks, src) return // Check for sufficient blood @@ -822,3 +843,12 @@ // Remove blood as compensation for healing // Value is determined by amount healed quirk_mob.blood_volume -= (quirk_mob.health - health_start) + +/datum/quirk/zombie/proc/set_damage_cooldown() + SIGNAL_HANDLER + + // Set cooldown time + regen_cooldown = world.time + regen_delay + + // Start processing + START_PROCESSING(SSquirks, src) From f97351f04871dc1aad226ad0f0c8ea08cd459b1b Mon Sep 17 00:00:00 2001 From: Darius <5933805+LeDrascol@users.noreply.github.com> Date: Tue, 14 Feb 2023 13:37:49 -0500 Subject: [PATCH 6/6] Make zombies cold blooded Fixes an oversight where the cold blooded trait was not being applied to zombie quirk users. --- modular_splurt/code/datums/traits/neutral.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modular_splurt/code/datums/traits/neutral.dm b/modular_splurt/code/datums/traits/neutral.dm index 0f320c4decc0..7895271b1af5 100644 --- a/modular_splurt/code/datums/traits/neutral.dm +++ b/modular_splurt/code/datums/traits/neutral.dm @@ -711,6 +711,7 @@ ADD_TRAIT(quirk_mob,TRAIT_NOHARDCRIT,TRAIT_UNDEAD_QUIRK) ADD_TRAIT(quirk_mob,TRAIT_NOCLONE,TRAIT_UNDEAD_QUIRK) ADD_TRAIT(quirk_mob,TRAIT_NOMARROW,TRAIT_UNDEAD_QUIRK) + ADD_TRAIT(quirk_mob,TRAIT_COLDBLOODED,TRAIT_UNDEAD_QUIRK) // Check for halloween if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) @@ -786,6 +787,7 @@ REMOVE_TRAIT(quirk_mob,TRAIT_NOMARROW,TRAIT_UNDEAD_QUIRK) REMOVE_TRAIT(quirk_mob,TRAIT_NOCLONE,TRAIT_UNDEAD_QUIRK) REMOVE_TRAIT(quirk_mob,TRAIT_NODEATH,TRAIT_UNDEAD_QUIRK) + REMOVE_TRAIT(quirk_mob,TRAIT_COLDBLOODED,TRAIT_UNDEAD_QUIRK) // Remove undead biotype quirk_mob.mob_biotypes -= MOB_UNDEAD