mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 12:35:33 +01:00
8df0c5851d
## About The Pull Request In #89619, I removed the mech PKA's mining AOE and reduced the damaging AOE to a fraction of the damage. I have restored both of these aspects, but I have also applied this change to the standard PKA's mining and damage AOE. I have also included the mob biotype limitations as well. AOE modkits take 10% capacity, now allowing miners to use them in more setups. However, they conflict with one another. You can only have one AOE mod until you can get the dual AOE mod from tendrils. The AOE damage/mining effect is now a 2 tile effect rather than 1 tile effect. ## Why It's Good For The Game My intent in the previous PR was to bring mech PKA's down to standard mining limitations. So, why not improve those standards for everyone instead? The new state of mining expects you to be dealing with a lot of mobs at once. Even small vents can, on occasion, decide to spit out several goliaths back to back. That's a lot of mobs with a lot of health. Miners need AOE options more than ever. They have very little that are actually meaningful, sadly. So my intent here is that this should be an expectation for our miners to be seeking out and can fit into their current, standard gameplay. Certainly I've only felt like shit having to sacrifice a damage or cooldown mod for an AOE mod, only to get a very minor amount of damage splash for my efforts. That, and the radius doesn't usually impact most mobs as they spawn and attack from awkward angles or distances from one another where they are JUST out of reach of one another. Trying to use the splash to hit multiple enemies is often not worth it compared to just hitting one enemy at a time with a lot of damage. So, let's just go with the standard of 'Good AOE is fundamentally needed now' and worth from that premise. ## Changelog 🆑 balance: Mech PKA now once again mines turfs and does full damage on its AOE explosion (still only hitting mining mobs). balance: The standard PKA AOE mods are now by default 10% capacity. But they cannot be used with one another. balance: The standard PKA offensive AOE mod now does the PKA's full damage in its AOE. balance: Mining AOEs will affect everything within a 2 tile radius around the point of impact, up from a 1 tile radius. /🆑 --------- Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
181 lines
7.9 KiB
Plaintext
181 lines
7.9 KiB
Plaintext
///Earthquake random event.
|
|
///Draws a curve of turfs between a high and low point. These turfs will shake and eventually "collapse", forming a cut in the station that drops to the z-level below.
|
|
///Much of the actual structural damage is done through the explosions subsystem. Objects, machines, and especially people
|
|
///that aren't moved out of the epicenter area (indicated by the wobbly tiles) will not just be thrown down a z-level, but also be destroyed/maimed in the process.
|
|
/datum/round_event_control/earthquake
|
|
name = "Chasmic Earthquake"
|
|
description = "Causes an earthquake, demolishing anything caught in the fault."
|
|
typepath = /datum/round_event/earthquake
|
|
category = EVENT_CATEGORY_ENGINEERING
|
|
min_players = 20
|
|
max_occurrences = 3
|
|
earliest_start = 35 MINUTES
|
|
weight = 7
|
|
min_wizard_trigger_potency = 3
|
|
max_wizard_trigger_potency = 7
|
|
map_flags = EVENT_PLANETARY_ONLY
|
|
|
|
/datum/round_event_control/earthquake/can_spawn_event(players_amt, allow_magic)
|
|
. = ..()
|
|
if(!.)
|
|
return .
|
|
|
|
if(!length(GLOB.generic_event_spawns))
|
|
return FALSE
|
|
|
|
/datum/round_event/earthquake
|
|
start_when = 1
|
|
announce_when = 3
|
|
end_when = 25
|
|
announce_chance = 25
|
|
///The chosen location and center of our earthquake.
|
|
var/turf/epicenter
|
|
///A list of turfs that will be damaged by this event.
|
|
var/list/turfs_to_shred
|
|
///A list of turfs directly under turfs_to_shred, for creating a proper chasm to the floor below.
|
|
var/list/underbelly = list()
|
|
///The edges of our fault line, to receive light damage.
|
|
var/list/edges = list()
|
|
|
|
/datum/round_event/earthquake/setup()
|
|
epicenter = get_turf(pick(GLOB.generic_event_spawns))
|
|
if(!epicenter)
|
|
message_admins("Earthquake event failed to find a turf! generic_event_spawn landmarks may be absent or bugged. Aborting...")
|
|
return
|
|
|
|
// Give a bit of variance so our epicenter isn't always on the landmark.
|
|
epicenter = locate(epicenter.x + rand(-10, 10), epicenter.y + rand(-10, 10), epicenter.z)
|
|
|
|
message_admins("An earthquake event is about to strike the [get_area_name(epicenter)][ADMIN_JMP(epicenter)].")
|
|
|
|
// Picks two points generally opposite from each other
|
|
var/turf/fracture_point_high = locate(epicenter.x + rand(4, 10), epicenter.y + rand(4, 8), epicenter.z)
|
|
var/turf/fracture_point_low = locate(epicenter.x - rand(4, 10), epicenter.y - rand(4, 8), epicenter.z)
|
|
|
|
turfs_to_shred = block(fracture_point_high, fracture_point_low)
|
|
|
|
// Now, we filter out some of the points that are a certain distance away from a rough approximation of the fault line.
|
|
// This should create a pattern more akin to a fracture in the ground, rather than a rectangle-shaped crater of destroyed ground.
|
|
var/turf/high_midpoint = TURF_MIDPOINT(fracture_point_high, epicenter)
|
|
var/turf/low_midpoint = TURF_MIDPOINT(fracture_point_low, epicenter)
|
|
|
|
// We populate a list with the midpoints and midpoints of midpoints to create a rough line of turfs to compare distances against.
|
|
var/list/turfs_to_compare = list(
|
|
fracture_point_high,
|
|
fracture_point_low,
|
|
high_midpoint,
|
|
low_midpoint,
|
|
TURF_MIDPOINT(fracture_point_high, high_midpoint),
|
|
TURF_MIDPOINT(fracture_point_low, low_midpoint),
|
|
TURF_MIDPOINT(high_midpoint, epicenter),
|
|
TURF_MIDPOINT(low_midpoint, epicenter),
|
|
)
|
|
|
|
// Find the shortest distance between each turf in the list and the rough fault line we've just established
|
|
for(var/turf/turf_to_check in turfs_to_shred)
|
|
var/nearest_distance = get_dist(turf_to_check, epicenter)
|
|
|
|
for(var/turf/turf_to_compare in turfs_to_compare)
|
|
nearest_distance = min(get_dist(turf_to_check, turf_to_compare), nearest_distance)
|
|
|
|
// If the turf is too far from any point on our fault line estimate, we remove it. If it's on the edge, we lightly damage it
|
|
if(nearest_distance > 2)
|
|
if(nearest_distance == 3)
|
|
edges += turf_to_check
|
|
turfs_to_shred -= turf_to_check
|
|
|
|
// Grab a list of turfs below the ones we're going to destroy.
|
|
// If we're at the bottom layer, it will just tear up the flooring a bunch (exposing it to LAVA).
|
|
for(var/turf/turf_to_quake in turfs_to_shred)
|
|
underbelly += GET_TURF_BELOW(turf_to_quake)
|
|
|
|
/datum/round_event/earthquake/announce(fake)
|
|
priority_announce("Planetary monitoring systems indicate a devastating seismic event in the near future.", "Seismic Report")
|
|
|
|
/datum/round_event/earthquake/start()
|
|
notify_ghosts(
|
|
"The earthquake's epicenter has been located: [get_area_name(epicenter)]!",
|
|
source = epicenter,
|
|
header = "Rumble Rumble Rumble!",
|
|
)
|
|
|
|
/datum/round_event/earthquake/tick()
|
|
if(ISMULTIPLE(activeFor, 5))
|
|
for(var/turf/turf_to_quake in turfs_to_shred)
|
|
turf_to_quake.Shake(pixelshiftx = 0.1, pixelshifty = 0.1, duration = 1 SECONDS)
|
|
|
|
if(ISMULTIPLE(activeFor, 10))
|
|
for(var/mob/earthquake_witness as anything in GLOB.player_list)
|
|
if(!is_station_level(earthquake_witness.z))
|
|
continue
|
|
shake_camera(earthquake_witness, 1 SECONDS, 1 + (activeFor % 10))
|
|
earthquake_witness.playsound_local(
|
|
earthquake_witness,
|
|
pick(
|
|
'sound/ambience/earth_rumble/earth_rumble_distant1.ogg',
|
|
'sound/ambience/earth_rumble/earth_rumble_distant2.ogg',
|
|
'sound/ambience/earth_rumble/earth_rumble_distant3.ogg',
|
|
'sound/ambience/earth_rumble/earth_rumble_distant4.ogg',
|
|
),
|
|
75,
|
|
)
|
|
|
|
for(var/turf/turf_to_quake in underbelly)
|
|
turf_to_quake.Shake(pixelshiftx = 0.1, pixelshifty = 0.1, duration = 1 SECONDS)
|
|
|
|
if(activeFor == end_when - 2)
|
|
for(var/turf/turf_to_quake in turfs_to_shred)
|
|
turf_to_quake.Shake(pixelshiftx = 0.5, pixelshifty = 0.5, duration = 1 SECONDS)
|
|
for(var/mob/living/quake_victim in turf_to_quake)
|
|
quake_victim.Knockdown(7 SECONDS)
|
|
quake_victim.Paralyze(5 SECONDS)
|
|
to_chat(quake_victim, span_warning("The ground quakes violently beneath you, throwing you off your feet!"))
|
|
|
|
for(var/turf/turf_to_quake in underbelly)
|
|
turf_to_quake.Shake(pixelshiftx = 0.5, pixelshifty = 0.5, duration = 1 SECONDS)
|
|
for(var/mob/living/carbon/quake_victim in turf_to_quake)
|
|
to_chat(quake_victim, span_warning("Damn, I wonder what that rumbling noise is?")) ///You're about to find out
|
|
|
|
// Step one of the destruction, which clears natural tiles out from the underbelly and does a bit of initial damage to the topside.
|
|
if(activeFor == end_when - 1)
|
|
for(var/turf/turf_to_shred in turfs_to_shred)
|
|
if(prob(90))
|
|
SSexplosions.lowturf += turf_to_shred
|
|
for(var/turf/turf_to_clear in underbelly)
|
|
if(ismineralturf(turf_to_clear))
|
|
var/turf/closed/mineral/rock_to_clear = turf_to_clear
|
|
rock_to_clear.gets_drilled()
|
|
for(var/turf/turf_to_quake in edges)
|
|
turf_to_quake.Shake(pixelshiftx = 0.5, pixelshifty = 0.5, duration = 1 SECONDS)
|
|
playsound(epicenter, 'sound/misc/metal_creak.ogg', 125, TRUE)
|
|
|
|
/datum/round_event/earthquake/end()
|
|
playsound(epicenter, 'sound/ambience/earth_rumble/earth_rumble.ogg', 125)
|
|
for(var/mob/earthquake_witness as anything in GLOB.player_list)
|
|
if(!is_station_level(earthquake_witness.z) || !is_mining_level(earthquake_witness.z))
|
|
continue
|
|
shake_camera(earthquake_witness, 2 SECONDS, 4)
|
|
earthquake_witness.playsound_local(earthquake_witness, 'sound/effects/explosion/explosionfar.ogg', 75)
|
|
|
|
// Step two of the destruction, which detonates the turfs in the earthquake zone. There is no actual explosion, meaning stuff around the earthquake zone is perfectly safe.
|
|
// All turfs, and everything else that IS in the earthquake zone, however, will behave as if it were bombed.
|
|
// If you are caught in the earthquake zone, you will not only die but probably be torn apart in the process.
|
|
for(var/turf/turf_to_shred in turfs_to_shred)
|
|
if(prob(10))
|
|
SSexplosions.medturf += turf_to_shred
|
|
else
|
|
SSexplosions.highturf += turf_to_shred
|
|
|
|
if(isasteroidturf(turf_to_shred) && prob(95))
|
|
turf_to_shred.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
|
|
|
for(var/mob/living/carbon/quake_victim in turf_to_shred)
|
|
if(quake_victim.client)
|
|
quake_victim.client.give_award(/datum/award/achievement/misc/earthquake_victim, quake_victim)
|
|
|
|
for(var/turf/edge_to_damage in edges)
|
|
if(prob(25))
|
|
SSexplosions.medturf += edge_to_damage
|
|
else
|
|
SSexplosions.lowturf += edge_to_damage
|