diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index 2a25c9f0a48..e2d6a191b36 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -325,3 +325,9 @@
for(var/i in 1 to 3)
new/obj/item/cardboard_cutout/adaptive(src)
new/obj/item/toy/crayon/rainbow(src)
+
+/obj/item/weapon/storage/box/syndie_kit/romerol/New()
+ ..()
+ new /obj/item/weapon/reagent_containers/glass/bottle/romerol(src)
+ new /obj/item/weapon/reagent_containers/syringe(src)
+ new /obj/item/weapon/reagent_containers/dropper(src)
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 8a2612c7d56..530f249c23e 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1010,7 +1010,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
return
for(var/mob/living/carbon/human/H in mob_list)
- new /obj/item/organ/body_egg/zombie_infection(H)
+ new /obj/item/organ/zombie_infection(H)
message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.")
log_admin("[key_name(usr)] added a latent zombie infection to all humans.")
@@ -1027,7 +1027,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
if(confirm != "Yes")
return
- for(var/obj/item/organ/body_egg/zombie_infection/I in zombie_infection_list)
+ for(var/obj/item/organ/zombie_infection/I in zombie_infection_list)
qdel(I)
message_admins("[key_name_admin(usr)] cured all zombies.")
@@ -1169,4 +1169,4 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
if (world.visibility && !world.reachable)
message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.")
- feedback_add_details("admin_verb","HUB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
\ No newline at end of file
+ feedback_add_details("admin_verb","HUB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 0a6f818669c..f4fd85f5eb5 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -6,7 +6,7 @@
sexes = 0
blacklisted = 1
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
- species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT,TOXINLOVER)
+ species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT)
mutant_organs = list(/obj/item/organ/tongue/zombie)
/datum/species/zombie/infectious
@@ -40,7 +40,7 @@
C.put_in_hands(zh)
// Next, deal with the source of this zombie corruption
- var/obj/item/organ/body_egg/zombie_infection/infection
+ var/obj/item/organ/zombie_infection/infection
infection = C.getorganslot("zombie_infection")
if(!infection)
infection = new(C)
@@ -59,4 +59,4 @@
limbs_id = "zombie" //They look like zombies
sexes = 0
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
- mutant_organs = list(/obj/item/organ/tongue/zombie)
\ No newline at end of file
+ mutant_organs = list(/obj/item/organ/tongue/zombie)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 5548290f907..f27d8ec5077 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -1365,7 +1365,7 @@
//Misc reagents
/datum/reagent/romerol
- name = "romerol"
+ name = "Romerol"
// the REAL zombie powder
id = "romerol"
description = "Romerol is a highly experimental bioterror agent \
@@ -1379,11 +1379,11 @@
/datum/reagent/romerol/on_mob_life(mob/living/carbon/human/H)
// Silently add the zombie infection organ to be activated upon death
- new /obj/item/organ/body_egg/zombie_infection(H)
+ new /obj/item/organ/zombie_infection(H)
..()
/datum/reagent/growthserum
- name = "Growth serum"
+ name = "Growth Serum"
id = "growthserum"
description = "A commercial chemical designed to help older men in the bedroom."//not really it just makes you a giant
color = "#ff0000"//strong red. rgb 255, 0, 0
diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm
index 61bd6b78ff6..9a142be07f0 100644
--- a/code/modules/reagents/reagent_containers/bottle.dm
+++ b/code/modules/reagents/reagent_containers/bottle.dm
@@ -234,6 +234,12 @@
icon_state = "bottle12"
list_reagents = list("atropine" = 30)
+/obj/item/weapon/reagent_containers/glass/bottle/romerol
+ name = "romerol bottle"
+ desc = "A small bottle of Romerol. The REAL zombie powder."
+ icon_state = "bottle12"
+ list_reagents = list("romerol" = 30)
+
/obj/item/weapon/reagent_containers/glass/bottle/flu_virion
name = "Flu virion culture bottle"
desc = "A small bottle. Contains H13N1 flu virion culture in synthblood medium."
diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_item.dm
index 9c39d0dc7e7..2c15ad8a299 100644
--- a/code/modules/uplink/uplink_item.dm
+++ b/code/modules/uplink/uplink_item.dm
@@ -632,6 +632,13 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
cost = 6
surplus = 50
+/datum/uplink_item/stealthy_weapons/romerol_kit
+ name = "Romerol"
+ desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. On death, these nodules take control of the dead body, causing limited revivification, along with slurred speech, aggression, and the ability to infect others with this agent."
+ item = /obj/item/weapon/storage/box/syndie_kit/romerol
+ cost = 25
+ exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/gang)
+
/datum/uplink_item/stealthy_weapons/dart_pistol
name = "Dart Pistol"
desc = "A miniaturized version of a normal syringe gun. It is very quiet when fired and can fit into any \
diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm
index 6af6c12fcd2..3bbecd08f6d 100644
--- a/code/modules/zombie/items.dm
+++ b/code/modules/zombie/items.dm
@@ -1,8 +1,8 @@
/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 \
- sustain the zombie, forcing open airlock doors and opening \
+ humans, butchering all other living things to \
+ sustain the zombie, smashing open airlock doors and opening \
child-safe caps on bottles."
flags = NODROP|ABSTRACT|DROPDEL
icon = 'icons/effects/blood.dmi'
@@ -28,9 +28,6 @@
. = ..()
if(!proximity_flag)
return
- if(istype(target, /obj/machinery/door/airlock) && !removing_airlock)
- tear_airlock(target, user)
-
else if(isliving(target))
if(ishuman(target))
check_infection(target, user)
@@ -45,7 +42,7 @@
// zombies)
return
- var/obj/item/organ/body_egg/zombie_infection/infection
+ var/obj/item/organ/zombie_infection/infection
infection = target.getorganslot("zombie_infection")
if(!infection)
infection = new(target)
@@ -54,48 +51,11 @@
if(target.stat == DEAD)
var/hp_gained = target.maxHealth
target.gib()
- user.adjustBruteLoss(-hp_gained)
- user.adjustToxLoss(-hp_gained)
- user.adjustFireLoss(-hp_gained)
- user.adjustCloneLoss(-hp_gained)
+ // zero as argument for no instant health update
+ user.adjustBruteLoss(-hp_gained, 0)
+ user.adjustToxLoss(-hp_gained, 0)
+ user.adjustFireLoss(-hp_gained, 0)
+ user.adjustCloneLoss(-hp_gained, 0)
+ user.updatehealth()
user.adjustBrainLoss(-hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!"
-
-/obj/item/zombie_hand/proc/tear_airlock(obj/machinery/door/airlock/A, mob/user)
- removing_airlock = TRUE
- user << "You start tearing apart the airlock..."
-
- playsound(src.loc, 'sound/machines/airlock_alien_prying.ogg', 100, 1)
- A.audible_message("You hear a loud metallic grinding sound.")
-
- addtimer(CALLBACK(src, .proc/growl, user), 20)
-
- if(do_after(user, delay=160, needhand=FALSE, target=A, progress=TRUE))
- playsound(src.loc, 'sound/hallucinations/far_noise.ogg', 50, 1)
- A.audible_message("With a screech, [A] is torn apart!")
- var/obj/structure/door_assembly/door = new A.assemblytype(get_turf(A))
- door.density = 0
- door.anchored = 1
- door.name = "ravaged [door]"
- door.desc = "An airlock that has been torn apart. Looks like it won't be keeping much out now."
- qdel(A)
- removing_airlock = FALSE
-
-/obj/item/zombie_hand/proc/growl(mob/user)
- if(removing_airlock)
- playsound(src.loc, 'sound/hallucinations/growl3.ogg', 50, 1)
- user.audible_message("[user] growls as [user.p_their()] claws dig into the metal frame...")
-
-/obj/item/zombie_hand/suicide_act(mob/living/carbon/user)
- // Suiciding as a zombie brings someone else in to play it
- user.visible_message("[user] is lying down.")
- if(!istype(user))
- return
-
- user.Weaken(30)
- var/success = offer_control(user)
- if(success)
- user.visible_message("[user] appears to have found new spirit.")
- return SHAME
- else
- user.visible_message("[user] stops moving.")
- return OXYLOSS
+ user.nutrition = min(user.nutrition + hp_gained, NUTRITION_LEVEL_FULL)
diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm
index c477af9bc64..0e2bd497ba5 100644
--- a/code/modules/zombie/organs.dm
+++ b/code/modules/zombie/organs.dm
@@ -1,67 +1,75 @@
-#define START_TIMER reanimation_timer = world.time + rand(600,1200)
-
-/obj/item/organ/body_egg/zombie_infection
+/obj/item/organ/zombie_infection
name = "festering ooze"
desc = "A black web of pus and vicera."
zone = "head"
slot = "zombie_infection"
- var/reanimation_timer
+ origin_tech = "biotech=5"
var/datum/species/old_species
var/living_transformation_time = 5
var/converts_living = FALSE
-/obj/item/organ/body_egg/zombie_infection/New()
+ var/revive_time_min = 600
+ var/revive_time_max = 1200
+ var/timer_id
+
+/obj/item/organ/zombie_infection/New(loc)
. = ..()
+ if(iscarbon(loc))
+ Insert(loc)
zombie_infection_list += src
-/obj/item/organ/body_egg/zombie_infection/Destroy()
+/obj/item/organ/zombie_infection/Destroy()
zombie_infection_list -= src
. = ..()
-/obj/item/organ/body_egg/zombie_infection/on_find(mob/living/finder)
+/obj/item/organ/zombie_infection/Insert(var/mob/living/carbon/M, special = 0)
+ . = ..()
+ START_PROCESSING(SSobj, src)
+
+/obj/item/organ/zombie_infection/Remove(mob/living/carbon/M, special = 0)
+ . = ..()
+ STOP_PROCESSING(SSobj, src)
+ if(iszombie(M) && old_species)
+ M.set_species(old_species)
+ if(timer_id)
+ deltimer(timer_id)
+
+/obj/item/organ/zombie_infection/on_find(mob/living/finder)
finder << "Inside the head is a disgusting black \
web of pus and vicera, bound tightly around the brain like some \
biological harness."
-/obj/item/organ/body_egg/zombie_infection/egg_process()
- if(!ishuman(owner)) // We do not support monkey or xeno zombies. Yet.
- qdel(src)
+/obj/item/organ/zombie_infection/process()
+ if(!owner)
return
- else if(reanimation_timer && (reanimation_timer < world.time))
- zombify() // Rise and shine, Mr Romero... rise and shine.
- reanimation_timer = null
- else if(owner.stat == DEAD && (!reanimation_timer))
- START_TIMER
- else if(converts_living && !iszombie(owner) && !reanimation_timer)
- START_TIMER
+ if(!(src in owner.internal_organs))
+ Remove(owner)
-/obj/item/organ/body_egg/zombie_infection/Remove(mob/living/carbon/M, special = 0)
- . = ..()
- CHECK_DNA_AND_SPECIES(M)
- if(iszombie(M) && old_species)
- M.set_species(old_species)
+ if(timer_id)
+ return
+ if(owner.stat != DEAD && !converts_living)
+ return
+
+ var/revive_time = rand(revive_time_min, revive_time_max)
+ var/flags = TIMER_STOPPABLE
+ timer_id = addtimer(CALLBACK(src, .proc/zombify), revive_time, flags)
+
+/obj/item/organ/zombie_infection/proc/zombify()
+ timer_id = null
-/obj/item/organ/body_egg/zombie_infection/proc/zombify()
- CHECK_DNA_AND_SPECIES(owner)
if(!iszombie(owner))
old_species = owner.dna.species.type
+ if(!converts_living && owner.stat != DEAD)
+ return
+
+ var/stand_up = (owner.stat == DEAD) || (owner.stat == UNCONSCIOUS)
+
owner.grab_ghost()
owner.set_species(/datum/species/zombie/infectious)
- var/old_stat = owner.stat // Save for the message
owner.revive(full_heal = TRUE)
- switch(old_stat)
- if(DEAD, UNCONSCIOUS)
- owner.visible_message("[owner] staggers to [owner.p_their()] feet!")
- owner << "You stagger to your feet!"
- // Conscious conversions will generally only happen for an event
- // or for a converts_living=TRUE infection
- if(CONSCIOUS)
- owner.visible_message("[owner] suddenly convulses, as [owner.p_they()] gain a ravenous hunger in [owner.p_their()] eyes!",
- "You HUNGER!")
- playsound(owner.loc, 'sound/hallucinations/growl3.ogg', 50, 1)
- owner.do_jitter_animation(living_transformation_time)
- owner.Stun(living_transformation_time)
- owner << "You are now a zombie!"
-
-#undef START_TIMER
+ owner.visible_message("[owner] suddenly convulses, as [owner.p_they()][stand_up ? " 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)
+ owner.do_jitter_animation(living_transformation_time * 10)
+ owner.Stun(living_transformation_time)
+ owner << "You are now a zombie!"