diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm
index bc8b8236032..1bd6dc7f34e 100644
--- a/code/__DEFINES/genetics.dm
+++ b/code/__DEFINES/genetics.dm
@@ -22,9 +22,6 @@
///////////////////////////////////////
// MUTATIONS
///////////////////////////////////////
-
-#define CHECK_DNA_AND_SPECIES(C) if((!(C.dna)) || (!(C.dna.species))) return
-
// Generic mutations:
#define TK 1
#define COLDRES 2
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 7c358ba951d..66a6748a683 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -65,7 +65,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
/datum/objective/assassinate/check_completion()
if(target && target.current)
- if(target.current.stat == DEAD)
+ if(target.current.stat == DEAD || iszombie(target))
return 1
if(issilicon(target.current) || isbrain(target.current)) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
return 1
@@ -109,7 +109,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
/datum/objective/maroon/check_completion()
if(target && target.current)
- if(target.current.stat == DEAD)
+ if(target.current.stat == DEAD || iszombie(target))
return 1
if(!target.current.ckey)
return 1
@@ -166,7 +166,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
if(!target) //If it's a free objective.
return 1
if(target.current)
- if(target.current.stat == DEAD)
+ if(target.current.stat == DEAD || iszombie(target))
return 0
if(issilicon(target.current))
return 0
@@ -261,7 +261,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
return 0
if(isbrain(owner.current))
return 0
- if(!owner.current || owner.current.stat == DEAD)
+ if(!owner.current || owner.current.stat == DEAD || iszombie(owner))
return 0
if(SSticker.force_ending) //This one isn't their fault, so lets just assume good faith
return 1
@@ -316,7 +316,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
explanation_text = "Die a glorious death."
/datum/objective/die/check_completion()
- if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current))
+ if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current) || iszombie(owner))
return 1
if(issilicon(owner.current) && owner.current != owner.original)
return 1
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index 25b188911ad..dcb328c8264 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -757,6 +757,15 @@
desc = "Bark bark bark."
key = "vu"
+/datum/language/com_srus
+ name = "Zombie"
+ desc = "BRAAAAAAINS!"
+ speech_verb = "moans"
+ whisper_verb = "mutters"
+ exclaim_verb = "wails"
+ colour = "zombie"
+ key = "zom"
+ syllables = list("BRAAAAAAAAAAAAAAAAINS", "BRAAINS", "BRAINS")
#undef SCRAMBLE_CACHE_LEN
diff --git a/code/modules/mob/living/carbon/human/species/zombies.dm b/code/modules/mob/living/carbon/human/species/zombies.dm
index 9fa6cf37de2..f11c3a7fbd3 100644
--- a/code/modules/mob/living/carbon/human/species/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species/zombies.dm
@@ -11,15 +11,32 @@
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
warning_low_pressure = 50
hazard_low_pressure = 0
+ has_organ = list(
+ "heart" = /obj/item/organ/internal/heart,
+ "lungs" = /obj/item/organ/internal/lungs,
+ "liver" = /obj/item/organ/internal/liver,
+ "kidneys" = /obj/item/organ/internal/kidneys,
+ "brain" = /obj/item/organ/internal/brain,
+ "appendix" = /obj/item/organ/internal/appendix,
+ "eyes" = /obj/item/organ/internal/eyes,
+ "ears" = /obj/item/organ/internal/ears,
+ "zombie_infection" = /obj/item/organ/internal/zombie_infection)
+
/datum/species/zombie/infectious
name = "Infectious Zombie"
mutanthands = /obj/item/zombie_hand
armor = 20 // 120 damage to KO a zombie, which kills it
speedmod = 1.6
+ default_language = "Zombie"
+ language = "Zombie"
var/heal_rate = 1
var/regen_cooldown = 0
+/datum/species/zombie/infectious/handle_dna(mob/living/carbon/human/H, remove)
+ H.mutations.Add(HUSK)
+ . = ..()
+
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
. = min(20, amount)
@@ -29,14 +46,12 @@
/datum/species/zombie/infectious/handle_life(mob/living/carbon/human/C)
. = ..()
- C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
-
//Zombies never actually die, they just fall down until they regenerate enough to rise back up.
//They must be restrained, beheaded or gibbed to stop being a threat.
if(regen_cooldown < world.time)
var/heal_amt = heal_rate
if(C.InCritical())
- heal_amt *= 2
+ heal_amt *= 5
C.heal_overall_damage(heal_amt,heal_amt)
C.adjustToxLoss(-heal_amt)
if(!C.InCritical() && prob(4))
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index b796e3d8a7d..8aa63f0a130 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -175,7 +175,7 @@
/obj/docking_port/mobile/emergency/proc/is_hijacked()
for(var/mob/living/player in GLOB.player_list)
if(player.mind)
- if(player.stat != DEAD)
+ if(player.stat != DEAD || !iszombie(player))
if(issilicon(player)) //Borgs are technically dead anyways
continue
if(isanimal(player)) //Poly does not own the shuttle
diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm
index bda4eeba2c6..90bd16e53b0 100644
--- a/code/modules/zombie/items.dm
+++ b/code/modules/zombie/items.dm
@@ -1,7 +1,7 @@
/obj/item/zombie_hand
name = "zombie claw"
desc = "A zombie's claw is its primary tool, capable of infecting \
- unconcious or dead humans, butchering all other living things to \
+ unconscious or dead humans, butchering all other living things to \
sustain the zombie, forcing open airlock doors and opening \
child-safe caps on bottles."
flags = NODROP|ABSTRACT
@@ -9,7 +9,6 @@
icon_state = "bloodhand_left"
var/icon_left = "bloodhand_left"
var/icon_right = "bloodhand_right"
- //hitsound = 'sound/hallucinations/growl1.ogg'
force = 25
damtype = "brute"
@@ -43,7 +42,6 @@
check_feast(target, user)
/obj/item/zombie_hand/proc/check_infection(var/mob/living/carbon/human/target, var/mob/user)
- CHECK_DNA_AND_SPECIES(target)
var/mob/living/carbon/human/T = target
if(NOZOMBIE in T.dna.species.species_traits)
// cannot infect any NOZOMBIE subspecies (such as high functioning
diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm
index bed6f646200..07c97e4162a 100644
--- a/code/modules/zombie/organs.dm
+++ b/code/modules/zombie/organs.dm
@@ -2,20 +2,21 @@
/obj/item/organ/internal/zombie_infection
name = "festering ooze"
- desc = "A black web of pus and vicera."
+ desc = "A black web of pus and viscera."
parent_organ = "head"
slot = "zombie_infection"
icon_state = "blacktumor"
var/causes_damage = TRUE
var/reanimation_timer
- var/datum/species/old_species = /datum/species/human
+ var/datum/species/old_species = new /datum/species/human
var/living_transformation_time = 5
var/converts_living = FALSE
/obj/item/organ/internal/zombie_infection/New()
. = ..()
- if(iscarbon(loc))
- insert(loc)
+ if(ishuman(owner) && !ismachine(owner))
+ old_species = owner.dna.species
+ insert(owner)
GLOB.zombie_infection_list += src
/obj/item/organ/internal/zombie_infection/Destroy()
@@ -27,14 +28,14 @@
START_PROCESSING(SSobj, src)
/obj/item/organ/internal/zombie_infection/remove(mob/living/carbon/human/M, special = 0)
- . = ..()
STOP_PROCESSING(SSobj, src)
if(iszombie(M) && old_species)
M.set_species(old_species)
+ ..()
/obj/item/organ/internal/zombie_infection/on_find(mob/living/finder)
to_chat(finder,"Inside the head is a disgusting black \
- web of pus and vicera, bound tightly around the brain like some \
+ web of pus and viscera, bound tightly around the brain like some \
biological harness.")
/obj/item/organ/internal/zombie_infection/process()
@@ -50,7 +51,12 @@
if (prob(10))
to_chat(owner, "You feel sick...")
if(!owner.get_int_organ(/obj/item/organ/internal/brain))
- return
+ return
+ if(!iszombie(owner) && !reanimation_timer)
+ to_chat(owner, "You can feel your heart stopping, but something isn't right... \
+ life has not abandoned your broken form. You can only feel a deep and immutable hunger that \
+ not even death can stop, you will rise again!")
+ START_TIMER
else if(reanimation_timer && (reanimation_timer < world.time))
zombify() // Rise and shine, Mr Romero... rise and shine.
reanimation_timer = null
@@ -61,25 +67,24 @@
/obj/item/organ/internal/zombie_infection/remove(mob/living/carbon/human/M, special = 0)
. = ..()
- CHECK_DNA_AND_SPECIES(M)
if(iszombie(M) && old_species)
M.set_species(old_species)
/obj/item/organ/internal/zombie_infection/proc/zombify()
- CHECK_DNA_AND_SPECIES(owner)
var/datum/species/zombie = /datum/species/zombie/infectious
if(!iszombie(owner))
old_species = owner.dna.species
owner.set_species(zombie)
//Fully heal the zombie's damage the first time they rise
- owner.setToxLoss(0, 0)
- owner.setOxyLoss(0, 0)
- owner.heal_overall_damage(INFINITY, INFINITY, INFINITY, null, TRUE)
-
- if(!owner.revive())
- return
-
- owner.grab_ghost()
+ owner.setToxLoss(0, 1)
+ owner.setOxyLoss(0, 1)
+ owner.setBrainLoss(0, 1)
+ owner.setCloneLoss(0,1)
+ owner.heal_overall_damage(INFINITY,INFINITY,TRUE,TRUE,FALSE)
+ owner.updatehealth()
+ owner.grab_ghost(TRUE)
+ owner.update_revive()
+ owner.ChangeToHusk()
owner.visible_message("[owner] suddenly convulses, as [owner.p_they()] stagger to [owner.p_their()] feet and gain a ravenous hunger in [owner.p_their()] eyes!", "You HUNGER!")
playsound(owner.loc, 'sound/hallucinations/far_noise.ogg', 50, 1)
to_chat(owner, "You are now a zombie!")
diff --git a/goon/browserassets/css/browserOutput-dark.css b/goon/browserassets/css/browserOutput-dark.css
index fed5a252ba3..3ee14b2a4d4 100644
--- a/goon/browserassets/css/browserOutput-dark.css
+++ b/goon/browserassets/css/browserOutput-dark.css
@@ -335,6 +335,7 @@ h1.alert, h2.alert {color: #FFF;}
.skrell {color: #00CED1;}
.solcom {color: #8282FB;}
.com_srus {color: #7c4848;}
+.zombie {color: #ff0000;}
.soghun {color: #228B22;}
.changeling {color: #800080;}
.vox {color: #AA00AA;}
@@ -388,7 +389,6 @@ h1.alert, h2.alert {color: #FFF;}
.whisper {font-style:italic;color:#CCCCCC;}
/* Recruiting stuff */
.recruit {color: #5c00e6; font-weight: bold; font-style: italic;}
-"}
.memo {color: #638500; text-align: center;}
.memoedit {text-align: center; font-size: 75%;}
diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css
index 1af8b03bd58..b664c1e9752 100644
--- a/goon/browserassets/css/browserOutput.css
+++ b/goon/browserassets/css/browserOutput.css
@@ -332,6 +332,7 @@ h1.alert, h2.alert {color: #000000;}
.skrell {color: #00CED1;}
.solcom {color: #22228B;}
.com_srus {color: #7c4848;}
+.zombie {color: #ff0000;}
.soghun {color: #228B22;}
.changeling {color: #800080;}
.vox {color: #AA00AA;}
@@ -385,7 +386,6 @@ h1.alert, h2.alert {color: #000000;}
.whisper {font-style:italic;color:#333333;}
/* Recruiting stuff */
.recruit {color: #5c00e6; font-weight: bold; font-style: italic;}
-"}
.memo {color: #638500; text-align: center;}
.memoedit {text-align: center; font-size: 75%;}