[MIRROR] Refactor mob spawner component so that it is independent [MDB IGNORE] (#19560)

Refactor mob spawner component so that it is independent

Co-authored-by: Jacquerel <hnevard@gmail.com>
Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-03-10 06:08:35 +00:00
committed by GitHub
co-authored by Jacquerel Gandalf
parent 7432ea47f6
commit ca0e0983c7
4 changed files with 58 additions and 40 deletions
+50 -21
View File
@@ -1,11 +1,18 @@
/datum/component/spawner
var/mob_types = list(/mob/living/basic/carp)
var/spawn_time = 300 //30 seconds default
/// 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()
var/spawn_delay = 0
var/max_mobs = 5
var/spawn_text = "emerges from"
var/list/faction = list("mining")
/// 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 (!length(mob_types))
@@ -22,27 +29,49 @@
/datum/component/spawner/process()
try_spawn_mob()
/// Stop spawning mobs
/datum/component/spawner/proc/stop_spawning(force)
SIGNAL_HANDLER
STOP_PROCESSING(SSprocessing, src)
for(var/mob/living/simple_animal/L in spawned_mobs)
if(L.nest == src)
L.nest = null
spawned_mobs = null
spawned_mobs = list()
/// Try to create a new mob
/datum/component/spawner/proc/try_spawn_mob()
var/atom/P = parent
if(spawned_mobs.len >= max_mobs)
if(!COOLDOWN_FINISHED(src, spawn_delay))
return
if(spawn_delay > world.time)
validate_references()
if(length(spawned_mobs) >= max_mobs)
return
spawn_delay = world.time + spawn_time
var/atom/spawner = parent
COOLDOWN_START(src, spawn_delay, spawn_time)
var/chosen_mob_type = pick(mob_types)
var/mob/living/simple_animal/L = new chosen_mob_type(P.loc)
L.flags_1 |= (P.flags_1 & ADMIN_SPAWNED_1)
spawned_mobs += L
L.nest = src
L.faction = src.faction
P.visible_message(span_danger("[L] [spawn_text] [P]."))
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))
@@ -46,8 +46,6 @@
var/recovery_time = 0
/// If this is a megafauna that is real (has achievements, gps signal)
var/true_spawn = TRUE
/// Range the megafauna can move from their nest (if they have one
var/nest_range = 10
/// The chosen attack by the megafauna
var/chosen_attack = 1
/// Attack actions, sets chosen_attack to the number in the action
@@ -74,13 +72,6 @@
//Safety check
if(!loc)
return ..()
if(nest && nest.parent && get_dist(nest.parent, src) > nest_range)
var/turf/closest = get_turf(nest.parent)
for(var/i = 1 to nest_range)
closest = get_step(closest, get_dir(closest, src))
forceMove(closest) // someone teleported out probably and the megafauna kept chasing them
LoseTarget()
return
return ..()
/mob/living/simple_animal/hostile/megafauna/death(gibbed, list/force_grant)
@@ -282,7 +282,14 @@
/mob/living/simple_animal/hostile/big_legion/Initialize(mapload)
.=..()
AddComponent(/datum/component/spawner, list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion), 200, faction, "peels itself off from", 3)
AddComponent(\
/datum/component/spawner,\
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion),\
spawn_time = 20 SECONDS,\
max_mobs = 3,\
spawn_text = "peels itself off from",\
faction = faction,\
)
// Snow Legion
@@ -123,8 +123,6 @@
///If the mob can be spawned with a gold slime core. HOSTILE_SPAWN are spawned with plasma, FRIENDLY_SPAWN are spawned with blood.
var/gold_core_spawnable = NO_SPAWN
var/datum/component/spawner/nest
///Sentience type, for slime potions.
var/sentience_type = SENTIENCE_ORGANIC
@@ -221,10 +219,6 @@
GLOB.simple_animals[AIStatus] -= src
SSnpcpool.currentrun -= src
if(nest)
nest.spawned_mobs -= src
nest = null
var/turf/T = get_turf(src)
if (T && AIStatus == AI_Z_OFF)
SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src
@@ -455,9 +449,6 @@
new i(loc)
/mob/living/simple_animal/death(gibbed)
if(nest)
nest.spawned_mobs -= src
nest = null
drop_loot()
if(dextrous)
drop_all_held_items()