Files
Bubberstation/code/modules/events/vent_clog.dm
SkyratBot f591dd3bd3 [MIRROR] Gondolas are now basic mobs (#27934)
* Gondolas are now basic mobs (#83451)

## About The Pull Request

This PR turns gondolas into basic mobs and does some fiddling with
gondola pods
Their verbs are now action buttons which they lose upon delivering. If
set to stay, they won't have their abilities afterwards (or wont get
them in the first place if the delivery is already done).
Lets them survive without a pod requirement in case admins want to spawn
one for their own stuff, so I also removed it from the snowflake checks
to exclude them from stuff.

Also replaced the hardcoded "cant speak" with simply giving the mute
trait, so admins can make gondolas speak if they want to for any reason.

## Why It's Good For The Game

The pet level of simple animals can finally be killed off, also gives
admins more control over gondola-related stuff if they so wish.

## Changelog

🆑
refactor: Gondolas (including gondola pods) are now basic mobs.
/🆑

---------

Co-authored-by: san7890 <the@san7890.com>

* Well then. Hope it works.

* Ohhh.

---------

Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: Useroth <37159550+Useroth@users.noreply.github.com>
2024-06-02 17:37:45 +02: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
user.balloon_alert_to_viewers("plunging vent...", "plunging clogged vent...")
if(do_after(user, 6 SECONDS, target = vent))
user.balloon_alert_to_viewers("finished plunging")
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/basic/pet/gondola,
)
return pick(mob_list)
#undef MOB_SPAWN_MINIMUM