Merge pull request #11535 from Couls/zombies

[Ready for review] Romerol Virus, Zombies!
This commit is contained in:
variableundefined
2019-09-03 20:58:53 -04:00
committed by GitHub
25 changed files with 419 additions and 88 deletions
+4 -2
View File
@@ -1,6 +1,8 @@
// String identifiers for associative list lookup
#define CHECK_DNA_AND_SPECIES(C) if((!(C.dna)) || (!(C.dna.species))) return
#define MUTCHK_FORCED 1
// mob/var/list/mutations
@@ -22,7 +24,6 @@
///////////////////////////////////////
// MUTATIONS
///////////////////////////////////////
// Generic mutations:
#define TK 1
#define COLDRES 2
@@ -149,4 +150,5 @@
#define RESISTHOT 16
#define RESISTCOLD 17
#define NO_EXAMINE 18
#define CAN_WINGDINGS 19
#define CAN_WINGDINGS 19
#define NOZOMBIE 20
+1
View File
@@ -4,6 +4,7 @@
// Mobs
#define ismegafauna(A) istype(A, /mob/living/simple_animal/hostile/megafauna)
#define iszombie(A) (is_species(A, /datum/species/zombie))
//Simple animals
#define isshade(A) (istype(A, /mob/living/simple_animal/shade))
+1
View File
@@ -16,6 +16,7 @@ GLOBAL_LIST_INIT(prisoncomputer_list, list())
GLOBAL_LIST_INIT(celltimers_list, list()) // list of all cell timers
GLOBAL_LIST_INIT(cell_logs, list())
GLOBAL_LIST_INIT(navigation_computers, list())
GLOBAL_LIST_INIT(zombie_infection_list, list())
GLOBAL_LIST_INIT(all_areas, list())
GLOBAL_LIST_INIT(machines, list())
+1 -16
View File
@@ -738,22 +738,7 @@
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
to_chat(M, "Control of your mob has been offered to dead players.")
log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.")
var/minhours = input(usr, "Minimum hours required to play [M]?", "Set Min Hrs", 10) as num
message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts with [minhours] hrs playtime")
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [M.real_name ? M.real_name : M.name]?", poll_time = 100, min_hours = minhours)
var/mob/dead/observer/theghost = null
if(candidates.len)
theghost = pick(candidates)
to_chat(M, "Your mob has been taken over by a ghost!")
message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)])")
M.ghostize()
M.key = theghost.key
else
to_chat(M, "There were no ghosts willing to take control.")
message_admins("No ghosts were willing to take control of [key_name_admin(M)])")
offer_control(M)
else if(href_list["delete"])
if(!check_rights(R_DEBUG, 0))
+9
View File
@@ -190,6 +190,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
cost = 1
job = list("Clown")
/datum/uplink_item/stealthy_weapons/romerol_kit
name = "Romerol"
reference = "ROM"
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/storage/box/syndie_kit/romerol
cost = 25
cant_discount = TRUE
//mime
/datum/uplink_item/jobspecific/caneshotgun
name = "Cane Shotgun and Assassination Shells"
@@ -646,6 +654,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/dangerous/guardian
name = "Holoparasites"
reference = "HPA"
desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an organic host as a home base and source of fuel. \
The holoparasites are unable to incoporate themselves to changeling and vampire agents."
item = /obj/item/storage/box/syndie_kit/guardian
+5 -5
View File
@@ -66,7 +66,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
@@ -110,7 +110,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
@@ -167,7 +167,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
@@ -262,7 +262,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
@@ -317,7 +317,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
@@ -121,6 +121,19 @@
desc = "A sleek, sturdy box"
icon_state = "box_of_doom"
/obj/item/storage/box/syndie_kit/romerol
name = "Romerol Kit"
desc = "A box containing a deadly virus capable of reanimating dead as zombies."
max_w_class = WEIGHT_CLASS_NORMAL
can_hold = list(/obj/item/reagent_containers/glass/bottle/romerol,/obj/item/reagent_containers/syringe,/obj/item/reagent_containers/dropper)
/obj/item/storage/box/syndie_kit/romerol/New()
..()
new /obj/item/reagent_containers/glass/bottle/romerol(src)
new /obj/item/reagent_containers/syringe(src)
new /obj/item/reagent_containers/dropper(src)
return
/obj/item/storage/box/syndie_kit/space
name = "Boxed Space Suit and Helmet"
can_hold = list(/obj/item/clothing/suit/space/syndicate/black/red, /obj/item/clothing/head/helmet/space/syndicate/black/red, /obj/item/tank/emergency_oxygen/syndi, /obj/item/clothing/mask/gas/syndicate)
+10
View File
@@ -762,6 +762,16 @@
desc = "Bark bark bark."
key = "vu"
/datum/language/zombie
name = "Zombie"
desc = "BRAAAAAAINS!"
speech_verb = "moans"
whisper_verb = "mutters"
exclaim_verb = "wails"
colour = "zombie"
key = "zom"
syllables = list("BRAAAAAAAAAAAAAAAAINS", "BRAAINS", "BRAINS")
/mob/proc/grant_all_languages()
for(var/la in GLOB.all_languages)
add_language(la)
@@ -344,56 +344,5 @@ This function restores all organs.
//Handle BRUTE and BURN damage
handle_suit_punctures(damagetype, damage)
blocked = (100 - blocked) / 100
if(blocked <= 0)
return 0
var/obj/item/organ/external/organ = null
if(isorgan(def_zone))
organ = def_zone
else
if(!def_zone)
def_zone = ran_zone(def_zone)
organ = get_organ(check_zone(def_zone))
if(!organ)
return 0
damage = damage * blocked
switch(damagetype)
if(BRUTE)
damageoverlaytemp = 20
if(dna.species)
damage = damage * dna.species.brute_mod
if(organ.receive_damage(damage, 0, sharp, used_weapon))
UpdateDamageIcon()
if(LAssailant && ishuman(LAssailant)) //superheros still get the comical hit markers
var/mob/living/carbon/human/H = LAssailant
if(H.mind && H.mind in (SSticker.mode.superheroes || SSticker.mode.supervillains || SSticker.mode.greyshirts))
var/list/attack_bubble_recipients = list()
var/mob/living/user
for(var/mob/O in viewers(user, src))
if(O.client && O.has_vision(information_only=TRUE))
attack_bubble_recipients.Add(O.client)
spawn(0)
var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1)
dmgIcon.pixel_x = (!lying) ? rand(-3,3) : rand(-11,12)
dmgIcon.pixel_y = (!lying) ? rand(-11,9) : rand(-10,1)
flick_overlay(dmgIcon, attack_bubble_recipients, 9)
if(BURN)
damageoverlaytemp = 20
if(dna.species)
damage = damage * dna.species.burn_mod
if(organ.receive_damage(0, damage, sharp, used_weapon))
UpdateDamageIcon()
// Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life().
updatehealth("apply damage")
return 1
//Handle species apply_damage procs
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, sharp, used_weapon)
@@ -14,7 +14,6 @@
handle_heartbeat()
handle_drunk()
dna.species.handle_life(src)
if(!client)
dna.species.handle_npc(src)
@@ -52,9 +52,10 @@
var/brain_mod = 1 // Brain damage damage reduction/amplification
var/stamina_mod = 1
var/stun_mod = 1 // If a species is more/less impacated by stuns/weakens/paralysis
var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
var/armor = 0 // overall defense for the race... or less defense, if it's negative.
var/blood_damage_type = OXY //What type of damage does this species take if it's low on blood?
var/obj/item/mutanthands
var/total_health = 100
var/punchdamagelow = 0 //lowest possible punch damage
var/punchdamagehigh = 9 //highest possible punch damage
@@ -308,6 +309,63 @@
/datum/species/proc/handle_death(mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
return
/datum/species/proc/spec_death(gibbed, mob/living/carbon/human/C)
return
/datum/species/proc/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, mob/living/carbon/human/H, sharp = 0, obj/used_weapon = null)
blocked = (100 - blocked) / 100
if(blocked <= 0)
return 0
var/obj/item/organ/external/organ = null
if(isorgan(def_zone))
organ = def_zone
else
if(!def_zone)
def_zone = ran_zone(def_zone)
organ = H.get_organ(check_zone(def_zone))
if(!organ)
return 0
damage = damage * blocked
switch(damagetype)
if(BRUTE)
H.damageoverlaytemp = 20
damage = damage * brute_mod
if(organ.receive_damage(damage, 0, sharp, used_weapon))
H.UpdateDamageIcon()
if(H.LAssailant && ishuman(H.LAssailant)) //superheros still get the comical hit markers
var/mob/living/carbon/human/A = H.LAssailant
if(A.mind && A.mind in (SSticker.mode.superheroes || SSticker.mode.supervillains || SSticker.mode.greyshirts))
var/list/attack_bubble_recipients = list()
var/mob/living/user
for(var/mob/O in viewers(user, src))
if(O.client && O.has_vision(information_only=TRUE))
attack_bubble_recipients.Add(O.client)
spawn(0)
var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1)
dmgIcon.pixel_x = (!H.lying) ? rand(-3,3) : rand(-11,12)
dmgIcon.pixel_y = (!H.lying) ? rand(-11,9) : rand(-10,1)
flick_overlay(dmgIcon, attack_bubble_recipients, 9)
if(BURN)
H.damageoverlaytemp = 20
damage = damage * burn_mod
if(organ.receive_damage(0, damage, sharp, used_weapon))
H.UpdateDamageIcon()
// Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life().
H.updatehealth("apply damage")
return 1
/datum/species/proc/spec_stun(mob/living/carbon/human/H,amount)
return
/datum/species/proc/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
return
@@ -0,0 +1,91 @@
#define REGENERATION_DELAY 60 // After taking damage, how long it takes for automatic regeneration to begin
/datum/species/zombie
// 1spooky
name = "High-Functioning Zombie"
name_plural = "High-Functioning Zombies"
icobase = 'icons/mob/human_races/r_zombie.dmi'
deform = 'icons/mob/human_races/r_def_zombie.dmi'
dies_at_threshold = TRUE
language = "Zombie"
species_traits = list(NO_BLOOD,NOZOMBIE,NOTRANSSTING,NO_BREATHE, RADIMMUNE, NO_SCAN)
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
flesh_color = "#00FF00" // for green examine text
bodyflags = HAS_SKIN_COLOR
dietflags = DIET_CARN
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
icobase = 'icons/mob/human_races/r_zombie.dmi'
deform = 'icons/mob/human_races/r_def_zombie.dmi'
armor = 20 // 120 damage to KO a zombie, which kills it
speedmod = 1.6
default_language = "Zombie"
var/heal_rate = 1
var/regen_cooldown = 0
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H, amount)
. = min(20, amount)
/datum/species/zombie/infectious/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, sharp = 0, obj/used_weapon = null)
. = ..()
if(damage)
regen_cooldown = world.time + REGENERATION_DELAY
/datum/species/zombie/infectious/handle_life(mob/living/carbon/human/C)
. = ..()
//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
C.heal_overall_damage(heal_amt,heal_amt)
C.adjustToxLoss(-heal_amt)
if(!C.InCritical() && prob(4))
playsound(C, pick(spooks), 50, TRUE, 10)
//Congrats you somehow died so hard you stopped being a zombie
/datum/species/zombie/infectious/spec_death(gibbed, mob/living/carbon/C)
. = ..()
var/obj/item/organ/internal/zombie_infection/infection
infection = C.get_organ_slot("zombie_infection")
if(infection)
qdel(infection)
/datum/species/zombie/infectious/on_species_gain(mob/living/carbon/human/C, datum/species/old_species)
. = ..()
// Deal with the source of this zombie corruption
// Infection organ needs to be handled separately from mutant_organs
// because it persists through species transitions
if(mutanthands)
C.drop_l_hand()
C.drop_r_hand()
C.put_in_hands(new mutanthands())
C.put_in_hands(new mutanthands())
var/obj/item/organ/internal/zombie_infection/infection
infection = C.get_organ_slot("zombie_infection")
if(!infection)
infection = new()
infection.insert(C)
/datum/species/zombie/infectious/on_species_loss(mob/living/carbon/human/C, datum/species/old_species)
QDEL_NULL(C.r_hand)
QDEL_NULL(C.l_hand)
return ..()
#undef REGENERATION_DELAY
@@ -5,21 +5,29 @@
. = ..()
/mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0)
if(dna.species)
if(dna.species.stun_mod)
amount = amount * dna.species.stun_mod
else
amount = dna.species.spec_stun(src,amount)
return ..()
/mob/living/carbon/human/SetWeakened(amount, updating = 1, force = 0)
if(dna.species)
if(dna.species.stun_mod)
amount = amount * dna.species.stun_mod
else
amount = dna.species.spec_stun(src,amount)
return ..()
/mob/living/carbon/human/SetParalysis(amount, updating = 1, force = 0)
if(dna.species)
if(dna.species.stun_mod)
amount = amount * dna.species.stun_mod
else
amount = dna.species.spec_stun(src,amount)
return ..()
/mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE)
if(dna.species)
if(dna.species.stun_mod)
amount = amount * dna.species.stun_mod
return ..()
else
amount = dna.species.spec_stun(src,amount)
return ..()
+18
View File
@@ -113,6 +113,24 @@
return U.sensor_mode
return SUIT_SENSOR_OFF
/proc/offer_control(mob/M)
to_chat(M, "Control of your mob has been offered to dead players.")
log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.")
var/minhours = input(usr, "Minimum hours required to play [M]?", "Set Min Hrs", 10) as num
message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts with [minhours] hrs playtime")
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [M.real_name ? M.real_name : M.name]?", poll_time = 100, min_hours = minhours)
var/mob/dead/observer/theghost = null
if(LAZYLEN(candidates))
theghost = pick(candidates)
to_chat(M, "Your mob has been taken over by a ghost!")
message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)])")
M.ghostize()
M.key = theghost.key
else
to_chat(M, "There were no ghosts willing to take control.")
message_admins("No ghosts were willing to take control of [key_name_admin(M)])")
/proc/check_zone(zone)
if(!zone) return "chest"
switch(zone)
@@ -48,7 +48,7 @@
var/gender = NEUTER //Determines if the accessory will be skipped or included in random hair generations
// Restrict some styles to specific species
var/list/species_allowed = list("Human", "Slime People")
var/list/species_allowed = list("Human", "Slime People", "Infectious Zombie", "High-Functioning Zombie")
var/list/sprite_sheets = list() //For accessories common across species but need to use 'fitted' sprites (like underwear). e.g. list("Vox" = 'icons/mob/species/vox/iconfile.dmi')
var/list/models_allowed = list() //Specifies which, if any, hairstyles or markings can be accessed by which prosthetics. Should equal the manufacturing company name in robolimbs.dm.
var/list/heads_allowed = null //Specifies which, if any, alt heads a head marking, hairstyle or facial hair style is compatible with.
@@ -207,6 +207,25 @@
return ..()
datum/reagent/romerol
name = "romerol"
// the REAL zombie powder
id = "romerol"
description = "Romerol is a highly experimental bioterror agent \
which causes dormant nodules to be etched into the grey matter of \
the subject. These nodules only become active upon death of the \
host, upon which, the secondary structures activate and take control \
of the host body."
color = "#123524" // RGB (18, 53, 36)
metabolization_rate = INFINITY
can_synth = FALSE
taste_description = "CAAAARL"
/datum/reagent/romerol/reaction_mob(mob/living/carbon/human/H)
// Silently add the zombie infection organ to be activated upon death
new /obj/item/organ/internal/zombie_infection(H)
..()
/datum/reagent/stable_mutagen/on_tick()
var/datum/reagent/blood/B = locate() in holder.reagent_list
if(B && islist(B.data) && !data)
@@ -12,6 +12,11 @@
container_type = OPENCONTAINER
volume = 30
/obj/item/reagent_containers/glass/bottle/romerol
name = "romerol bottle"
desc = "A small bottle of Romerol. The REAL zombie powder."
list_reagents = list("romerol" = 30)
/obj/item/reagent_containers/glass/bottle/on_reagent_change()
update_icon()
+1 -1
View File
@@ -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
+67
View File
@@ -0,0 +1,67 @@
/obj/item/zombie_hand
name = "zombie claw"
desc = "A zombie's claw is its primary tool, capable of infecting \
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|DROPDEL
icon = 'icons/effects/blood.dmi'
icon_state = "bloodhand_left"
var/icon_left = "bloodhand_left"
var/icon_right = "bloodhand_right"
hitsound = 'sound/hallucinations/growl1.ogg'
force = 25
damtype = "brute"
/obj/item/zombie_hand/equipped(mob/user, slot)
. = ..()
switch(slot)
// Yes, these intentionally don't match
if(slot_l_hand)
icon_state = icon_right
if(slot_r_hand)
icon_state = icon_left
/obj/item/zombie_hand/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
if(!proximity_flag)
return
else if(isliving(target))
if(ishuman(target))
check_infection(target, user)
else
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)
if(NOZOMBIE in target.dna.species.species_traits)
// cannot infect any NOZOMBIE subspecies (such as high functioning
// zombies)
return
var/obj/item/organ/internal/zombie_infection/infection
infection = target.get_organ_slot("zombie_infection")
if(!infection)
if (target.InCritical() || (!target.check_death_method() && target.health <= HEALTH_THRESHOLD_DEAD))
infection = new(target)
/obj/item/zombie_hand/proc/check_feast(mob/living/target, mob/living/user)
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)
user.adjustBrainLoss(-hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!"
/obj/item/zombie_hand/suicide_act(mob/living/carbon/human/user)
user.visible_message("<span class='suicide'>[user] is ripping [user.p_their()] brains out! It looks like [user.p_theyre()] trying to commit suicide!</span>")
if(ishuman(user))
var/mob/living/carbon/human/L = user
var/obj/item/organ/external/O = L.get_organ("head")
if(O)
O.droplimb()
return (BRUTELOSS)
+93
View File
@@ -0,0 +1,93 @@
/obj/item/organ/internal/zombie_infection
name = "festering ooze"
desc = "A black web of pus and viscera."
parent_organ = "head"
slot = "zombie_infection"
icon_state = "blacktumor"
var/converts_living = FALSE
var/causes_damage = TRUE
var/datum/species/old_species = /datum/species/human
var/living_transformation_time = 3
var/revive_time_min = 450
var/revive_time_max = 700
var/timer_id
var/dont_delete = FALSE // to prevent set_species proc in zombify from deleting the infection organ immediately
/obj/item/organ/internal/zombie_infection/New()
. = ..()
if(ishuman(owner) && !ismachine(owner) && !iszombie(owner.dna.species))
old_species = owner.dna.species
GLOB.zombie_infection_list += src
/obj/item/organ/internal/zombie_infection/Destroy()
GLOB.zombie_infection_list -= src
. = ..()
/obj/item/organ/internal/zombie_infection/insert(mob/living/carbon/human/M, special = 0)
. = ..()
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 && !dont_delete)
M.set_species(old_species)
if(timer_id)
deltimer(timer_id)
..()
/obj/item/organ/internal/zombie_infection/on_find(mob/living/finder)
to_chat(finder,"<span class='warning'>Inside the head is a disgusting black \
web of pus and viscera, bound tightly around the brain like some \
biological harness.</span>")
/obj/item/organ/internal/zombie_infection/process()
if(!ishuman(owner)) // We do not support monkey or xeno zombies. Yet.
qdel(src)
return
if(owner.suiciding)
return
if(owner.stat != DEAD && !converts_living)
return
if(causes_damage && !iszombie(owner) && owner.stat != DEAD)
owner.adjustToxLoss(1)
if (prob(10))
to_chat(owner, "<span class='danger'>You feel sick...</span>")
if(!owner.get_int_organ(/obj/item/organ/internal/brain))
return
if(!iszombie(owner) && !timer_id)
to_chat(owner, "<span class='cultlarge'>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!</span>")
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/internal/zombie_infection/proc/zombify()
timer_id = null
if(owner.stat != DEAD && !converts_living)
return
if(!iszombie(owner))
old_species = owner.dna.species
dont_delete = TRUE // make sure the remove code above does not run when the species code replaces all the organs
owner.set_species(/datum/species/zombie/infectious)
for(var/thing in owner.viruses) // cure any new crit viruses
var/datum/disease/D = thing
D.cure(0)
dont_delete = FALSE
//Fully heal the zombie's damage the first time they rise
owner.setToxLoss(0)
owner.setOxyLoss(0)
owner.setBrainLoss(0)
owner.setCloneLoss(0)
owner.SetLoseBreath(0)
owner.heal_overall_damage(INFINITY,INFINITY,TRUE,TRUE,FALSE)
if(owner.update_revive())
owner.grab_ghost()
owner.visible_message("<span class='danger'>[owner] suddenly convulses, as [owner.p_they()] stagger to [owner.p_their()] feet and gain a ravenous hunger in [owner.p_their()] eyes!</span>", "<span class='alien'>You HUNGER!</span>")
playsound(owner.loc, 'sound/hallucinations/far_noise.ogg', 50, 1)
owner.do_jitter_animation(living_transformation_time)
owner.Stun(living_transformation_time)
to_chat(owner, "<span class='alertalien'>You are now a zombie! Do not seek to be cured, do not help any non-zombies in any way, do not harm your zombie brethren and spread the disease by killing others. You are a creature of hunger and violence.</span>")
@@ -336,6 +336,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;}
@@ -389,7 +390,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%;}
+1 -1
View File
@@ -333,6 +333,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;}
@@ -386,7 +387,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%;}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

+3
View File
@@ -1829,6 +1829,7 @@
#include "code\modules\mob\living\carbon\human\species\vox.dm"
#include "code\modules\mob\living\carbon\human\species\vulpkanin.dm"
#include "code\modules\mob\living\carbon\human\species\wryn.dm"
#include "code\modules\mob\living\carbon\human\species\zombies.dm"
#include "code\modules\mob\living\carbon\slime\death.dm"
#include "code\modules\mob\living\carbon\slime\emote.dm"
#include "code\modules\mob\living\carbon\slime\examine.dm"
@@ -2470,6 +2471,8 @@
#include "code\modules\vr\vr_controller.dm"
#include "code\modules\vr\vr_goggles.dm"
#include "code\modules\vr\vr_outfits.dm"
#include "code\modules\zombie\items.dm"
#include "code\modules\zombie\organs.dm"
#include "goon\code\datums\browserOutput.dm"
#include "interface\interface.dm"
#include "interface\skin.dmf"