Adds a new mecha-fauna to lavaland. Ready to TM (#17999)

* pain

* more progress

* progress continues

* more progress™️

* saving progress while I swap brances

* leg moving working for real, woo

* more saving as power goes out

* eeven more

* fix transfer

* More changes, closer to pr ready

* final stuff for night backup

* almost done™️

* almost done

* Final changes to get ready for posting

* Update code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm

Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>

* new sprite

* Loot added (minus crusher loot)

* Apply suggestions from code review

Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>

* Defines, loot, and requested changes, oh my!

* Apply suggestions from code review

Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>

* sound, bluespace charge improvements, more text

* Update code/game/gamemodes/nuclear/pinpointer.dm

Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>

* WOOO CRUSHER ITEM

* don't code when dead tired kids

* Update code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm

Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>

* Makes crusher loot work, reworks shield for mecha fauna

* Names it, lets it spawn, buffs it, should be ready.

* Adds better sprites.

* pick to rand

* Buff, prevent cheese.

* Merge conflict hook test

* double checking to see if I installed it or not, think I need to manual

* fixes the merge issue

* makes gibtonite not yeet the mechafauna as much.

* fixes hostile/hostile fuckup

* fix most beam issues

* extra qdel insurance but it should be good

* fixes chasm issues, beep on self destruct, extra bluspace charge

* Shrinks the kaboom.

* spelling + beam fix

* Apply suggestions from code review

Co-authored-by: Charlie <69320440+hal9000PR@users.noreply.github.com>

* late_initialize, var names, and styling, oh my!

* attacl

Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>
Co-authored-by: Charlie <69320440+hal9000PR@users.noreply.github.com>
This commit is contained in:
Qwertytoforty
2022-07-15 10:28:07 -04:00
committed by GitHub
parent 813e88a8cb
commit acc48358b4
18 changed files with 908 additions and 3 deletions
+2
View File
@@ -12,6 +12,7 @@
#define BOSS_MEDAL_LEGION "Legion"
#define BOSS_MEDAL_SWARMERS "Swarmer Beacon"
#define BOSS_MEDAL_TENDRIL "Tendril"
#define BOSS_MEDAL_ROBOT "Ancient Robot"
// Score names
#define HIEROPHANT_SCORE "Hierophants Killed"
@@ -22,3 +23,4 @@
#define LEGION_SCORE "Legion Killed"
#define SWARMER_BEACON_SCORE "Swarmer Beacons Killed"
#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
#define ROBOT_SCORE "Ancient Robots Killed"
+5
View File
@@ -71,6 +71,9 @@
#define STATUS_EFFECT_TELEPORTSICK /datum/status_effect/teleport_sickness //increasing debuffs as you rapidly teleport.
#define STATUS_EFFECT_PACIFIED /datum/status_effect/pacifism //forces the pacifism trait
#define STATUS_EFFECT_BLUESPACESLOWDOWN /datum/status_effect/bluespace_slowdown //Halfs victims next move modifier
//#define STATUS_EFFECT_NECROPOLIS_CURSE /datum/status_effect/necropolis_curse
//#define CURSE_BLINDING 1 //makes the edges of the target's screen obscured
//#define CURSE_SPAWNING 2 //spawns creatures that attack the target only
@@ -126,3 +129,5 @@
#define STATUS_EFFECT_CRUSHERDAMAGETRACKING /datum/status_effect/crusher_damage //tracks total kinetic crusher damage on a target
#define STATUS_EFFECT_SYPHONMARK /datum/status_effect/syphon_mark //tracks kills for the KA death syphon module
#define STATUS_EFFECT_ADAPTIVELEARNING /datum/status_effect/adaptive_learning //tracks the total bonus damage needed to be done to target
+12
View File
@@ -178,6 +178,18 @@
/datum/status_effect/pacifism/on_remove()
REMOVE_TRAIT(owner, TRAIT_PACIFISM, id)
/datum/status_effect/bluespace_slowdown
id = "bluespace_slowdown"
alert_type = null
duration = 15 SECONDS
/datum/status_effect/bluespace_slowdown/on_apply()
owner.next_move_modifier *= 2
return ..()
/datum/status_effect/bluespace_slowdown/on_remove()
owner.next_move_modifier /= 2
// start of `living` level status procs.
/**
+7
View File
@@ -38,6 +38,13 @@
get_kill()
. = ..()
/datum/status_effect/adaptive_learning
id = "adaptive_learning"
duration = 30 SECONDS
status_type = STATUS_EFFECT_REFRESH
alert_type = null
var/bonus_damage = 0
/datum/status_effect/high_five
id = "high_five"
duration = 5 SECONDS
+47
View File
@@ -6,6 +6,7 @@
#define MODE_OPERATIVE 5
#define MODE_CREW 6
#define MODE_DET 7
#define MODE_TENDRIL 8
#define SETTING_DISK 0
#define SETTING_LOCATION 1
#define SETTING_OBJECT 2
@@ -87,6 +88,8 @@
return "You point the pinpointer to the nearest operative."
if(MODE_CREW)
return "You turn on the pinpointer."
if(MODE_TENDRIL)
return "High energy scanner active"
/obj/item/pinpointer/proc/activate_mode(mode, mob/user) //for crew pinpointer
return
@@ -459,6 +462,49 @@
var/turf/there = get_turf(H)
return istype(there) && istype(here) && there.z == here.z
/obj/item/pinpointer/tendril
name = "ancient scanning unit"
desc = "Convenient that the scanning unit for the robot survived. Seems to point to the tendrils around here."
icon_state = "pinoff_ancient"
icon_off = "pinoff_ancient"
icon_null = "pinonnull_ancient"
icon_direct = "pinondirect_ancient"
icon_close = "pinonclose_ancient"
icon_medium = "pinonmedium_ancient"
icon_far = "pinonfar_ancient"
modes = list(MODE_TENDRIL)
var/obj/structure/spawner/lavaland/target
/obj/item/pinpointer/tendril/process()
if(mode == MODE_TENDRIL)
worktendril()
point_at(target, FALSE)
else
icon_state = icon_off
/obj/item/pinpointer/tendril/proc/worktendril()
if(mode == MODE_TENDRIL)
scan_for_tendrils()
point_at(target)
else
return FALSE
/obj/item/pinpointer/tendril/proc/scan_for_tendrils()
if(mode == MODE_TENDRIL)
target = null //Resets nearest_op every time it scans
var/closest_distance = 1000
for(var/obj/structure/spawner/lavaland/T in GLOB.tendrils)
var/temp_distance = get_dist(T, get_turf(src))
if(temp_distance < closest_distance)
target = T
closest_distance = temp_distance
/obj/item/pinpointer/tendril/examine(mob/user)
. = ..()
if(mode == MODE_TENDRIL)
. += "Number of high energy signatures remaining: [length(GLOB.tendrils)]"
#undef MODE_OFF
#undef MODE_DISK
#undef MODE_NUKE
@@ -466,6 +512,7 @@
#undef MODE_SHIP
#undef MODE_OPERATIVE
#undef MODE_CREW
#undef MODE_TENDRIL
#undef SETTING_DISK
#undef SETTING_LOCATION
#undef SETTING_OBJECT
+14 -1
View File
@@ -182,8 +182,13 @@
icon = 'icons/obj/projectiles.dmi'
icon_state = "bluespace"
density = TRUE
var/mass_teleporting = TRUE
aSignal = /obj/item/assembly/signaler/anomaly/bluespace
/obj/effect/anomaly/bluespace/Initialize(mapload, new_lifespan, drops_core = TRUE, _mass_teleporting = TRUE)
. = ..()
mass_teleporting = _mass_teleporting
/obj/effect/anomaly/bluespace/anomalyEffect()
..()
for(var/mob/living/M in range(1, src))
@@ -194,6 +199,8 @@
do_teleport(AM, locate(AM.x, AM.y, AM.z), 8)
/obj/effect/anomaly/bluespace/detonate()
if(!mass_teleporting)
return
var/turf/T = pick(get_area_turfs(impact_area))
if(T)
// Calculate new position (searches through beacons in world)
@@ -257,8 +264,13 @@
name = "pyroclastic anomaly"
icon_state = "mustard"
var/ticks = 0
var/produces_slime = TRUE
aSignal = /obj/item/assembly/signaler/anomaly/pyro
/obj/effect/anomaly/pyro/Initialize(mapload, new_lifespan, drops_core = TRUE, _produces_slime = TRUE)
. = ..()
produces_slime = _produces_slime
/obj/effect/anomaly/pyro/anomalyEffect()
..()
ticks++
@@ -271,7 +283,8 @@
T.atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS | LINDA_SPAWN_OXYGEN, 5)
/obj/effect/anomaly/pyro/detonate()
INVOKE_ASYNC(src, .proc/makepyroslime)
if(produces_slime)
INVOKE_ASYNC(src, .proc/makepyroslime)
/obj/effect/anomaly/pyro/proc/makepyroslime()
var/turf/simulated/T = get_turf(src)
+4 -1
View File
@@ -156,7 +156,7 @@
#define SPAWN_MEGAFAUNA "bluh bluh huge boss"
#define SPAWN_BUBBLEGUM 6
GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/megafauna/dragon = 4, /mob/living/simple_animal/hostile/megafauna/colossus = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = SPAWN_BUBBLEGUM))
GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/megafauna/dragon = 4, /mob/living/simple_animal/hostile/megafauna/colossus = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = SPAWN_BUBBLEGUM, /mob/living/simple_animal/hostile/megafauna/ancient_robot = 4))
/turf/simulated/floor/plating/asteroid/airless/cave
var/length = 100
@@ -302,6 +302,9 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me
if(ispath(randumb, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it
megafauna_spawn_list.Remove(randumb)
if(ispath(randumb, /mob/living/simple_animal/hostile/megafauna/ancient_robot)) //same as above, we do not want multiple of these robots
megafauna_spawn_list.Remove(randumb)
new randumb(T)
#undef SPAWN_MEGAFAUNA
+3 -1
View File
@@ -22,7 +22,9 @@
/obj/effect/temp_visual,
/obj/effect/light_emitter/tendril,
/obj/effect/collapse,
/obj/effect/particle_effect/ion_trails
/obj/effect/particle_effect/ion_trails,
/obj/effect/abstract,
/obj/effect/ebeam
))
var/drop_x = 1
var/drop_y = 1
@@ -26,6 +26,7 @@
var/backstab_bonus = 30
var/light_on = FALSE
var/brightness_on = 5
var/adaptive_damage_bonus = 0
/obj/item/twohanded/kinetic_crusher/Destroy()
QDEL_LIST(trophies)
@@ -68,7 +69,16 @@
if(!C)
C = target.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
var/target_health = target.health
var/temp_force_bonus = 0
var/datum/status_effect/adaptive_learning/A = target.has_status_effect(STATUS_EFFECT_ADAPTIVELEARNING)
if(!A && adaptive_damage_bonus)
A = target.apply_status_effect(STATUS_EFFECT_ADAPTIVELEARNING)
if(A)
temp_force_bonus = A.bonus_damage
A.bonus_damage = min((A.bonus_damage + adaptive_damage_bonus), 20)
force += temp_force_bonus
..()
force -= temp_force_bonus
for(var/t in trophies)
if(!QDELETED(target))
var/obj/item/crusher_trophy/T = t
@@ -445,3 +455,23 @@
/obj/effect/temp_visual/hierophant/wall/crusher
duration = 75
/obj/item/crusher_trophy/adaptive_intelligence_core
name = "adaptive inteligence core"
desc = "Seems to be one of the cores from a massive robot. Suitable as a trophy for a kinetic crusher."
icon_state = "adaptive_core"
denied_type = /obj/item/crusher_trophy/adaptive_intelligence_core
bonus_value = 2
/obj/item/crusher_trophy/adaptive_intelligence_core/effect_desc()
return "melee hits deal <b>[bonus_value]</b> more damage per hit after hitting a target, up to <b>[bonus_value * 10]</b> extra damage to that target"
/obj/item/crusher_trophy/adaptive_intelligence_core/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.adaptive_damage_bonus += bonus_value
/obj/item/crusher_trophy/adaptive_intelligence_core/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.adaptive_damage_bonus -= bonus_value
@@ -0,0 +1,38 @@
/obj/structure/closet/crate/necropolis/ancient
name = "ancient supply cache"
/obj/structure/closet/crate/necropolis/ancient/populate_contents()
new /obj/item/pinpointer/tendril(src) // in pinpointers, with the rest of them
var/list/common_ore = list(
/obj/item/stack/ore/uranium,
/obj/item/stack/ore/silver,
/obj/item/stack/ore/gold,
/obj/item/stack/ore/plasma,
/obj/item/stack/ore/titanium
)
for(var/res in common_ore)
var/obj/item/stack/R = new res(src)
R.amount = rand(15, 30)
var/list/rare_ore = list(
/obj/item/stack/ore/diamond,
/obj/item/stack/ore/bluespace_crystal,
/obj/item/stack/sheet/mineral/abductor // few ruins of it often spawn, should be fine.
)
for(var/res in rare_ore)
var/obj/item/stack/R = new res(src)
R.amount = rand(10, 15) //ash drakes drop 5, this is perfectly fine
/obj/structure/closet/crate/necropolis/ancient/ex_act(severity)
return
/obj/structure/closet/crate/necropolis/ancient/crusher
name = "alloyed ancient supply cache"
/obj/structure/closet/crate/necropolis/ancient/crusher/populate_contents()
. = ..()
new /obj/item/crusher_trophy/adaptive_intelligence_core(src)
@@ -0,0 +1,744 @@
#define BODY_SHIELD_COOLDOWN_TIME 5 SECONDS
#define EXTRA_PLAYER_ANGER_NORMAL_CAP 6
#define EXTRA_PLAYER_ANGER_STATION_CAP 3
#define BLUESPACE 1
#define GRAV 2
#define PYRO 3
#define FLUX 4
#define VORTEX 5
#define TOP_RIGHT 1
#define TOP_LEFT 2
#define BOTTOM_RIGHT 3
#define BOTTOM_LEFT 4
/*
Vetus Speculator
An old 4 legged self learning robot made from a long gone civilization. Likes to scan and learn from things... Including crewmembers.
Hybrid ranged / melee combatant, similar to bubblegum.
It has several attacks at it's disposal. It can melee with it's body and legs, however a person will not be hit by both at once unless poorly positioned. Legs also have a weak turret on each leg, that can be broken via damage.
Every 5 seconds it creates a shield around itself, that blocks 1 hit, or multiple non damaging hits. Crusher users will need blast tube to break the shield, OR melee the robot with shield up to de-activate it.
The main feature that makes it unique, is that it has 5 modes, based on each anomaly core, that can augment it's remaning attacks.
It can charge like bubblegum. If it has a pyro core, it makes a trail of fire and temporary lava. If it is bluespace, it charges with more delay between charges, but instead teleports between charges, to make it less predictable. Grav throws people if they bump into them during charge.
It can spawn 3 anomalies around it for 15 seconds with a low chance. They do not explode / mass teleport / spawn slimes.
Finaly, for each mode, it has a special attack.
- Bluespace causes it's current target to have half attack speed for 10 seconds.
- Grav picks up rocks from the terrain, and throws them at the target.
- Pyro turns 3x3 areas around the target (but not too close) into lava.
- Flux shoots weakened tesla revolver shots at all humans nearby.
- Vortex causes a small earthquake, leading to rocks falling from the sky.
Upon reaching critical HP (normally death), it preps a 10 second self destruct, before exploding. Large tell, hard to miss.
Loot: Anomaly core that matches the mode that was picked of the robot. A pinpointer that can point to tendrils, which should be fine, as by the time this is killed, the round should be an hour or more over. As well as a variety of raw ores.
Crusher Loot: Adaptive inteligence core, a trophy that temporarly increases the force of a crusher against a target it has hit within the last 30 seconds by 2 per hit, up to 20 extra force.
Difficulty: Hard
*/
/mob/living/simple_animal/hostile/megafauna/ancient_robot
name = "\improper Vetus Speculator"
desc = "An ancient robot from a long forgotten civilization. Adapts to the enviroment, and what it finds, to be the ideal combatant."
health = 2500
maxHealth = 2500
attacktext = "shocks"
attack_sound = 'sound/machines/defib_zap.ogg'
icon = 'icons/mob/lavaland/64x64megafauna.dmi'
icon_state = "ancient_robot"
icon_living = "ancient_robot"
friendly = "stares down"
speak_emote = list("BUZZES")
universal_speak = TRUE
universal_understand = TRUE
armour_penetration = 40
melee_damage_lower = 20
melee_damage_upper = 20
melee_damage_type = BURN //Legs do the stomping, this is just a shock
speed = 5
move_to_delay = 5
ranged = TRUE
pixel_x = -16
pixel_y = -16
del_on_death = TRUE
loot = list(/obj/structure/closet/crate/necropolis/ancient)
crusher_loot = list(/obj/structure/closet/crate/necropolis/ancient/crusher)
internal_type = /obj/item/gps/internal/ancient
medal_type = BOSS_MEDAL_ROBOT
score_type = ROBOT_SCORE
deathmessage = "explodes into a shower of alloys"
footstep_type = FOOTSTEP_MOB_HEAVY //make stomp like bubble
attack_action_types = list()
var/charging = FALSE
var/revving_charge = FALSE
var/player_cooldown = 0
var/body_shield_enabled = FALSE
var/extra_player_anger = 0
var/mode = 0 //This variable controls the special attacks of the robot, one for each anomaly core.
var/exploding = FALSE
/// Legs and the connector for the legs
var/mob/living/simple_animal/hostile/ancient_robot_leg/TR = null
var/mob/living/simple_animal/hostile/ancient_robot_leg/TL = null
var/mob/living/simple_animal/hostile/ancient_robot_leg/BR = null
var/mob/living/simple_animal/hostile/ancient_robot_leg/BL = null
var/obj/effect/abstract/beam = null
/mob/living/simple_animal/hostile/megafauna/ancient_robot/Initialize(mapload, mob/living/ancient) //We spawn and move them to clear out area for the legs, rather than risk the legs getting put in a wall
. = ..()
TR = new /mob/living/simple_animal/hostile/ancient_robot_leg(loc, src, TOP_RIGHT)
TL = new /mob/living/simple_animal/hostile/ancient_robot_leg(loc, src, TOP_LEFT)
BR = new /mob/living/simple_animal/hostile/ancient_robot_leg(loc, src, BOTTOM_RIGHT)
BL = new /mob/living/simple_animal/hostile/ancient_robot_leg(loc, src, BOTTOM_LEFT)
beam = new /obj/effect/abstract(loc)
mode = pick(BLUESPACE, GRAV, PYRO, FLUX, VORTEX) //picks one of the 5 cores.
if(mode == FLUX) // Main attack is shock, so flux makes it stronger
melee_damage_lower = 25
melee_damage_upper = 25
body_shield()
add_overlay("[mode]")
add_overlay("eyes")
return INITIALIZE_HINT_LATELOAD
/mob/living/simple_animal/hostile/megafauna/ancient_robot/LateInitialize()
fix_specific_leg(TOP_RIGHT)
fix_specific_leg(TOP_LEFT)
fix_specific_leg(BOTTOM_RIGHT)
fix_specific_leg(BOTTOM_LEFT)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/Destroy()
QDEL_NULL(TR)
QDEL_NULL(TL)
QDEL_NULL(BR)
QDEL_NULL(BL)
QDEL_NULL(beam)
return ..()
/obj/item/gps/internal/ancient
icon_state = null
gpstag = "Malfunctioning Signal"
desc = "ERROR_NULL_ENTRY"
invisibility = 100
/mob/living/simple_animal/hostile/megafauna/ancient_robot/death(gibbed, allowed = FALSE)
if(allowed)
return ..()
else if(exploding) //but it refused
return
adjustBruteLoss(-1)
self_destruct()
exploding = TRUE
/mob/living/simple_animal/hostile/megafauna/ancient_robot/Life(seconds, times_fired)
..()
if(!exploding)
return
playsound(src, 'sound/items/timer.ogg', 70, 0)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/drop_loot()
var/core_type = null
switch(mode)
if(BLUESPACE)
core_type = /obj/item/assembly/signaler/anomaly/bluespace
if(GRAV)
core_type = /obj/item/assembly/signaler/anomaly/grav
if(PYRO)
core_type = /obj/item/assembly/signaler/anomaly/pyro
if(FLUX)
core_type = /obj/item/assembly/signaler/anomaly/flux
if(VORTEX)
core_type = /obj/item/assembly/signaler/anomaly/vortex
var/crate_type = pick(loot)
var/obj/structure/closet/crate/C = new crate_type(loc)
new core_type(C)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/OpenFire()
if(charging)
return
if(exploding)
return
anger_modifier = clamp(((maxHealth - health) / 50), 0, 20)
ranged_cooldown = world.time + (ranged_cooldown_time * ((10 - extra_player_anger) / 10))
if(prob(30 + anger_modifier))
triple_charge()
else if(prob(15 + anger_modifier))
spawn_anomalies()
else if(prob(60 + anger_modifier))
do_special_move()
calculate_extra_player_anger()
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/triple_charge()
if(mode == BLUESPACE)
charge(delay = 24) //An extra charge, to make up for the longer time between teleports
charge(delay = 18)
charge(delay = 12)
charge(delay = 6)
else
charge(delay = 9)
charge(delay = 6)
charge(delay = 3)
SetRecoveryTime(15)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/charge(atom/chargeat = target, delay = 5, chargepast = 2) //add limb charge as well
if(!chargeat)
return
if(mode == BLUESPACE)
new /obj/effect/temp_visual/bsg_kaboom(get_turf(src))
src.visible_message("<span class='danger'>[src] teleports somewhere nearby!</span>")
do_teleport(src, target, 7, asoundin = 'sound/effects/phasein.ogg', safe_turf_pick = TRUE) //Teleport within 7 tiles of the target
new /obj/effect/temp_visual/bsg_kaboom(get_turf(src))
TR.health_and_snap_check(FALSE)// We want the legs to instantly teleport with it, without regening
TL.health_and_snap_check(FALSE)
BR.health_and_snap_check(FALSE)
BL.health_and_snap_check(FALSE)
var/chargeturf = get_turf(chargeat)
if(!chargeturf)
return
var/dir = get_dir(src, chargeturf)
var/turf/T = get_ranged_target_turf(chargeturf, dir, chargepast)
if(!T)
return
new /obj/effect/temp_visual/dragon_swoop/bubblegum/ancient_robot(T, beam)
charging = TRUE
revving_charge = TRUE
DestroySurroundings()
walk(src, 0)
setDir(dir)
SLEEP_CHECK_DEATH(delay)
revving_charge = FALSE
var/movespeed = 0.8
walk_towards(src, T, movespeed)
SLEEP_CHECK_DEATH(get_dist(src, T) * movespeed)
walk(src, 0) // cancel the movement
charging = FALSE
/mob/living/simple_animal/hostile/megafauna/ancient_robot/MeleeAction(patience = TRUE)
if(charging)
return
return ..()
/mob/living/simple_animal/hostile/megafauna/ancient_robot/Bump(atom/A)
if(charging)
DestroySurroundings()
if(isliving(A))
var/mob/living/L = A
if(!istype(A, /mob/living/simple_animal/hostile/ancient_robot_leg))
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] tramples you into the ground!</span>")
forceMove(get_turf(L))
var/limb_to_hit = L.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, MELEE, null, null, armour_penetration))
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, TRUE)
shake_camera(L, 4, 3)
shake_camera(src, 2, 3)
if(mode == GRAV)
var/atom/throw_target = get_edge_target_turf(L, get_dir(src, get_step_away(L, src)))
L.throw_at(throw_target, 3, 2)
..()
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/body_shield()
body_shield_enabled = TRUE
visible_message("<span class='danger'>[src] creates some sort of energy shield!</span>")
add_overlay("shield")
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/disable_shield()
visible_message("<span class='danger'>[src]'s shield fails!</span>")
cut_overlay("shield")
body_shield_enabled = FALSE
addtimer(CALLBACK(src, .proc/body_shield), BODY_SHIELD_COOLDOWN_TIME)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/bullet_act(obj/item/projectile/P)
if(!body_shield_enabled)
return ..()
do_sparks(2, 1, src)
visible_message("<span class='danger'>[src]'s shield deflects [P] in a shower of sparks!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
if(P.damage)
disable_shield()
/mob/living/simple_animal/hostile/megafauna/ancient_robot/attacked_by(obj/item/I, mob/living/user)
if(!body_shield_enabled)
return ..()
do_sparks(2, 1, src)
visible_message("<span class='danger'>[src]'s shield deflects [I] in a shower of sparks!</span>", "<span class='userdanger'>You deflect the attack!</span>")
if(I.force)
disable_shield()
/mob/living/simple_animal/hostile/megafauna/ancient_robot/devour(mob/living/L)
say(pick("JKYZXAIZOBK GTGREYKX GIZOBK", "OTZKMXGZOTM YAHPKIZ YZXKTMZNY", "JKIUSVOROTM GTJ RKGXTOTM", "LOTJOTM IXOZOIGR CKGQTKYYKY")) //what can I say, I like the trope of something talking in cypher
visible_message("<span class='userdanger'>[src] disintigrates [L]!</span>","<span class='userdanger'>You analyse [L], restoring your health!</span>")
if(client || !is_station_level(z))
adjustHealth(-maxHealth * 0.1)
L.dust()
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/do_special_move()
say(pick("JKVRUEOTM LUIAYKJ VUCKX", "JKVRUEOTM KDVKXOSKTZGR GZZGIQ", "LUIAYOTM VUCKX OTZU GTUSGRUAY UHPKIZ", "VUCKX UL ZNK YAT OT ZNK NKGXZ UL SE IUXK"))
switch(mode)
if(BLUESPACE)
if(ishuman(target))
var/mob/living/carbon/human/H = target
to_chat(H, "<span class='danger'>[src] starts to slow time around you!</span>")
H.apply_status_effect(STATUS_EFFECT_BLUESPACESLOWDOWN)
if(GRAV)
visible_message("<span class='danger'>Debris from the battlefield begin to get compressed into rocks!</span>")
var/list/turfs = new/list()
var/rocks = 0
for(var/turf/T in view(4, target))
if(T.density)
continue
if(T in range (2, target))
continue
turfs += T
while(rocks < 3 && length(turfs))
var/turf/spot = pick_n_take(turfs)
new /obj/effect/temp_visual/rock(spot)
addtimer(CALLBACK(src, .proc/throw_rock, spot, target), 2 SECONDS)
rocks++
if(PYRO)
visible_message("<span class='danger'>The ground begins to heat up around you!</span>")
var/list/turfs = new/list()
var/volcanos = 0
for(var/turf/T in view(4, target))
if(T.density)
continue
if(T in range(1, target))
continue
turfs += T
while(volcanos < 3 && length(turfs))
var/turf/spot = pick_n_take(turfs)
for(var/turf/around in range(1, spot))
new /obj/effect/temp_visual/lava_warning(around)
volcanos++
if(FLUX)
for(var/mob/living/carbon/human/H in view(7, src))
var/turf/T = get_turf(H)
var/turf/S = get_turf(src)
if(!S || !T)
return
var/obj/item/projectile/energy/shock_revolver/ancient/O = new /obj/item/projectile/energy/shock_revolver/ancient(S)
O.current = S
O.yo = T.y - S.y
O.xo = T.x - S.x
O.fire()
if(VORTEX)
visible_message("<span class='danger'>[src] begins vibrate rapidly. It's causing an earthquake!</span>")
for(var/turf/turf in range(9,get_turf(target)))
if(prob(11))
new /obj/effect/temp_visual/target/ancient(turf)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/spawn_anomalies()
say(pick("JKVRUEOTM XGC VUCKX", "KXXUX OT GTUSGRE IUTZGOTSKTZ", "YZGHOROZE OT OTYZGHOROZE OT YZGHOROZE OT OTYZGH-"))
var/list/turfs = list()
var/anomalies = 0
for(var/turf/T in view(5, src))
if(T.density)
continue
turfs += T
while(anomalies < 3 && length(turfs))
var/turf/spot = pick(turfs)
turfs -= spot
switch(mode)
if(BLUESPACE)
var/obj/effect/anomaly/bluespace/A = new(spot, 150, FALSE)
A.mass_teleporting = FALSE
if(GRAV)
new /obj/effect/anomaly/grav(spot, 150, FALSE)
if(PYRO)
var/obj/effect/anomaly/pyro/A = new(spot, 150, FALSE)
A.produces_slime = FALSE
if(FLUX)
var/obj/effect/anomaly/flux/A = new(spot, 150, FALSE)
A.explosive = FALSE
if(VORTEX)
new /obj/effect/anomaly/bhole(spot, 150, FALSE)
anomalies++
return
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/throw_rock(turf/spot, mob/target)
var/turf/T = get_turf(target)
if(!spot || !T)
return
var/obj/item/projectile/rock/O = new /obj/item/projectile/rock(spot)
O.current = spot
O.yo = T.y - spot.y
O.xo = T.x - spot.x
O.fire()
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/calculate_extra_player_anger()// To make this fight harder, it scales it's attacks based on number of players. Capped lower on station.
var/anger = 0
var/cap = 0
for(var/mob/living/carbon/human/H in range(10, src))
if(stat == DEAD)
continue
anger++
cap = (is_station_level(loc.z) ? EXTRA_PLAYER_ANGER_STATION_CAP : EXTRA_PLAYER_ANGER_NORMAL_CAP)
extra_player_anger = clamp(anger,1,cap) - 1
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/self_destruct()
say(pick("OTZKMXOZE LGORAXK, YKRL JKYZXAIZ GIZOBK", "RUYY IKXZGOT, KTMGMKOTM XKIUBKXE JKTOGR", "VUCKX IUXKY 8-12 HXKGINKJ, UBKXRUGJOTM XKSGOTOTM IUXKY", "KXXUX KXXUX KXXUX KXXUX KXX-", "-ROQK ZKGXY OT XGOT- - -ZOSK ZU JOK"))
visible_message("<span class='biggerdanger'>[src] begins to overload it's core. It is going to explode!</span>")
walk(src, 0)
playsound(src,'sound/machines/alarm.ogg',100,0,5)
addtimer(CALLBACK(src, .proc/kaboom), 10 SECONDS)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/kaboom()
explosion(get_turf(src), -1, 7, 15, 20)
health = 0
death(allowed = TRUE)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/disable_legs()
TR.ranged = FALSE
TL.ranged = FALSE
BR.ranged = FALSE
BL.ranged = FALSE
/mob/living/simple_animal/hostile/megafauna/ancient_robot/face_atom(atom/A) //This is used to make the legs get near the core when a user is meleeing the core
. = ..()
switch(dir)
if(NORTH)
leg_control_system(TOP_RIGHT, 1, 2)
leg_control_system(TOP_LEFT, -1, 2)
if(SOUTH)
leg_control_system(BOTTOM_RIGHT, 1, -2)
leg_control_system(BOTTOM_LEFT, -1, -2)
if(EAST)
leg_control_system(TOP_RIGHT, 2, 1)
leg_control_system(BOTTOM_RIGHT, 2, -1)
if(WEST)
leg_control_system(TOP_LEFT, -2, 1)
leg_control_system(BOTTOM_LEFT, -2,- 1)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/fix_specific_leg(input) //Used to reset legs to specific locations
switch(input)
if(TOP_RIGHT)
leg_control_system(input, 2, 2)
if(TOP_LEFT)
leg_control_system(input, -2, 2)
if(BOTTOM_RIGHT)
leg_control_system(input, 2, -2)
if(BOTTOM_LEFT)
leg_control_system(input, -2, -2)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/leg_walking_controler(dir) //This controls the legs. Here be pain.
switch(dir)
if(NORTH)
leg_walking_orderer(TOP_RIGHT, TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT)
if(SOUTH)
leg_walking_orderer(BOTTOM_LEFT, BOTTOM_RIGHT, TOP_LEFT, TOP_RIGHT)
if(EAST)
leg_walking_orderer(TOP_RIGHT, TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT)
if(WEST)
leg_walking_orderer(BOTTOM_LEFT, BOTTOM_RIGHT, TOP_LEFT, TOP_RIGHT)
if(NORTHEAST)
leg_walking_orderer(TOP_RIGHT, TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT)
if(SOUTHEAST)
leg_walking_orderer(BOTTOM_RIGHT, TOP_LEFT, BOTTOM_LEFT, TOP_RIGHT)
if(NORTHWEST)
leg_walking_orderer(TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT)
if(SOUTHEAST)
leg_walking_orderer(BOTTOM_LEFT, TOP_LEFT, BOTTOM_RIGHT, TOP_RIGHT)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/leg_walking_orderer(A, B, C, D)
addtimer(CALLBACK(src, .proc/fix_specific_leg, A), 1)
addtimer(CALLBACK(src, .proc/fix_specific_leg, B), 2)
addtimer(CALLBACK(src, .proc/fix_specific_leg, C), 3)
addtimer(CALLBACK(src, .proc/fix_specific_leg, D), 4)
/mob/living/simple_animal/hostile/megafauna/ancient_robot/proc/leg_control_system(input, horizontal, vertical)
var/turf/target = locate(x + horizontal, y + vertical, z)
switch(input)
if(TOP_RIGHT)
TR.leg_movement(target, 0.6)
if(TOP_LEFT)
TL.leg_movement(target, 0.6)
if(BOTTOM_RIGHT)
BR.leg_movement(target, 0.6)
if(BOTTOM_LEFT)
BL.leg_movement(target, 0.6)
/mob/living/simple_animal/hostile/megafauna/anicent_robot/ex_act(severity, target)
switch(severity)
if(1)
adjustBruteLoss(25)
if(2)
adjustBruteLoss(10)
if(3)
return
/mob/living/simple_animal/hostile/megafauna/ancient_robot/Goto()
if(!exploding)
return ..()
return
/mob/living/simple_animal/hostile/megafauna/ancient_robot/Moved(atom/OldLoc, Dir, Forced = FALSE)
if(charging)
DestroySurroundings()
if(Dir)
leg_walking_controler(Dir)
if(charging)
if(mode == PYRO)
var/turf/C = get_turf(src)
new /obj/effect/temp_visual/lava_warning(C)
for(var/turf/T in range (1,src))
new /obj/effect/hotspot(T)
T.hotspot_expose(700,50,1)
if(mode == VORTEX)
var/turf/C = get_turf(src)
C.ex_act(3)
beam.forceMove(get_turf(src))
return ..()
/mob/living/simple_animal/hostile/ancient_robot_leg
name = "leg"
desc = "Legs with a mounted turret, for shooting and crushing small miners like you."
icon = 'icons/mob/lavaland/lavaland_monsters.dmi'
icon_state = "leg"
maxHealth = INFINITY //it's fine trust me
health = INFINITY
faction = list("mining", "boss") // No attacking your leg
weather_immunities = list("lava","ash")
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
flying = TRUE
check_friendly_fire = 1
ranged = TRUE
projectilesound = 'sound/weapons/gunshots/gunshot.ogg'
projectiletype = /obj/item/projectile/ancient_robot_bullet
attacktext = "stomps on"
armour_penetration = 40
melee_damage_lower = 15
melee_damage_upper = 15
obj_damage = 400
move_force = MOVE_FORCE_OVERPOWERING
move_resist = MOVE_FORCE_OVERPOWERING
pull_force = MOVE_FORCE_OVERPOWERING
sentience_type = SENTIENCE_BOSS
environment_smash = ENVIRONMENT_SMASH_RWALLS
stop_automated_movement = 1
wander = 0
robust_searching = TRUE
ranged_ignores_vision = TRUE
stat_attack = DEAD
var/range = 3
var/mob/living/simple_animal/hostile/megafauna/ancient_robot/core = null
var/fake_max_hp = 400
var/fake_hp = 400
var/fake_hp_regen = 10
var/transfer_rate = 0.75
var/who_am_i = null
var/datum/beam/leg_part
/mob/living/simple_animal/hostile/ancient_robot_leg/Initialize(mapload, mob/living/ancient, who)
. = ..()
if(!ancient)
qdel(src) //no
core = ancient
who_am_i = who
ranged_cooldown_time = rand(30, 60) // keeps them not running on the same time
addtimer(CALLBACK(src, .proc/beam_setup), 1 SECONDS)
/mob/living/simple_animal/hostile/ancient_robot_leg/Destroy()
QDEL_NULL(leg_part)
return ..()
/mob/living/simple_animal/hostile/ancient_robot_leg/Life(seconds, times_fired)
..()
health_and_snap_check(TRUE)
/mob/living/simple_animal/hostile/ancient_robot_leg/bullet_act(obj/item/projectile/P)
if(core.stat == CONSCIOUS && !core.target && core.AIStatus != AI_OFF && !core.client)
if(P.firer && get_dist(core, P.firer) <= core.aggro_vision_range)
core.FindTarget(list(P.firer), 1)
core.Goto(P.starting, core.move_to_delay, 3)
..()
/mob/living/simple_animal/hostile/ancient_robot_leg/Goto()
return // stops the legs from trying to move on their own
/mob/living/simple_animal/hostile/ancient_robot_leg/proc/beam_setup()
leg_part = Beam(core.beam, "leg_connection", 'icons/effects/effects.dmi', time=INFINITY, maxdistance=INFINITY, beam_type=/obj/effect/ebeam)
/mob/living/simple_animal/hostile/ancient_robot_leg/onTransitZ(old_z,new_z)
..()
update_z(new_z)
if(leg_part)
QDEL_NULL(leg_part)
addtimer(CALLBACK(src, .proc/beam_setup), 1 SECONDS)
/mob/living/simple_animal/hostile/ancient_robot_leg/adjustHealth(amount, updating_health = TRUE)
var/damage = amount * transfer_rate
core.adjustBruteLoss(damage)
fake_hp = clamp(fake_hp - damage, 0, fake_max_hp)
if(damage && ranged && fake_hp <= 200)
ranged = FALSE
visible_message("<span class='danger'>[src]'s turret breaks and pulls back into the leg!</span>")
if(damage && transfer_rate <= 0.25) //warn that you are not doing much damage
visible_message("<span class='danger'>[src] looks too damaged to hurt it much more!</span>")
health_and_snap_check(FALSE)
/mob/living/simple_animal/hostile/ancient_robot_leg/proc/health_and_snap_check(regen = FALSE)
if(regen)
fake_hp = min(fake_hp + fake_hp_regen, fake_max_hp)
transfer_rate = 0.75 * (fake_hp/fake_max_hp)
if(fake_hp >= 300 && !ranged)
ranged = TRUE
visible_message("<span class='danger'>[src]'s turret pops out of it!</span>")
if(get_dist(get_turf(core),get_turf(src)) <= range)
return
else
forceMove(core.loc)
core.fix_specific_leg(who_am_i)
/mob/living/simple_animal/hostile/ancient_robot_leg/proc/leg_movement(turf/T, movespeed) //byond doesn't like calling walk_towards on the legs directly
walk_towards(src, T, movespeed)
DestroySurroundings()
/mob/living/simple_animal/hostile/ancient_robot_leg/Bump(atom/A)
if(!core.charging)
return
if(isliving(A))
if(!istype(A, /mob/living/simple_animal/hostile/megafauna/ancient_robot))
var/mob/living/L = A
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] tramples you into the ground!</span>")
forceMove(get_turf(L))
var/limb_to_hit = L.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
L.apply_damage(12.5, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, MELEE, null, null, armour_penetration))
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, TRUE)
shake_camera(L, 4, 3)
shake_camera(src, 2, 3)
..()
/mob/living/simple_animal/hostile/ancient_robot_leg/ex_act(severity, target)
switch(severity)
if(1)
adjustBruteLoss(25)
if(2)
adjustBruteLoss(10)
if(3)
return
/mob/living/simple_animal/hostile/ancient_robot_leg/MeleeAction(patience = TRUE)
if(core.charging || core.exploding)
return
return ..()
/mob/living/simple_animal/hostile/ancient_robot_leg/OpenFire() // This is (idealy) to keep the turrets on the legs from shooting people that are close to the robot. The guns will only shoot if they won't hit the robot, or if the user is between a leg and another leg / robot
if(core.exploding)
return
if(get_dist(target, core) < 3)
return
if(prob(33))
return
ranged_cooldown_time = (rand(30, 60)) // keeps them not running on the same time
..()
/mob/living/simple_animal/hostile/ancient_robot_leg/Moved(atom/OldLoc, Dir, Forced = FALSE)
playsound(src, 'sound/effects/meteorimpact.ogg', 60, TRUE, 2, TRUE) //turned way down from bubblegum levels due to 4 legs
/obj/item/projectile/ancient_robot_bullet
damage = 8
damage_type = BRUTE
/obj/item/projectile/rock
name= "thrown rock"
damage = 25
damage_type = BRUTE
icon = 'icons/obj/meteor.dmi'
icon_state = "small1"
/obj/effect/temp_visual/rock
name = "floating rock"
desc = "Might want to focus on dodging, rather than looking at it."
icon = 'icons/obj/meteor.dmi'
icon_state = "small1"
duration = 20
/obj/item/projectile/energy/shock_revolver/ancient
damage = 5
/obj/item/projectile/energy/shock_revolver/ancient/Bump(atom/A, yes) // Don't want the projectile hitting the legs
if(!istype(/mob/living/simple_animal/hostile/ancient_robot_leg, A))
return ..()
var/turf/target_turf = get_turf(A)
loc = target_turf
/obj/effect/temp_visual/dragon_swoop/bubblegum/ancient_robot //this is the worst path I have ever made
icon_state = "target"
/obj/effect/temp_visual/dragon_swoop/bubblegum/ancient_robot/Initialize(mapload, target)
. = ..()
new /obj/effect/temp_visual/beam_target(get_turf(src), target) // Yup, we have to make *another* effect since beam doesn't work right with 64x64
set_light(4, l_color = "#ee2e27")
/obj/effect/temp_visual/beam_target
duration = 1.6 SECONDS
var/datum/beam/charge
/obj/effect/temp_visual/beam_target/Initialize(mapload, target)
. = ..()
charge = Beam(target, "target_beam", 'icons/effects/effects.dmi', time=1.5 SECONDS, maxdistance=INFINITY, beam_type=/obj/effect/ebeam)
/obj/effect/temp_visual/beam_target/Destroy()
QDEL_NULL(charge)
return ..()
/obj/effect/temp_visual/target/ancient
/obj/effect/temp_visual/target/ancient/fall(list/flame_hit)
var/turf/T = get_turf(src)
playsound(T,'sound/magic/fleshtostone.ogg', 80, TRUE)
new /obj/effect/temp_visual/fireball/rock(T)
sleep(duration)
if(ismineralturf(T))
var/turf/simulated/mineral/M = T
M.gets_drilled()
playsound(T, 'sound/effects/meteorimpact.ogg', 80, TRUE)
for(var/mob/living/L in T.contents)
if(istype(L, /mob/living/simple_animal/hostile/megafauna/ancient_robot))
continue
L.adjustBruteLoss(35)
to_chat(L, "<span class='userdanger'>You're hit by the falling rock!</span>")
/obj/effect/temp_visual/fireball/rock
icon = 'icons/obj/meteor.dmi'
icon_state = "small1"
#undef BODY_SHIELD_COOLDOWN_TIME
#undef EXTRA_PLAYER_ANGER_NORMAL_CAP
#undef EXTRA_PLAYER_ANGER_STATION_CAP
#undef BLUESPACE
#undef GRAV
#undef PYRO
#undef FLUX
#undef VORTEX
Binary file not shown.

Before

Width:  |  Height:  |  Size: 380 KiB

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 KiB

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

+2
View File
@@ -1829,6 +1829,7 @@
#include "code\modules\mining\laborcamp\laborstacker.dm"
#include "code\modules\mining\lavaland\ash_flora.dm"
#include "code\modules\mining\lavaland\necropolis_chests.dm"
#include "code\modules\mining\lavaland\loot\ancient_loot.dm"
#include "code\modules\mining\lavaland\loot\ashdragon_loot.dm"
#include "code\modules\mining\lavaland\loot\bubblegum_loot.dm"
#include "code\modules\mining\lavaland\loot\colossus_loot.dm"
@@ -2102,6 +2103,7 @@
#include "code\modules\mob\living\simple_animal\hostile\tree.dm"
#include "code\modules\mob\living\simple_animal\hostile\venus_human_trap.dm"
#include "code\modules\mob\living\simple_animal\hostile\winter_mobs.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\ancient_robot.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\blood_drunk_miner.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\bubblegum.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\colossus.dm"