adds spawners for NPC zombies (#25873)

* lmao

* lol

* yes

* yeah sure

* fix

* Apply suggestions from code review

Co-authored-by: 1080pCat <96908085+1080pCat@users.noreply.github.com>
Signed-off-by: Contrabang <91113370+Contrabang@users.noreply.github.com>

* lewc review + duplicate

---------

Signed-off-by: Contrabang <91113370+Contrabang@users.noreply.github.com>
Co-authored-by: 1080pCat <96908085+1080pCat@users.noreply.github.com>
This commit is contained in:
Contrabang
2024-06-20 11:38:23 +00:00
committed by GitHub
co-authored by 1080pCat
parent 2ef31cc6e4
commit 18b0b09778
8 changed files with 61 additions and 26 deletions
+2
View File
@@ -231,6 +231,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_CAN_STRIP "can_strip" // This mob can strip other mobs.
#define TRAIT_CLING_BURSTING "cling_bursting" // This changeling is about to burst into a headslug, block cremation / gibber to prevent nullspace issues
#define TRAIT_I_WANT_BRAINS "mob_zombie" // A general trait for tracking if the mob is a zombie.
#define TRAIT_NON_INFECTIOUS_ZOMBIE "non_infectious_zombie" // A trait for checking if a zombie shouldn't be able to infect other people
#define TRAIT_NPC_ZOMBIE "npc_zombie" // A trait for checking if a zombie should act like an NPC and attack
#define TRAIT_ABSTRACT_HANDS "abstract_hands" // Mobs with this trait can only pick up abstract items.
#define TRAIT_LANGUAGE_LOCKED "language_locked" // cant add/remove languages until removed (excludes babel because fuck everything i guess)
#define TRAIT_HAS_IV_BAG "iv_bag" // Used to check if there is an active IV bag. Currently blocks another IV bags from being inserted.
+2 -1
View File
@@ -96,7 +96,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_I_WANT_BRAINS" = TRAIT_I_WANT_BRAINS,
"TRAIT_ABSTRACT_HANDS" = TRAIT_ABSTRACT_HANDS,
"TRAIT_LANGUAGE_LOCKED" = TRAIT_LANGUAGE_LOCKED,
"TRAIT_HAS_IV_BAG" = TRAIT_HAS_IV_BAG
"TRAIT_HAS_IV_BAG" = TRAIT_HAS_IV_BAG,
"TRAIT_NON_INFECTIOUS_ZOMBIE" = TRAIT_NON_INFECTIOUS_ZOMBIE
),
/datum/mind = list(
+1 -1
View File
@@ -36,7 +36,7 @@
return
if(zomboid.client || isLivingSSD(zomboid))
return
if(zomboid.last_known_ckey && !zomboid.key) // make sure they were player inhabited and not admin ghosted
if((zomboid.last_known_ckey || HAS_TRAIT(zomboid, TRAIT_NPC_ZOMBIE)) && !zomboid.key) // make sure they were player inhabited and not admin ghosted
mindless_hunger()
/datum/component/zombie_regen/proc/zombie_rejuv()
@@ -40,14 +40,7 @@
/obj/item/dnascrambler/proc/injected(mob/living/carbon/human/target, mob/living/carbon/user)
if(istype(target))
var/mob/living/carbon/human/H = target
scramble(1, H, 100)
H.real_name = random_name(H.gender, H.dna.species.name) //Give them a name that makes sense for their species.
H.sync_organ_dna(assimilate = 1)
H.update_body()
H.reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover.
H.reset_markings() //...Or markings.
H.dna.ResetUIFrom(H)
H.flavor_text = ""
H.get_dna_scrambled()
target.update_icons()
add_attack_logs(user, target, "injected with [src]")
@@ -128,7 +128,7 @@
/obj/item/zombie_claw/proc/try_infect(mob/living/carbon/human/target, mob/living/user)
if(!ishuman(target))
if(!ishuman(target) || HAS_TRAIT(user, TRAIT_NON_INFECTIOUS_ZOMBIE))
return
if(!(user.zone_selected in list(BODY_ZONE_CHEST, BODY_ZONE_HEAD)))
to_chat(user, "<span class='warning zombie'>Our infection cannot spread without their head or chest.</span>")
+27
View File
@@ -183,6 +183,8 @@
assignedrole = "Ghost Role"
var/husk = null
/// Should we fully dna-scramble these humans?
var/dna_scrambled = FALSE
//these vars are for lazy mappers to override parts of the outfit
//these cannot be null by default, or mappers cannot set them to null if they want nothing in that slot
var/uniform = -1
@@ -259,6 +261,9 @@
H.s_tone = random_skin_tone()
H.skin_colour = rand_hex_color()
if(dna_scrambled)
H.get_dna_scrambled()
H.update_body(rebuild_base = TRUE)
if(outfit)
@@ -581,6 +586,28 @@
mob_species = /datum/species/skeleton/brittle
mob_gender = NEUTER
/obj/effect/mob_spawn/human/alive/zombie
name = "NPC Zombie (Infectious)"
icon = 'icons/mob/human.dmi'
icon_state = "zombie_s"
roundstart = TRUE
dna_scrambled = TRUE
/obj/effect/mob_spawn/human/alive/zombie/equip(mob/living/carbon/human/H)
ADD_TRAIT(H, TRAIT_NPC_ZOMBIE, ROUNDSTART_TRAIT)
H.ForceContractDisease(new /datum/disease/zombie)
for(var/datum/disease/zombie/zomb in H.viruses)
zomb.stage = 8
return ..()
/obj/effect/mob_spawn/human/alive/zombie/non_infectious
name = "NPC Zombie (Non-infectious)"
/obj/effect/mob_spawn/human/alive/zombie/non_infectious/equip(mob/living/carbon/human/H)
ADD_TRAIT(H, TRAIT_NON_INFECTIOUS_ZOMBIE, ROUNDSTART_TRAIT)
return ..()
////////Non-human spawners////////
/obj/effect/mob_spawn/mouse
@@ -2046,3 +2046,13 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
return dna.species.unarmed
return zombie.claw_attack
/mob/living/carbon/human/proc/get_dna_scrambled()
scramble(1, src, 100)
real_name = random_name(gender, dna.species.name) // Give them a name that makes sense for their species.
sync_organ_dna(assimilate = 1)
update_body()
reset_hair() // No more winding up with hairstyles you're not supposed to have, and blowing your cover.
reset_markings() // ...Or markings.
dna.ResetUIFrom(src)
flavor_text = ""
@@ -1087,17 +1087,18 @@ It'll return null if the organ doesn't correspond, so include null checks when u
playsound(user.loc, 'sound/misc/moist_impact.ogg', 50, TRUE)
user.do_attack_animation(target, ATTACK_EFFECT_BITE)
target.apply_damage(20, BRUTE, user.zone_selected)
if(!target.HasDisease(/datum/disease/zombie))
var/datum/disease/zombie/zomb = new /datum/disease/zombie
if(target.CanContractDisease(zomb)) // biosuit aint going to protect you buddy
target.ForceContractDisease(zomb)
target.Dizzy(10 SECONDS)
target.Confused(10 SECONDS)
else
qdel(zomb)
if(!HAS_TRAIT(user, TRAIT_NON_INFECTIOUS_ZOMBIE))
if(!target.HasDisease(/datum/disease/zombie))
var/datum/disease/zombie/zomb = new /datum/disease/zombie
if(target.CanContractDisease(zomb)) // biosuit aint going to protect you buddy
target.ForceContractDisease(zomb)
target.Dizzy(10 SECONDS)
target.Confused(10 SECONDS)
else
qdel(zomb)
for(var/datum/disease/zombie/zomb in target.viruses)
zomb.stage = max(rand(3, 4), zomb.stage)
for(var/datum/disease/zombie/zomb in target.viruses)
zomb.stage = max(rand(3, 4), zomb.stage)
qdel(grabby)
return TRUE
@@ -1126,12 +1127,13 @@ It'll return null if the organ doesn't correspond, so include null checks when u
eat_brain.custom_pain("OH GOD!!! THEY'RE EATING MY [uppertext(eat_brain.name)]!!") // gnarly
user.visible_message("<span class='danger'>[user] digs their claws into [target]'s [brain_house.name], eating their [eat_brain]!</span>", "<span class='danger zombie'>We feast on [target]'s brains.</span>")
if(!target.HasDisease(/datum/disease/zombie))
var/datum/disease/zombie/zomb = new /datum/disease/zombie
target.ContractDisease(zomb)
if(!HAS_TRAIT(user, TRAIT_NON_INFECTIOUS_ZOMBIE))
if(!target.HasDisease(/datum/disease/zombie))
var/datum/disease/zombie/zomb = new /datum/disease/zombie
target.ContractDisease(zomb)
for(var/datum/disease/zombie/zomb in target.viruses)
zomb.stage = max(5, zomb.stage)
for(var/datum/disease/zombie/zomb in target.viruses)
zomb.stage = max(5, zomb.stage)
if(!do_mob(user, target, 1 SECONDS))
return