mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 12:29:46 +01:00
Backports the new zombification mechanics from the Konyang zombie event. (#18710)
* Reorder parasites * sounds * organ defines, dmdocs * maiming stuff * undead changes, abilities * hylemnomil, undead sprites * antibodies * antibody extractor code * icons * antibody fixes * antibodies vial, rock break sfx * You're all going to die down here. * hylemnomilz eta vial and attributions * zombified organs can't be removed * hylemnomil zeta edits * fixes * lmao * easier check --------- Co-authored-by: Matt Atlas <liermattia@gmail.com>
This commit is contained in:
@@ -143,10 +143,6 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/carbon/human/zombie/Initialize(mapload)
|
||||
. = ..(mapload, SPECIES_ZOMBIE)
|
||||
|
||||
/datum/species/zombie
|
||||
name = SPECIES_ZOMBIE
|
||||
name_plural = "Zombies"
|
||||
@@ -166,8 +162,13 @@
|
||||
|
||||
has_fine_manipulation = FALSE
|
||||
|
||||
speech_sounds = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg')
|
||||
speech_chance = 50
|
||||
speech_sounds = list(
|
||||
'sound/effects/zombies/zombie_1.ogg',
|
||||
'sound/effects/zombies/zombie_2.ogg',
|
||||
'sound/effects/zombies/zombie_3.ogg',
|
||||
'sound/effects/zombies/zombie_4.ogg'
|
||||
)
|
||||
speech_chance = 100
|
||||
|
||||
ethanol_resistance = -1
|
||||
taste_sensitivity = TASTE_NUMB
|
||||
@@ -192,16 +193,16 @@
|
||||
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/zombie)
|
||||
)
|
||||
|
||||
total_health = 80
|
||||
total_health = 150
|
||||
|
||||
slowdown = 2
|
||||
slowdown = 1
|
||||
|
||||
vision_flags = DEFAULT_SIGHT
|
||||
|
||||
reagent_tag = IS_UNDEAD
|
||||
|
||||
rarity_value = 10
|
||||
blurb = "Once a living person, this unholy creature was created either by the power of science or necromancy."
|
||||
blurb = "Once a living person, this unholy creature was created by the power of science."
|
||||
|
||||
remains_type = /obj/effect/decal/remains/human
|
||||
dust_remains_type = /obj/effect/decal/remains/human/burned
|
||||
@@ -214,35 +215,37 @@
|
||||
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR | HAS_SOCKS
|
||||
spawn_flags = IS_RESTRICTED
|
||||
|
||||
stamina = 500 //Tireless automatons
|
||||
stamina = 500 //Tireless automatons
|
||||
stamina_recovery = 1
|
||||
sprint_speed_factor = 0.1
|
||||
sprint_speed_factor = 1
|
||||
exhaust_threshold = 10
|
||||
|
||||
inherent_verbs = list(/mob/living/carbon/human/proc/darkness_eyes)
|
||||
inherent_verbs = list(/mob/living/carbon/human/proc/darkness_eyes, /mob/living/carbon/proc/consume)
|
||||
|
||||
allowed_eat_types = TYPE_ORGANIC | TYPE_HUMANOID
|
||||
|
||||
gluttonous = 1
|
||||
show_ssd = null
|
||||
|
||||
/mob/living/carbon/human/zombie/Initialize(mapload)
|
||||
. = ..(mapload, SPECIES_ZOMBIE)
|
||||
set_name("zombie")
|
||||
|
||||
/datum/species/zombie/handle_post_spawn(var/mob/living/carbon/human/H)
|
||||
H.mutations |= CLUMSY
|
||||
var/datum/martial_art/zombie/Z = new /datum/martial_art/zombie()
|
||||
Z.teach(H)
|
||||
to_chat(H, "<font size=4><span class='notice'>Use the Check Attacks verb in your IC tab for information on your attacks! They are important! Your bite infects, but is worse at getting through armour than your claws, which have great damage and are armor piercing!</font></span>")
|
||||
H.accent = ACCENT_BLUESPACE
|
||||
return ..()
|
||||
|
||||
//Zombies do not have oxygen, so we have to handle the sprint this way
|
||||
/datum/species/zombie/handle_sprint_cost(var/mob/living/carbon/human/H, var/cost, var/pre_move)
|
||||
. = ..()
|
||||
|
||||
if(exhaust_threshold && (H.stamina) < (exhaust_threshold * 0.8))
|
||||
H.m_intent = M_WALK
|
||||
H.hud_used.move_intent.update_move_icon(H)
|
||||
to_chat(H, SPAN_DANGER("You're too exhausted to run anymore!"))
|
||||
H.flash_pain(H.get_shock())
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/datum/species/zombie/tajara
|
||||
name = SPECIES_ZOMBIE_TAJARA
|
||||
@@ -329,7 +332,7 @@
|
||||
icobase = 'icons/mob/human_races/zombie/r_zombie_bull.dmi'
|
||||
deform = 'icons/mob/human_races/zombie/r_zombie_bull.dmi'
|
||||
|
||||
total_health = 300
|
||||
total_health = 250
|
||||
|
||||
allowed_eat_types = TYPE_ORGANIC | TYPE_HUMANOID | TYPE_SYNTHETIC | TYPE_WEIRD
|
||||
gluttonous = GLUT_ANYTHING
|
||||
@@ -344,15 +347,28 @@
|
||||
species_height = HEIGHT_CLASS_TALL
|
||||
|
||||
natural_armor = list(
|
||||
ballistic = ARMOR_BALLISTIC_RIFLE,
|
||||
laser = ARMOR_LASER_MEDIUM,
|
||||
ballistic = ARMOR_BALLISTIC_MEDIUM,
|
||||
melee = ARMOR_MELEE_MAJOR,
|
||||
bomb = null,
|
||||
energy = ARMOR_ENERGY_RESISTANT
|
||||
)
|
||||
|
||||
unarmed_types = list(/datum/unarmed_attack/bite/infectious)
|
||||
mob_size = 20
|
||||
|
||||
unarmed_types = list(/datum/unarmed_attack/bite/infectious)
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/darkness_eyes,
|
||||
/mob/living/carbon/proc/consume,
|
||||
/mob/living/carbon/proc/smash_barricade,
|
||||
/mob/living/carbon/human/proc/throw_rock
|
||||
)
|
||||
show_ssd = TRUE
|
||||
|
||||
/datum/species/zombie/bull/get_random_name(gender)
|
||||
return "zombie bull"
|
||||
|
||||
/mob/living/carbon/human/bull/Initialize(mapload, new_species)
|
||||
. = ..(mapload, SPECIES_ZOMBIE_BULL)
|
||||
|
||||
///A zombie tuned to hunt preys
|
||||
/datum/species/zombie/hunter
|
||||
@@ -362,10 +378,10 @@
|
||||
deform = 'icons/mob/human_races/zombie/r_zombie_hunter.dmi'
|
||||
slowdown = 2
|
||||
|
||||
total_health = 90
|
||||
total_health = 80
|
||||
|
||||
stamina = 40
|
||||
sprint_speed_factor = 0.9
|
||||
stamina = 80
|
||||
sprint_speed_factor = 1.2
|
||||
slowdown = -2
|
||||
standing_jump_range = 5
|
||||
natural_climbing = TRUE
|
||||
@@ -373,15 +389,20 @@
|
||||
vision_flags = SEE_SELF | SEE_MOBS
|
||||
hearing_sensitivity = HEARING_VERY_SENSITIVE
|
||||
|
||||
natural_armor = list(
|
||||
ballistic = ARMOR_BALLISTIC_MEDIUM,
|
||||
laser = ARMOR_LASER_PISTOL,
|
||||
melee = ARMOR_MELEE_MAJOR,
|
||||
bomb = ARMOR_BOMB_PADDED,
|
||||
energy = ARMOR_ENERGY_SMALL
|
||||
)
|
||||
maneuvers = list(/singleton/maneuver/leap/areagrab)
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/darkness_eyes,
|
||||
/mob/living/carbon/proc/consume
|
||||
)
|
||||
|
||||
unarmed_types = list(/datum/unarmed_attack/shocking) //This zombie cannot infect, it's an harrass type of zombie
|
||||
unarmed_types = list(/datum/unarmed_attack/claws/strong)
|
||||
show_ssd = TRUE
|
||||
|
||||
/datum/species/zombie/hunter/get_random_name(gender)
|
||||
return "zombie hunter"
|
||||
|
||||
/mob/living/carbon/human/hunter/Initialize(mapload, new_species)
|
||||
. = ..(mapload, SPECIES_ZOMBIE_HUNTER)
|
||||
|
||||
///A zombie tuned for charge attacks
|
||||
/datum/species/zombie/rhino
|
||||
@@ -391,7 +412,7 @@
|
||||
deform = 'icons/mob/human_races/zombie/r_zombie_rhino.dmi'
|
||||
slowdown = 2
|
||||
|
||||
total_health = 120
|
||||
total_health = 200
|
||||
|
||||
stamina = 50
|
||||
sprint_speed_factor = 0.7
|
||||
@@ -406,13 +427,184 @@
|
||||
grab_mod = 5
|
||||
|
||||
natural_armor = list(
|
||||
ballistic = ARMOR_BALLISTIC_MEDIUM,
|
||||
laser = ARMOR_LASER_PISTOL,
|
||||
melee = ARMOR_MELEE_MAJOR,
|
||||
ballistic = ARMOR_BALLISTIC_MINOR,
|
||||
laser = ARMOR_LASER_MINOR,
|
||||
melee = ARMOR_MELEE_SMALL,
|
||||
bomb = ARMOR_BOMB_PADDED,
|
||||
energy = ARMOR_ENERGY_SMALL
|
||||
)
|
||||
|
||||
maneuvers = list(/singleton/maneuver/leap/areagrab)
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/trample,
|
||||
/mob/living/carbon/human/proc/darkness_eyes,
|
||||
/mob/living/carbon/proc/consume
|
||||
)
|
||||
|
||||
unarmed_types = list(/datum/unarmed_attack/bite/infectious, /datum/unarmed_attack/golem)
|
||||
show_ssd = TRUE
|
||||
|
||||
/datum/species/zombie/rhino/get_random_name(gender)
|
||||
return "zombie rhino"
|
||||
|
||||
/mob/living/carbon/human/rhino/Initialize(mapload, new_species)
|
||||
. = ..(mapload, SPECIES_ZOMBIE_RHINO)
|
||||
|
||||
/mob/living/carbon/proc/consume()
|
||||
set name = "Consume"
|
||||
set desc = "Regain life and infect others by feeding upon them."
|
||||
set category = "Abilities"
|
||||
|
||||
if (last_special > world.time)
|
||||
to_chat(src, SPAN_WARNING("You aren't ready to do that! Wait [round(last_special - world.time) / 10] seconds."))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/target
|
||||
var/list/victims = list()
|
||||
for (var/mob/living/carbon/human/L in get_turf(src))
|
||||
if (L != src && (L.lying || L.stat == DEAD))
|
||||
if (iszombie(L))
|
||||
to_chat(src, SPAN_WARNING("\The [L] isn't fresh anymore!"))
|
||||
continue
|
||||
if (!L.species.zombie_type || L.is_diona() || L.isSynthetic())
|
||||
to_chat(src, SPAN_WARNING("You'd break your teeth on \the [L]!"))
|
||||
continue
|
||||
victims += L
|
||||
|
||||
if (!length(victims))
|
||||
to_chat(src, SPAN_WARNING("No valid targets nearby!"))
|
||||
return
|
||||
if (client)
|
||||
if (length(victims) == 1) //No need to choose
|
||||
target = victims[1]
|
||||
else
|
||||
target = tgui_input_list(src, "Who would you like to consume?", "Zombie", victims)
|
||||
else //NPCs
|
||||
if (length(victims) > 0)
|
||||
target = victims[1]
|
||||
|
||||
if (!target)
|
||||
return
|
||||
if (get_turf(src) != get_turf(target) || !(target.lying || target.stat == DEAD))
|
||||
to_chat(src, SPAN_WARNING("You're no longer on top of \the [target]!"))
|
||||
return
|
||||
|
||||
last_special = world.time + 5 SECONDS
|
||||
|
||||
src.visible_message(SPAN_DANGER("\The [src] hunkers down over \the [target], tearing into their flesh."))
|
||||
playsound(loc, 'sound/effects/bonebreak3.ogg', 20, 1)
|
||||
playsound(loc, 'sound/weapons/bloodyslice.ogg', 30, 1)
|
||||
|
||||
target.adjustHalLoss(50)
|
||||
|
||||
if (do_after(src, 5 SECONDS, target, DO_DEFAULT | DO_USER_UNIQUE_ACT, INCAPACITATION_KNOCKOUT))
|
||||
admin_attack_log(src, target, "Consumed their victim.", "Was consumed.", "consumed")
|
||||
|
||||
if (!target.lying && target.stat != DEAD) //Check victims are still prone
|
||||
return
|
||||
|
||||
target.apply_damage(rand(50, 60), DAMAGE_BRUTE, BP_CHEST)
|
||||
target.adjustBruteLoss(20)
|
||||
var/infection_chance = 80
|
||||
var/hylemnomil_amount = REAGENT_VOLUME(target.reagents, /singleton/reagent/toxin/hylemnomil)
|
||||
if(prob(infection_chance))
|
||||
if(target.reagents)
|
||||
target.reagents.add_reagent(/singleton/reagent/toxin/hylemnomil, min(10, ZOMBIE_MAX_HYLEMNOMIL - hylemnomil_amount))
|
||||
|
||||
if (target.getBruteLoss() > target.maxHealth * 3)
|
||||
if (target.stat != DEAD)
|
||||
to_chat(src,SPAN_WARNING("You've scraped \the [target] down to the bones already!."))
|
||||
else
|
||||
to_chat(src,SPAN_DANGER("You shred and rip apart \the [target]'s remains!."))
|
||||
target.gib()
|
||||
playsound(loc, 'sound/effects/splat.ogg', 40, 1)
|
||||
return
|
||||
|
||||
to_chat(target,SPAN_DANGER("\The [src] scrapes your flesh from your bones!"))
|
||||
to_chat(src,SPAN_DANGER("You feed hungrily off \the [target]'s flesh."))
|
||||
|
||||
if (iszombie(target)) //Just in case they turn whilst being eaten
|
||||
return
|
||||
|
||||
var/obj/item/organ/external/E = target.organs_by_name[BP_CHEST]
|
||||
if(E && E.open < 3 && target.getBruteLoss() > 100)
|
||||
E.open = min(E.open + 1, 3)
|
||||
target.update_surgery() //Update broken ribcage sprites etc.
|
||||
|
||||
adjustBruteLoss(-5)
|
||||
adjustFireLoss(-15)
|
||||
adjustToxLoss(-5)
|
||||
adjustBrainLoss(-5)
|
||||
nutrition += 40
|
||||
|
||||
playsound(loc, 'sound/effects/splat.ogg', 20, 1)
|
||||
new /obj/effect/decal/cleanable/blood/splatter(get_turf(src), target.species.blood_color)
|
||||
if (target.getBruteLoss() > target.maxHealth*0.75)
|
||||
if (prob(50))
|
||||
gibs(get_turf(src), target.dna)
|
||||
src.visible_message(SPAN_DANGER("\The [src] tears out \the [target]'s insides!"))
|
||||
else
|
||||
src.visible_message(SPAN_WARNING("\The [src] leaves their meal for later."))
|
||||
|
||||
/mob/living/carbon/proc/smash_barricade()
|
||||
set name = "Destroy Barricade"
|
||||
set desc = "Destroy a barricade in front of you."
|
||||
set category = "Abilities"
|
||||
|
||||
if (last_special > world.time)
|
||||
to_chat(src, SPAN_WARNING("You aren't ready to do that! Wait [round(last_special - world.time) / 10] seconds."))
|
||||
return
|
||||
|
||||
var/obj/structure/barricade/B = locate() in get_turf(get_step(src, dir))
|
||||
if(!B)
|
||||
to_chat(src, SPAN_WARNING("You are not facing a barricade!"))
|
||||
return
|
||||
|
||||
last_special = world.time + 10 SECONDS
|
||||
if(do_after(src, 2 SECONDS, B))
|
||||
visible_message(SPAN_DANGER("<font size=4>\The [src] raises a giant, mutated hand and smashes \the [B]!</font>"))
|
||||
playsound(src, 'sound/weapons/heavysmash.ogg', 100)
|
||||
B.attack_generic(src, 200, "destroys", TRUE)
|
||||
|
||||
/mob/living/carbon/human/proc/throw_rock()
|
||||
set name = "Throw Rock"
|
||||
set desc = "Pick up a large rock and throw it. Tank-style."
|
||||
set category = "Abilities"
|
||||
|
||||
if (last_special > world.time)
|
||||
to_chat(src, SPAN_WARNING("You aren't ready to do that! Wait [round(last_special - world.time) / 10] seconds."))
|
||||
return
|
||||
|
||||
last_special = world.time + 10 SECONDS
|
||||
visible_message(SPAN_DANGER(FONT_LARGE("[src] digs their hands into the ground and starts picking up a portion of it!")))
|
||||
if(do_after(src, 3 SECONDS))
|
||||
visible_message(SPAN_DANGER(FONT_LARGE("[src] picks up a large boulder out of the ground!")))
|
||||
var/obj/item/tank_rock/TR = new()
|
||||
put_in_any_hand_if_possible(TR)
|
||||
|
||||
/obj/item/tank_rock
|
||||
name = "boulder"
|
||||
desc = "A large boulder."
|
||||
icon = 'icons/obj/flora/rocks_grey.dmi'
|
||||
icon_state = "basalt2"
|
||||
throwforce = 30
|
||||
armor_penetration = 20
|
||||
mob_throw_hit_sound = 'sound/effects/rock_break.ogg'
|
||||
|
||||
/obj/item/tank_rock/do_additional_pickup_checks(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.mob_size < 16)
|
||||
to_chat(user, SPAN_WARNING("That's way too heavy for you to pick up!"))
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/tank_rock/throw_impact(atom/hit_atom)
|
||||
. = ..()
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/M = hit_atom
|
||||
M.visible_message(SPAN_DANGER(FONT_LARGE("\The [src] breaks as it makes contact with [M]!")))
|
||||
M.Paralyse(5)
|
||||
M.apply_damage(30, DAMAGE_BRUTE, used_weapon = src, armor_pen = 30)
|
||||
qdel(src)
|
||||
|
||||
@@ -209,8 +209,8 @@
|
||||
infection_chance -= target.get_blocked_ratio(zone, DAMAGE_BRUTE, damage_flags = DAMAGE_FLAG_SHARP|DAMAGE_FLAG_EDGE, damage = damage)*100
|
||||
if(prob(infection_chance))
|
||||
if(target.reagents)
|
||||
var/trioxin_amount = REAGENT_VOLUME(target.reagents, /singleton/reagent/toxin/trioxin)
|
||||
target.reagents.add_reagent(/singleton/reagent/toxin/trioxin, min(10, ZOMBIE_MAX_TRIOXIN - trioxin_amount))
|
||||
var/hylemnomil_amount = REAGENT_VOLUME(target.reagents, /singleton/reagent/toxin/hylemnomil)
|
||||
target.reagents.add_reagent(/singleton/reagent/toxin/hylemnomil, min(10, ZOMBIE_MAX_HYLEMNOMIL - hylemnomil_amount))
|
||||
|
||||
/datum/unarmed_attack/bite/infectious/get_unarmed_damage(var/mob/attacker, var/target)
|
||||
if(istype(target, /mob/living/heavy_vehicle))
|
||||
|
||||
Reference in New Issue
Block a user