Files
SmArtKarandGitHub 9b110eb64e Reworks and fixes blood drunk miner megafauna (#96286)
## About The Pull Request

Blood-drunk miner has been reworked to change it from a DPS race into a
more dynamic fight

- Buffed health from 900 to 1300 (45% increase), slightly increased
speed (3 -> 2.5), increased saw damage (6/10 -> 8/12) to compensate for
other changes below
- Slightly reduced PKA shot damage (20 -> 18)
- Saw attacks now have a slightly longer delay inbetween hits
(especially in unfolded form), ***no longer are guaranteed to hit no
matter what*** (was a bug which forced players to eat 50 damage to the
face) and slow down the miner during the combo
- Singular PKA shot has been replaced with a telegraphed barrage of 3
projectiles, during which the miner cannot move, letting players gain
some distance
- Dash is no longer a teleport but a proper charge akin to that of
lobstrocities with a very short chargeup that deals no damage or
knockdown, but allows the miner to travel further
- Miner's attacks no longer give the target stun immunity for a brief
moment (why?)
- Default PKA it drops has been replaced with an infernal version, which
comes with a cheaper (30% vs 50% of the default one) in-built rapid
repeater (that also has a less punishing miss delay)

<img width="169" height="143" alt="Aseprite_UfXRbgVuqB"
src="https://github.com/user-attachments/assets/3ac257a4-5443-4c7f-a891-4e69f8188cb4"
/>

---

Full fight with a single basic pen and 2 legion cores, no PKC trophies:
(fumbled a bit midway though, pre-PKA projectile damage nerf)


https://github.com/user-attachments/assets/40c8af0d-035c-49da-861b-5e74ca7d7551

## Why It's Good For The Game

Current blood-drunk miner is a hard DPS check with unavoidable damage
(both due to the bug and instant dashes/PKA hits) that simply requires
you to facetank the damage using heals and kill it first before it kills
you.
This should make the fight a bit longer, more engaging and fairer than
it is right now.

## Changelog
🆑
add: Blood-drunk miner now drops an infernal PKA with an in-built
improved rapid repeater modification
balance: Blood-drunk miner has been reworked with new attacks and
patterns
fix: Blood-drunk miner's combos are no longer guaranteed to land even if
you move away from it
/🆑
2026-06-05 18:03:12 +02:00

127 lines
4.4 KiB
Plaintext

/obj/structure/closet/cardboard
name = "large cardboard box"
desc = "Just a box..."
icon_state = "cardboard"
mob_storage_capacity = 1
resistance_flags = FLAMMABLE
max_integrity = 70
integrity_failure = 0
can_weld_shut = 0
cutting_tool = /obj/item/wirecutters
material_drop = /obj/item/stack/sheet/cardboard
material_drop_amount = 4
custom_materials = list(/datum/material/cardboard = SHEET_MATERIAL_AMOUNT * 4)
delivery_icon = "deliverybox"
anchorable = FALSE
open_sound = 'sound/machines/cardboard_box.ogg'
close_sound = 'sound/machines/cardboard_box.ogg'
open_sound_volume = 35
close_sound_volume = 35
has_closed_overlay = FALSE
door_anim_time = 0 // no animation
can_install_electronics = FALSE
paint_jobs = null
/// Cooldown controlling when the box can trigger the Metal Gear Solid-style '!' alert.
COOLDOWN_DECLARE(alert_cooldown)
/// How much time must pass before the box can trigger the next Metal Gear Solid-style '!' alert.
var/time_between_alerts = 60 SECONDS
/// List of viewers around the box
var/list/alerted
/// How fast a mob can move inside this box
var/move_speed_multiplier = 1
/// If the speed multiplier should be applied to mobs inside this box
var/move_delay = FALSE
/obj/structure/closet/cardboard/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_SPEED_POTION_APPLIED, PROC_REF(on_speed_potioned))
/obj/structure/closet/cardboard/proc/on_speed_potioned(datum/source)
SIGNAL_HANDLER
move_speed_multiplier *= 0.2
/obj/structure/closet/cardboard/relaymove(mob/living/user, direction)
if(opened || move_delay || user.incapacitated || !isturf(loc) || !has_gravity(loc))
return
move_delay = TRUE
var/oldloc = loc
try_step_multiz(direction)
user.setDir(dir)
if(oldloc != loc)
addtimer(CALLBACK(src, PROC_REF(ResetMoveDelay)), CONFIG_GET(number/movedelay/walk_delay) * move_speed_multiplier)
else
move_delay = FALSE
/obj/structure/closet/cardboard/proc/ResetMoveDelay()
move_delay = FALSE
/obj/structure/closet/cardboard/before_open(mob/living/user, force)
. = ..()
if(!.)
return FALSE
LAZYINITLIST(alerted)
var/do_alert = (COOLDOWN_FINISHED(src, alert_cooldown) && (locate(/mob/living) in contents))
if(!do_alert)
return TRUE
alerted.Cut() // just in case we runtimed and the list didn't get cleared in after_open
// Cache the list before we open the box.
for(var/mob/living/alerted_mob in viewers(7, src))
alerted += alerted_mob
return TRUE
/obj/structure/closet/cardboard/after_open(mob/living/user, force)
. = ..()
if(!length(alerted))
return
COOLDOWN_START(src, alert_cooldown, time_between_alerts)
for(var/mob/living/alerted_mob as anything in alerted)
if(alerted_mob.stat != CONSCIOUS || alerted_mob.is_blind())
continue
if(!INCAPACITATED_IGNORING(alerted_mob, INCAPABLE_RESTRAINTS))
alerted_mob.face_atom(src)
alerted_mob.do_alert_animation()
alerted.Cut()
playsound(loc, 'sound/machines/chime.ogg', 50, FALSE, -5)
/// Does the MGS ! animation
/atom/proc/do_alert_animation(duration = 1 SECONDS)
var/mutable_appearance/alert = mutable_appearance('icons/obj/storage/closet.dmi', "cardboard_special")
SET_PLANE_EXPLICIT(alert, ABOVE_LIGHTING_PLANE, src)
var/atom/movable/flick_visual/exclamation = flick_overlay_view(alert, duration)
exclamation.alpha = 0
exclamation.pixel_x = -pixel_x
animate(exclamation, pixel_z = 32, alpha = 255, time = duration * 0.5, easing = ELASTIC_EASING)
animate(time = duration * 0.35)
animate(pixel_z = 64, alpha = 0, time = duration * 0.15, easing = SINE_EASING)
// We use this list to update plane values on parent z change, which is why we need the timer too
// I'm sorry :(
LAZYADD(update_on_z, exclamation)
// Intentionally less time then the flick so we don't get weird shit
addtimer(CALLBACK(src, PROC_REF(forget_alert), exclamation), max(0.05 SECONDS, duration - 0.1 SECONDS), TIMER_CLIENT_TIME)
/atom/proc/forget_alert(atom/movable/flick_visual/exclamation)
LAZYREMOVE(update_on_z, exclamation)
/obj/structure/closet/cardboard/metal
name = "large metal box"
desc = "THE COWARDS! THE FOOLS!"
icon_state = "metalbox"
max_integrity = 500
mob_storage_capacity = 5
resistance_flags = NONE
move_speed_multiplier = 2
cutting_tool = /obj/item/weldingtool
open_sound = 'sound/machines/crate/crate_open.ogg'
close_sound = 'sound/machines/crate/crate_close.ogg'
open_sound_volume = 35
close_sound_volume = 50
custom_materials = list(/datum/material/alloy/plasteel = SHEET_MATERIAL_AMOUNT * 4)
material_drop = /obj/item/stack/sheet/plasteel