mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-06-07 07:09:17 +01:00
4d1e34322f
## About The Pull Request [Removes the pretense of relative multiz levels](https://github.com/tgstation/tgstation/pull/76248/commits/0293fdc2bd8c8af7a0d18da33265e060789c71f7) Our multiz system does not support having a z level that is only connected one way, or which goes down backwards or anything like that. That's a fiction of the trait system, the actual backend has never really supported this. This pr removes the assumptions we were making backend around this, and uses that to save cpu time. I am also converting multiz_levels from an assoc list to a pure one, which saves significantly on access times and cleans up the code somewhat. Also I'm making the get_below/get_above procs into macros, for the sake of cpu time. [Converts the starlight disease to use BYOND's directional defines instead of our own](https://github.com/tgstation/tgstation/commit/7d698f02d991eb4e1bde56314c657cf6e48ceb5d) To some extent spurred on by https://github.com/DaedalusDock/daedalusdock/pull/298, tho it was known before ## Why It's Good For The Game Faster multiz code, faster init, etc etc etc
177 lines
7.8 KiB
Plaintext
177 lines
7.8 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 recieve 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/misc/earth_rumble_distant1.ogg',
|
|
'sound/misc/earth_rumble_distant2.ogg',
|
|
'sound/misc/earth_rumble_distant3.ogg',
|
|
'sound/misc/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(give_exp = FALSE)
|
|
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/misc/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/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
|