mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 07:33:34 +01:00
Adds supermatter events (#21406)
* Class D and C SM events * see above * B-Class events * A-class events * S-class events (ebents done) * Start of console * datumization p1 * supermatter_event * beginning of tgui * adds new circuitboard for anomaly monitoring * more supermatter event code * forgot to change last_events * tgui progression * fix the freakin errors * forgot to move this to on_start() * some small fixes - tgui stuff to change * bug fixes * TGUI take two - in progress * TGUI and circuit board removal for anom console * Fixes world time spamming events * S class event fix * Fixes D class events * Fixes worldtime based event calling * Apply suggestions from code review Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> * ACTUAL logging * I blame copypaste * Goddamit --------- Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> Co-authored-by: Burzah <mbsx@proton.me> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
This commit is contained in:
@@ -59,17 +59,7 @@
|
||||
continue
|
||||
// if we are going to break this one
|
||||
if(prob(APC_BREAK_PROBABILITY))
|
||||
// if it has internal wires, cut the power wires
|
||||
if(A.wires)
|
||||
if(!A.wires.is_cut(WIRE_MAIN_POWER1))
|
||||
A.wires.cut(WIRE_MAIN_POWER1)
|
||||
if(!A.wires.is_cut(WIRE_MAIN_POWER2))
|
||||
A.wires.cut(WIRE_MAIN_POWER2)
|
||||
// if it was operating, toggle off the breaker
|
||||
if(A.operating)
|
||||
A.toggle_breaker()
|
||||
// no matter what, ensure the area knows something happened to the power
|
||||
current_area.powernet.power_change()
|
||||
A.apc_short()
|
||||
affected_apc_count++
|
||||
log_and_message_admins("APC Short Out event has shorted out [affected_apc_count] APCs.")
|
||||
|
||||
|
||||
@@ -1012,6 +1012,19 @@
|
||||
to_chat(user, "You emag the APC interface.")
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/apc/proc/apc_short()
|
||||
// if it has internal wires, cut the power wires
|
||||
if(wires)
|
||||
if(!wires.is_cut(WIRE_MAIN_POWER1))
|
||||
wires.cut(WIRE_MAIN_POWER1)
|
||||
if(!wires.is_cut(WIRE_MAIN_POWER2))
|
||||
wires.cut(WIRE_MAIN_POWER2)
|
||||
// if it was operating, toggle off the breaker
|
||||
if(operating)
|
||||
toggle_breaker()
|
||||
// no matter what, ensure the area knows something happened to the power
|
||||
apc_area.powernet.power_change()
|
||||
|
||||
/// *************
|
||||
/// APC subtypes
|
||||
/// *************
|
||||
|
||||
@@ -155,6 +155,8 @@
|
||||
var/dynamic_heat_resistance = 1
|
||||
///Uses powerloss_dynamic_scaling and combined_gas to lessen the effects of our powerloss functions
|
||||
var/powerloss_inhibitor = 1
|
||||
///value plus T0C = temp at which the SM starts to take damage. Variable for event usage
|
||||
var/heat_penalty_threshold = HEAT_PENALTY_THRESHOLD
|
||||
///Based on co2 percentage, slowly moves between 0 and 1. We use it to calc the powerloss_inhibitor
|
||||
var/powerloss_dynamic_scaling= 0
|
||||
///Affects the amount of radiation the sm makes. We multiply this with power to find the rads.
|
||||
@@ -206,6 +208,23 @@
|
||||
///Disables the sm's proccessing totally.
|
||||
var/processes = TRUE
|
||||
|
||||
//vars used for supermatter events (Anomalous crystal activityw)
|
||||
/// Do we have an active event?
|
||||
var/datum/supermatter_event/event_active
|
||||
///flat multiplies the amount of gas released by the SM.
|
||||
var/gas_multiplier = 1
|
||||
///flat multiplies the heat released by the SM
|
||||
var/heat_multiplier = 1
|
||||
///amount of EER to ADD
|
||||
var/power_additive = 0
|
||||
/// A list of all previous events
|
||||
var/list/last_events
|
||||
/// Time of next event
|
||||
var/next_event_time
|
||||
/// Run S-Class event? So we can only run one S-class event per round per crystal
|
||||
var/has_run_sclass = FALSE
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/Initialize(mapload)
|
||||
. = ..()
|
||||
supermatter_id = global_supermatter_id++
|
||||
@@ -220,6 +239,7 @@
|
||||
if(is_main_engine)
|
||||
GLOB.main_supermatter_engine = src
|
||||
soundloop = new(list(src), TRUE)
|
||||
make_next_event_time()
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/Destroy()
|
||||
if(warp)
|
||||
@@ -399,6 +419,8 @@
|
||||
visible_message("<span class='warning'>[src] melts through [T]!</span>")
|
||||
return
|
||||
|
||||
try_events()
|
||||
|
||||
//We vary volume by power, and handle OH FUCK FUSION IN COOLING LOOP noises.
|
||||
if(power)
|
||||
soundloop.volume = clamp((50 + (power / 50)), 50, 100)
|
||||
@@ -439,7 +461,7 @@
|
||||
//((((some value between 0.5 and 1 * temp - ((273.15 + 40) * some values between 1 and 10)) * some number between 0.25 and knock your socks off / 150) * 0.25
|
||||
//Heat and mols account for each other, a lot of hot mols are more damaging then a few
|
||||
//Mols start to have a positive effect on damage after 350
|
||||
damage = max(damage + (max(clamp(removed.total_moles() / 200, 0.5, 1) * removed.temperature - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0)
|
||||
damage = max(damage + (max(clamp(removed.total_moles() / 200, 0.5, 1) * removed.temperature - ((T0C + heat_penalty_threshold)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0)
|
||||
//Power only starts affecting damage when it is above 5000
|
||||
damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500) * DAMAGE_INCREASE_MULTIPLIER, 0)
|
||||
//Molar count only starts affecting damage when it is above 1800
|
||||
@@ -449,7 +471,7 @@
|
||||
//healing damage
|
||||
if(combined_gas < MOLE_PENALTY_THRESHOLD)
|
||||
//Only has a net positive effect when the temp is below 313.15, heals up to 2 damage. Psycologists increase this temp min by up to 45
|
||||
damage = max(damage + (min(removed.temperature - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150 ), 0)
|
||||
damage = max(damage + (min(removed.temperature - (T0C + heat_penalty_threshold), 0) / 150 ), 0)
|
||||
|
||||
//Check for holes in the SM inner chamber
|
||||
for(var/t in RANGE_TURFS(1, loc))
|
||||
@@ -538,15 +560,15 @@
|
||||
//Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock
|
||||
//is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall.
|
||||
//Power * 0.55 * (some value between 1.5 and 23) / 5
|
||||
removed.temperature += ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER)
|
||||
removed.temperature += (((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER) * heat_multiplier)
|
||||
//We can only emit so much heat, that being 57500
|
||||
removed.temperature = max(0, min(removed.temperature, 2500 * dynamic_heat_modifier))
|
||||
|
||||
//Calculate how much gas to release
|
||||
//Varies based on power and gas content
|
||||
removed.toxins += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)
|
||||
removed.toxins += max(((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER) * gas_multiplier, 0)
|
||||
//Varies based on power, gas content, and heat
|
||||
removed.oxygen += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)
|
||||
removed.oxygen += max((((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER) * gas_multiplier, 0)
|
||||
|
||||
if(produces_gas)
|
||||
env.merge(removed)
|
||||
@@ -649,7 +671,7 @@
|
||||
//Boom (Mind blown)
|
||||
if(damage > explosion_point)
|
||||
countdown()
|
||||
|
||||
power += power_additive
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/bullet_act(obj/item/projectile/Proj)
|
||||
@@ -1152,6 +1174,47 @@
|
||||
power += amount
|
||||
message_admins("[src] has been activated and given an increase EER of [amount] at [ADMIN_JMP(src)]")
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/proc/make_next_event_time()
|
||||
// Some completely random bullshit to make a "bell curve"
|
||||
var/fake_time = rand(5 MINUTES, 25 MINUTES)
|
||||
if(fake_time < 15 MINUTES && prob(30))
|
||||
fake_time += rand(2 MINUTES, 10 MINUTES)
|
||||
else if(fake_time > 15 MINUTES && prob(30))
|
||||
fake_time -= rand(2 MINUTES, 10 MINUTES)
|
||||
next_event_time += fake_time
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/proc/try_events()
|
||||
if(has_been_powered == FALSE)
|
||||
return
|
||||
if(!next_event_time) // for when the SM starts
|
||||
make_next_event_time()
|
||||
return
|
||||
if(world.time < next_event_time)
|
||||
return
|
||||
if(event_active)
|
||||
return
|
||||
var/static/list/events = list(/datum/supermatter_event/delta_tier = 40,
|
||||
/datum/supermatter_event/charlie_tier = 40,
|
||||
/datum/supermatter_event/bravo_tier = 15,
|
||||
/datum/supermatter_event/alpha_tier = 5,
|
||||
/datum/supermatter_event/sierra_tier = 1)
|
||||
|
||||
var/datum/supermatter_event/event = pick(subtypesof(pickweight(events)))
|
||||
if(istype(event, /datum/supermatter_event/sierra_tier) && has_run_sclass)
|
||||
make_next_event_time()
|
||||
return // We're only gonna have one s-class per round, take a break engineers
|
||||
run_event(event)
|
||||
make_next_event_time()
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/proc/run_event(datum/supermatter_event/event) // mostly admin testing and stuff
|
||||
if(ispath(event))
|
||||
event = new event(src)
|
||||
if(!istype(event))
|
||||
log_debug("Attempted supermatter event aborted due to incorrect path. Incorrect path type: [event.type].")
|
||||
return
|
||||
event.start_event()
|
||||
|
||||
|
||||
#undef HALLUCINATION_RANGE
|
||||
#undef GRAVITATIONAL_ANOMALY
|
||||
#undef FLUX_ANOMALY
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/datum/supermatter_event
|
||||
var/name = "Unknown X-K (Report this to coders)"
|
||||
var/obj/machinery/atmospherics/supermatter_crystal/supermatter
|
||||
var/datum/gas_mixture/environment
|
||||
/// Probability of the event not running, higher tiers being rarer
|
||||
var/threat_level
|
||||
var/duration
|
||||
|
||||
/datum/supermatter_event/New(obj/machinery/atmospherics/supermatter_crystal/_supermatter)
|
||||
. = ..()
|
||||
supermatter = _supermatter
|
||||
if(!supermatter)
|
||||
stack_trace("a /datum/supermatter_event was called without an involved supermatter.")
|
||||
return
|
||||
if(!istype(supermatter))
|
||||
stack_trace("a /datum/supermatter_event was called with (name: [supermatter], type: [supermatter.type]) instead of a supermatter!")
|
||||
return
|
||||
var/turf/T = get_turf(supermatter)
|
||||
environment = T.return_air()
|
||||
|
||||
/datum/supermatter_event/proc/start_event()
|
||||
supermatter.event_active = src
|
||||
on_start()
|
||||
alert_engi()
|
||||
if(duration)
|
||||
addtimer(CALLBACK(src, PROC_REF(on_end)), duration)
|
||||
|
||||
/datum/supermatter_event/proc/on_start()
|
||||
return
|
||||
|
||||
/datum/supermatter_event/proc/alert_engi()
|
||||
return
|
||||
|
||||
/datum/supermatter_event/proc/on_end()
|
||||
sm_radio_say("Anomalous crystal activity has ended.")
|
||||
supermatter.heat_penalty_threshold = HEAT_PENALTY_THRESHOLD
|
||||
supermatter.gas_multiplier = 1
|
||||
supermatter.power_additive = 0
|
||||
supermatter.heat_multiplier = 1
|
||||
supermatter.event_active = null
|
||||
supermatter.last_events += src
|
||||
|
||||
/datum/supermatter_event/proc/sm_radio_say(text)
|
||||
if(!text)
|
||||
return
|
||||
supermatter.radio.autosay(text, supermatter, "Engineering", list(supermatter.z))
|
||||
|
||||
/datum/supermatter_event/proc/general_radio_say(text)
|
||||
if(!text)
|
||||
return
|
||||
supermatter.radio.autosay(text, supermatter, null, list(supermatter.z))
|
||||
|
||||
// Below this are procs used for the SM events, in order of severity
|
||||
|
||||
//D class events
|
||||
|
||||
/datum/supermatter_event/delta_tier
|
||||
threat_level = SM_EVENT_THREAT_D
|
||||
duration = 10 SECONDS
|
||||
|
||||
/datum/supermatter_event/delta_tier/alert_engi()
|
||||
sm_radio_say("Abnormal crystal activity detected! Activity class: [name].")
|
||||
|
||||
// sleeping gas
|
||||
/datum/supermatter_event/delta_tier/sleeping_gas
|
||||
name = "D-1"
|
||||
|
||||
/datum/supermatter_event/delta_tier/sleeping_gas/on_start()
|
||||
environment.sleeping_agent += 200
|
||||
|
||||
// nitrogen
|
||||
/datum/supermatter_event/delta_tier/nitrogen
|
||||
name = "D-2"
|
||||
|
||||
/datum/supermatter_event/delta_tier/nitrogen/on_start()
|
||||
environment.nitrogen += 200
|
||||
|
||||
// carbon dioxide
|
||||
/datum/supermatter_event/delta_tier/carbon_dioxide
|
||||
name = "D-3"
|
||||
|
||||
/datum/supermatter_event/delta_tier/carbon_dioxide/on_start()
|
||||
environment.carbon_dioxide += 250
|
||||
|
||||
|
||||
// C class events
|
||||
|
||||
/datum/supermatter_event/charlie_tier
|
||||
threat_level = SM_EVENT_THREAT_C
|
||||
duration = 15 SECONDS
|
||||
|
||||
/datum/supermatter_event/charlie_tier/alert_engi()
|
||||
sm_radio_say("Anomalous crystal activity detected. Activity class: [name]. Operator intervention may be required.")
|
||||
|
||||
// oxygen
|
||||
/datum/supermatter_event/charlie_tier/oxygen
|
||||
name = "C-1"
|
||||
|
||||
/datum/supermatter_event/charlie_tier/oxygen/on_start()
|
||||
environment.oxygen += 250
|
||||
|
||||
// plasma
|
||||
/datum/supermatter_event/charlie_tier/plasma
|
||||
name = "C-2"
|
||||
|
||||
/datum/supermatter_event/charlie_tier/plasma/on_start()
|
||||
environment.toxins += 200
|
||||
|
||||
// lowers the temp required for the SM to take damage.
|
||||
/datum/supermatter_event/charlie_tier/heat_penalty_threshold
|
||||
name = "C-3"
|
||||
duration = 5 MINUTES
|
||||
|
||||
/datum/supermatter_event/charlie_tier/heat_penalty_threshold/on_start()
|
||||
supermatter.heat_penalty_threshold -= -73
|
||||
|
||||
//Class B events
|
||||
/datum/supermatter_event/bravo_tier
|
||||
threat_level = SM_EVENT_THREAT_B
|
||||
duration = 1 MINUTES
|
||||
|
||||
/datum/supermatter_event/bravo_tier/alert_engi()
|
||||
sm_radio_say("Anomalous crystal activity detected! Activity class: [name]. Operator intervention is required!")
|
||||
|
||||
|
||||
// more gas
|
||||
/datum/supermatter_event/bravo_tier/gas_multiply
|
||||
name = "B-1"
|
||||
|
||||
/datum/supermatter_event/bravo_tier/gas_multiply/on_start()
|
||||
supermatter.gas_multiplier = 1.5
|
||||
|
||||
|
||||
/datum/supermatter_event/bravo_tier/heat_multiplier
|
||||
name = "B-2"
|
||||
|
||||
/datum/supermatter_event/bravo_tier/heat_multiplier/on_start()
|
||||
supermatter.heat_multiplier = 1.25
|
||||
|
||||
/datum/supermatter_event/bravo_tier/power_additive
|
||||
name = "B-3"
|
||||
|
||||
/datum/supermatter_event/bravo_tier/power_additive/on_start()
|
||||
supermatter.power_additive = 2000
|
||||
|
||||
//A class events
|
||||
/datum/supermatter_event/alpha_tier
|
||||
threat_level = SM_EVENT_THREAT_A
|
||||
duration = 10 SECONDS
|
||||
|
||||
/datum/supermatter_event/alpha_tier/alert_engi()
|
||||
sm_radio_say("ALERT: Critical anomalous crystal activity detected! Activity class: [name]. IMMEDIATE Operator intervention is REQUIRED!")
|
||||
|
||||
/datum/supermatter_event/alpha_tier/apc_short
|
||||
name = "A-1"
|
||||
|
||||
/datum/supermatter_event/alpha_tier/apc_short/on_start()
|
||||
var/area/current_area = get_area(src)
|
||||
var/obj/machinery/power/apc/A = current_area.get_apc()
|
||||
A.apc_short()
|
||||
|
||||
/datum/supermatter_event/alpha_tier/air_siphon
|
||||
name = "A-2"
|
||||
|
||||
/datum/supermatter_event/alpha_tier/air_siphon/on_start()
|
||||
var/area/current_area = get_area(src)
|
||||
var/obj/machinery/alarm/engine/A = current_area.master_air_alarm
|
||||
A.apply_mode(AALARM_MODE_SCRUBBING)
|
||||
|
||||
/datum/supermatter_event/alpha_tier/gas_multiplier
|
||||
name = "A-3"
|
||||
duration = 2 MINUTES
|
||||
|
||||
/datum/supermatter_event/alpha_tier/gas_multiplier/on_start()
|
||||
supermatter.gas_multiplier = 4
|
||||
|
||||
// S-tier events are special. They are very dangerous, but give a 5 minute warning to the engis.
|
||||
/datum/supermatter_event/sierra_tier
|
||||
threat_level = SM_EVENT_THREAT_S
|
||||
duration = 7 MINUTES // 2 MINUTES of s-tier anomaly
|
||||
|
||||
/datum/supermatter_event/sierra_tier/alert_engi()
|
||||
general_radio_say("ALERT: Anomalous supermatter state expected in: 5 minutes.")
|
||||
sm_radio_say("EMERGENCY ALERT: 5 MINUTES UNTIL [supermatter] EXHIBITS [name] CLASS ANOMALOUS ACTIVITY!")
|
||||
|
||||
/datum/supermatter_event/sierra_tier/on_start()
|
||||
addtimer(CALLBACK(src, PROC_REF(start_sierra_event)), 5 MINUTES)
|
||||
supermatter.has_run_sclass = TRUE
|
||||
|
||||
/datum/supermatter_event/sierra_tier/proc/start_sierra_event()
|
||||
general_radio_say("ALERT: ANOMALOUS SUPERMATTER STATE DETECTED!")
|
||||
sm_radio_say("EMERGENCY ALERT: Class [name] anomalous behavior in progress!")
|
||||
|
||||
//S class events
|
||||
//Arc-type
|
||||
/datum/supermatter_event/sierra_tier/arc
|
||||
name = "S-ARC"
|
||||
|
||||
/datum/supermatter_event/sierra_tier/arc/start_sierra_event()
|
||||
..()
|
||||
supermatter.power_additive = 6000
|
||||
|
||||
// Laminate type
|
||||
/datum/supermatter_event/sierra_tier/laminate
|
||||
name = "S-LAMINATE REJECTION"
|
||||
|
||||
/datum/supermatter_event/sierra_tier/laminate/start_sierra_event()
|
||||
..()
|
||||
supermatter.heat_multiplier = 10
|
||||
Reference in New Issue
Block a user