mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-25 09:01:40 +00:00
* 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>
306 lines
11 KiB
Plaintext
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
|