Files
Bubberstation/code/datums/components/spawner.dm
SkyratBot ee2bc1be73 [MIRROR] admins can use the spawner component again [MDB IGNORE] (#19851)
* admins can use the spawner component again (#73976)

Not playing code vanity project with this shit.

Do not require data that just gets stored on a var to be passed via the
stack.

---------

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

* admins can use the spawner component again

---------

Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com>
Co-authored-by: san7890 <the@ san7890.com>
2023-03-15 00:48:05 +00:00

78 lines
2.7 KiB
Plaintext

/datum/component/spawner
/// Time to wait between spawns
var/spawn_time
/// Maximum number of mobs we can have active at one time
var/max_mobs
/// Visible message to show when a mob spawns
var/spawn_text
/// List of mob types to spawn, picked randomly
var/list/mob_types
/// Faction to grant to mobs
var/list/faction
/// List of weak references to mobs we have already created
var/list/spawned_mobs = list()
/// Time until we next spawn
COOLDOWN_DECLARE(spawn_delay)
/datum/component/spawner/Initialize(mob_types = list(), spawn_time = 30 SECONDS, max_mobs = 5, faction = list(FACTION_MINING), spawn_text = "emerges from")
if (!islist(mob_types))
CRASH("invalid mob_types to spawn specified for spawner component!")
src.spawn_time = spawn_time
src.mob_types = mob_types
src.faction = faction
src.spawn_text = spawn_text
src.max_mobs = max_mobs
RegisterSignal(parent, COMSIG_PARENT_QDELETING, PROC_REF(stop_spawning))
START_PROCESSING(SSprocessing, src)
/datum/component/spawner/process()
try_spawn_mob()
/// Stop spawning mobs
/datum/component/spawner/proc/stop_spawning(force)
SIGNAL_HANDLER
STOP_PROCESSING(SSprocessing, src)
spawned_mobs = list()
/// Try to create a new mob
/datum/component/spawner/proc/try_spawn_mob()
if(!COOLDOWN_FINISHED(src, spawn_delay))
return
validate_references()
if(length(spawned_mobs) >= max_mobs)
return
var/atom/spawner = parent
COOLDOWN_START(src, spawn_delay, spawn_time)
var/chosen_mob_type = pick(mob_types)
var/mob/living/created = new chosen_mob_type(spawner.loc)
created.flags_1 |= (spawner.flags_1 & ADMIN_SPAWNED_1)
spawned_mobs += WEAKREF(created)
created.faction = src.faction
spawner.visible_message(span_danger("[created] [spawn_text] [spawner]."))
RegisterSignal(created, COMSIG_PARENT_QDELETING, PROC_REF(mob_deleted))
RegisterSignal(created, COMSIG_MOB_STATCHANGE, PROC_REF(mob_stat_changed))
/// Remove weakrefs to mobs which have been killed or deleted without us picking it up somehow
/datum/component/spawner/proc/validate_references()
for (var/datum/weakref/weak_mob as anything in spawned_mobs)
var/mob/living/previously_spawned = weak_mob.resolve()
if (previously_spawned && previously_spawned.stat != DEAD)
continue
spawned_mobs -= weak_mob
/// Called when a mob we spawned is deleted, remove it from the list
/datum/component/spawner/proc/mob_deleted(mob/living/source)
SIGNAL_HANDLER
spawned_mobs -= WEAKREF(source)
/// Called when a mob we spawned dies, remove it from the list and unregister signals
/datum/component/spawner/proc/mob_stat_changed(mob/living/source)
if (source.stat != DEAD)
return
spawned_mobs -= WEAKREF(source)
UnregisterSignal(source, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_STATCHANGE))