Files
Bubberstation/code/modules/events/vent_clog.dm
SkyratBot 9ab415d742 [MIRROR] Fixed false anomaly announcements. [MDB IGNORE] (#25509)
* Fixed false anomaly announcements.

* Update _anomaly.dm

* Update anomaly_bioscrambler.dm

* Update anomaly_bluespace.dm

* Fix merge conflicts

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
2023-12-08 18:59:41 -05:00

306 lines
11 KiB
Plaintext

#define MOB_SPAWN_MINIMUM 3
/datum/round_event_control/vent_clog
name = "Ventilation Clog: Minor"
typepath = /datum/round_event/vent_clog
weight = 25
earliest_start = 5 MINUTES
category = EVENT_CATEGORY_JANITORIAL
description = "Harmless mobs climb out of a vent."
/datum/round_event_control/vent_clog/can_spawn_event(players_amt, allow_magic = FALSE)
. = ..()
if(!.)
return
for(var/obj/machinery/atmospherics/components/unary/vent_pump/vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump))
var/turf/vent_turf = get_turf(vent)
if(vent_turf && is_station_level(vent_turf.z) && !vent.welded)
return TRUE //make sure we have a valid vent to spawn from.
return FALSE
/datum/round_event/vent_clog
announce_when = 10
announce_chance = 90
end_when = 600
///Vent selected for the event.
var/obj/machinery/atmospherics/components/unary/vent_pump/vent
///What mob will be spawned
var/mob/spawned_mob = /mob/living/basic/cockroach
///Cap on the number of spawned mobs that can be alive at once.
var/maximum_spawns = MOB_SPAWN_MINIMUM
///Interval between mob spawns.
var/spawn_delay = 10
///Used to track/limit produced mobs.
var/list/living_mobs = list()
///The list of decals we will choose from to spawn when producing a mob
var/list/filth_spawn_types = list()
/datum/round_event/vent_clog/announce(fake)
var/area/event_area = fake ? pick(GLOB.teleportlocs) : get_area_name(vent)
priority_announce("Minor biological obstruction detected in the ventilation network. Blockage is believed to be in the [event_area].", "Custodial Notification")
/datum/round_event/vent_clog/setup()
vent = get_vent()
spawned_mob = get_mob()
end_when = rand(300, 600)
maximum_spawns = rand(MOB_SPAWN_MINIMUM, 10)
spawn_delay = rand(10, 15)
filth_spawn_types = list(
/obj/effect/decal/cleanable/vomit,
/obj/effect/decal/cleanable/insectguts,
/obj/effect/decal/cleanable/oil,
)
/datum/round_event/vent_clog/start()
clog_vent()
announce_to_ghosts(vent)
/datum/round_event/vent_clog/tick() //Checks if spawn_interval is met, then sends signal to vent to produce a mob.
if(activeFor % spawn_delay == 0)
life_check()
if(living_mobs.len < maximum_spawns)
produce_mob()
/datum/round_event/vent_clog/end() //No end announcement. If you want to take the easy way out and just leave the vent welded, you must open it at your own peril.
vent = null
living_mobs.Cut()
/**
* Selects which mob will be spawned for a given vent clog event.
*
* Creates a static list of mobs, which is different based on the severity of the event being run, and returns a pick() of it.
*/
/datum/round_event/vent_clog/proc/get_mob()
var/static/list/mob_list = list(
/mob/living/basic/butterfly,
/mob/living/basic/cockroach,
/mob/living/basic/spider/maintenance,
/mob/living/basic/mouse,
)
return pick(mob_list)
/**
* Finds a valid vent to spawn mobs from.
*
* Randomly selects a vent that is on-station, unwelded, and hosted by a passable turf. If no vents are found, the event
* is immediately killed.
*/
/datum/round_event/vent_clog/proc/get_vent()
var/list/vent_list = list()
for(var/obj/machinery/atmospherics/components/unary/vent_pump/vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump))
var/turf/vent_turf = get_turf(vent)
if(vent_turf && is_station_level(vent_turf.z) && !vent.welded && !vent_turf.is_blocked_turf_ignore_climbable())
vent_list += vent
if(!length(vent_list))
kill()
CRASH("Unable to find suitable vent.")
return pick(vent_list)
/**
* Checks which mobs in the mob spawn list are alive.
*
* Checks each mob in the living_mobs list, to see if they're dead or not. If dead, they're removed from the list.
* This is used to keep new mobs spawning as the old ones die.
*/
/datum/round_event/vent_clog/proc/life_check()
for(var/datum/weakref/mob_ref as anything in living_mobs)
var/mob/living/real_mob = mob_ref.resolve()
if(QDELETED(real_mob) || real_mob.stat == DEAD)
living_mobs -= mob_ref
/**
* Finds a new vent for the event if the original is destroyed.
*
* This is used when the vent for the event is destroyed. It picks a new vent and announces that the event has moved elsewhere.
* Handles the vent ref if there are no valid vents to replace it with.
*/
/datum/round_event/vent_clog/proc/vent_move(datum/source)
SIGNAL_HANDLER
vent = null //If by some great calamity, the last valid vent is destroyed, the ref is cleared.
vent = get_vent()
clog_vent()
announce_to_ghosts(vent)
priority_announce("Lifesign readings have moved to a new location in the ventilation network. New Location: [prob(50) ? "Unknown.":"[get_area_name(vent)]."]", "Lifesign Notification")
/**
* Handles the production of our mob and adds it to our living_mobs list
*
* Used by the vent clog random event to handle the spawning of mobs. The proc receives the mob that will be spawned,
* and the event's current list of living mobs produced by the event so far. After checking if the vent is welded, the
* new mob is created on the vent's turf, then added to the living_mobs list.
*/
/datum/round_event/vent_clog/proc/produce_mob()
var/turf/vent_loc = get_turf(vent)
if (isnull(vent_loc))
CRASH("[vent] has no loc, aborting mobspawn")
if(vent.welded || vent_loc.is_blocked_turf_ignore_climbable()) // vents under tables can still spawn stuff
return
var/mob/new_mob = new spawned_mob(vent_loc) // we spawn it early so we can actually use is_blocked_turf
living_mobs += WEAKREF(new_mob)
vent.visible_message(span_warning("[new_mob] crawls out of [vent]!"))
var/list/potential_locations = list(vent_loc) // already confirmed to be accessable via the 2nd if check of the proc
// exists to prevent mobs from trying to move onto turfs they physically cannot
for(var/turf/nearby_turf in oview(1, get_turf(vent))) // oview, since we always add our loc to the list
if(!nearby_turf.is_blocked_turf(source_atom = new_mob))
potential_locations += nearby_turf
var/turf/spawn_location = pick(potential_locations)
new_mob.Move(spawn_location)
var/filth_to_spawn = pick(filth_spawn_types)
new filth_to_spawn(spawn_location)
playsound(spawn_location, 'sound/effects/splat.ogg', 30, TRUE)
///Signal catcher for plunger_act()
/datum/round_event/vent_clog/proc/plunger_unclog(datum/source, obj/item/plunger/attacking_plunger, mob/user, reinforced)
SIGNAL_HANDLER
INVOKE_ASYNC(src, PROC_REF(attempt_unclog), user)
return COMPONENT_NO_AFTERATTACK
///Handles the actual unclogging action and ends the event on completion.
/datum/round_event/vent_clog/proc/attempt_unclog(mob/user)
if(vent.welded)
to_chat(user, span_notice("You cannot pump [vent] if it's welded shut!"))
return
to_chat(user, span_notice("You begin pumping [vent] with your plunger."))
if(do_after(user, 6 SECONDS, target = vent))
to_chat(user, span_notice("You finish pumping [vent]."))
clear_signals()
kill()
///Handles the initial steps of clogging a vent, either at event start or when the vent moves.
/datum/round_event/vent_clog/proc/clog_vent()
RegisterSignal(vent, COMSIG_QDELETING, PROC_REF(vent_move))
RegisterSignal(vent, COMSIG_PLUNGER_ACT, PROC_REF(plunger_unclog))
for(var/turf/nearby_turf in view(2, get_turf(vent)))
if(isopenturf(nearby_turf) && prob(85))
new /obj/effect/decal/cleanable/dirt(nearby_turf)
produce_mob()
///Clears the signals related to the event, before we wrap things up.
/datum/round_event/vent_clog/proc/clear_signals()
UnregisterSignal(vent, list(COMSIG_QDELETING, COMSIG_PLUNGER_ACT))
/datum/round_event_control/vent_clog/major
name = "Ventilation Clog: Major"
typepath = /datum/round_event/vent_clog/major
weight = 12
max_occurrences = 5
earliest_start = 10 MINUTES
description = "Dangerous mobs climb out of a vent."
min_wizard_trigger_potency = 0
max_wizard_trigger_potency = 4
/datum/round_event/vent_clog/major/setup()
. = ..()
maximum_spawns = rand(MOB_SPAWN_MINIMUM, 5)
spawn_delay = rand(15,20)
filth_spawn_types = list(
/obj/effect/decal/cleanable/blood,
/obj/effect/decal/cleanable/insectguts,
/obj/effect/decal/cleanable/fuel_pool,
/obj/effect/decal/cleanable/oil,
)
/datum/round_event/vent_clog/major/get_mob()
var/static/list/mob_list = list(
/mob/living/basic/bee,
/mob/living/basic/cockroach/hauberoach,
/mob/living/basic/spider/giant,
/mob/living/basic/mouse/rat,
)
return pick(mob_list)
/datum/round_event/vent_clog/major/announce(fake)
var/area/event_area = fake ? pick(GLOB.teleportlocs) : get_area_name(vent)
priority_announce("Major biological obstruction detected in the ventilation network. Blockage is believed to be in the [event_area] area.", "Infestation Alert")
/datum/round_event_control/vent_clog/critical
name = "Ventilation Clog: Critical"
typepath = /datum/round_event/vent_clog/critical
weight = 8
min_players = 15
max_occurrences = 3
earliest_start = 25 MINUTES
description = "Really dangerous mobs climb out of a vent."
min_wizard_trigger_potency = 3
max_wizard_trigger_potency = 6
/datum/round_event/vent_clog/critical/setup()
. = ..()
spawn_delay = rand(15,25)
maximum_spawns = rand(MOB_SPAWN_MINIMUM, 6)
filth_spawn_types = list(
/obj/effect/decal/cleanable/blood,
/obj/effect/decal/cleanable/blood/splatter,
)
/datum/round_event/vent_clog/critical/announce(fake)
var/area/event_area = fake ? pick(GLOB.teleportlocs) : get_area_name(vent)
priority_announce("Potentially hazardous lifesigns detected in the [event_area] ventilation network.", "Security Alert")
/datum/round_event/vent_clog/critical/get_mob()
var/static/list/mob_list = list(
/mob/living/basic/bee/toxin,
/mob/living/basic/carp,
/mob/living/basic/cockroach/glockroach,
)
return pick(mob_list)
/datum/round_event_control/vent_clog/strange
name = "Ventilation Clog: Strange"
typepath = /datum/round_event/vent_clog/strange
weight = 5
max_occurrences = 2
description = "Strange mobs climb out of a vent, harmfulness varies."
min_wizard_trigger_potency = 0
max_wizard_trigger_potency = 7
/datum/round_event/vent_clog/strange/setup()
. = ..()
end_when = rand(600, 900)
spawn_delay = rand(6, 25)
maximum_spawns = rand(MOB_SPAWN_MINIMUM, 10)
filth_spawn_types = list(
/obj/effect/decal/cleanable/xenoblood,
/obj/effect/decal/cleanable/fuel_pool,
/obj/effect/decal/cleanable/greenglow,
/obj/effect/decal/cleanable/vomit,
)
/datum/round_event/vent_clog/strange/announce(fake)
var/area/event_area = fake ? pick(GLOB.teleportlocs) : get_area_name(vent)
priority_announce("Unusual lifesign readings detected in the [event_area] ventilation network.", "Lifesign Alert", ANNOUNCER_ALIENS)
/datum/round_event/vent_clog/strange/get_mob()
var/static/list/mob_list = list(
/mob/living/basic/bear,
/mob/living/basic/cockroach/glockroach/mobroach,
/mob/living/basic/lightgeist,
/mob/living/basic/mothroach,
/mob/living/basic/mushroom,
/mob/living/basic/viscerator,
/mob/living/simple_animal/hostile/retaliate/goose, //Janitors HATE geese.
/mob/living/simple_animal/pet/gondola,
)
return pick(mob_list)
#undef MOB_SPAWN_MINIMUM