mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-12 08:27:13 +01:00
538fd914bb
- status displays no longer delete 50 overlays a second - fauna spawners no longer cause carp harddels - ammo piles and rocket launchers no longer cause harddels
232 lines
7.8 KiB
Plaintext
232 lines
7.8 KiB
Plaintext
/obj/effect/fauna_spawner
|
|
name = "Mob spawner"
|
|
desc = "A mob spawner you're not supposed to see"
|
|
icon = 'icons/effects/map_effects.dmi'
|
|
icon_state = "ghostspawpoint"
|
|
|
|
anchored = 1
|
|
unacidable = 1
|
|
simulated = 0
|
|
invisibility = 101
|
|
|
|
var/first_spawn_done = FALSE // Keeping this false will make it so that it always spawns the first mob on the list first
|
|
var/spawning_enabled = FALSE
|
|
var/list/active_mobs = list()
|
|
var/max_active_mobs = 5
|
|
var/list/mob_choices = list() // List of mobs it'll spawn
|
|
|
|
/// Cooldown for spawning mobs. A value between min and max will be defined as seconds.
|
|
var/min_spawn_cooldown = 5
|
|
var/max_spawn_cooldown = 10
|
|
|
|
var/obj/effect/landmark/mob_waypoint/waypoint = null // The spawner automatically detects a waypoint on the same z-level, no need to set this manually
|
|
|
|
/obj/effect/fauna_spawner/Initialize()
|
|
. = ..()
|
|
var/obj/effect/landmark/mob_waypoint/W = locate(/obj/effect/landmark/mob_waypoint) in world
|
|
RegisterSignal(SSdcs, COMSIG_GLOB_MOB_DEATH, PROC_REF(mob_died))
|
|
if (W && W.z == src.z)
|
|
waypoint = W
|
|
if(!islist(GLOB.fauna_spawners))
|
|
GLOB.fauna_spawners = list()
|
|
GLOB.fauna_spawners |= src
|
|
return INITIALIZE_HINT_LATELOAD
|
|
|
|
/obj/effect/fauna_spawner/LateInitialize()
|
|
waypoint = LAZYACCESS(GLOB.mob_waypoints, z)
|
|
if(!istype(waypoint))
|
|
qdel(src)
|
|
|
|
/obj/effect/fauna_spawner/Destroy()
|
|
UnregisterSignal(GLOB, COMSIG_GLOB_MOB_DEATH, PROC_REF(mob_died))
|
|
for(var/mob/m in active_mobs)
|
|
UnregisterSignal(m, COMSIG_QDELETING)
|
|
active_mobs.Cut()
|
|
if(islist(GLOB.fauna_spawners))
|
|
GLOB.fauna_spawners -= src
|
|
return ..()
|
|
|
|
/obj/effect/fauna_spawner/proc/start_spawning()
|
|
if (spawning_enabled)
|
|
return
|
|
spawning_enabled = TRUE
|
|
spawn()
|
|
while (spawning_enabled && src)
|
|
for (var/i = length(active_mobs); i >= 1; i--)
|
|
var/mob/living/M = active_mobs[i]
|
|
if (!M || QDELETED(M) || M.stat == DEAD)
|
|
active_mobs.Cut(i, i+1)
|
|
if (length(active_mobs) < max_active_mobs)
|
|
spawn_mob()
|
|
sleep(rand(min_spawn_cooldown, max_spawn_cooldown) SECONDS)
|
|
|
|
/obj/effect/fauna_spawner/proc/spawn_mob()
|
|
if (!mob_choices || !length(mob_choices))
|
|
return
|
|
var/mob_type
|
|
var/move_speed = 5
|
|
var/choice
|
|
if (!first_spawn_done)
|
|
choice = mob_choices[1]
|
|
first_spawn_done = TRUE
|
|
else
|
|
choice = pick(mob_choices)
|
|
if (islist(choice))
|
|
mob_type = choice["type"]
|
|
move_speed = choice["speed"]
|
|
else
|
|
mob_type = choice
|
|
var/mob/living/new_mob = new mob_type(src.loc)
|
|
if (!new_mob)
|
|
return
|
|
active_mobs += new_mob
|
|
RegisterSignal(new_mob, COMSIG_QDELETING, PROC_REF(mob_died))
|
|
if (src.waypoint && istype(new_mob, /mob/living/simple_animal/hostile))
|
|
var/mob/living/simple_animal/hostile/H = new_mob
|
|
H.target_waypoint = src.waypoint
|
|
spawn()
|
|
if (isturf(src.waypoint.loc))
|
|
GLOB.move_manager.move_towards(H, src.waypoint.loc, move_speed, TRUE)
|
|
|
|
/obj/effect/fauna_spawner/proc/mob_died(var/mob/living/mob_ref, gibbed)
|
|
SIGNAL_HANDLER
|
|
UnregisterSignal(mob_ref, COMSIG_QDELETING)
|
|
for (var/i = length(active_mobs); i >= 1; i--)
|
|
var/mob/living/M = active_mobs[i]
|
|
if (!M || QDELETED(M) || M.stat == DEAD)
|
|
active_mobs.Cut(i, i+1)
|
|
if (mob_ref in active_mobs)
|
|
active_mobs -= mob_ref
|
|
|
|
/obj/effect/fauna_spawner/proc/stop_spawning()
|
|
spawning_enabled = FALSE
|
|
|
|
/proc/activate_fauna_spawners(var/z)
|
|
if(!islist(GLOB.fauna_spawners) || !length(GLOB.fauna_spawners))
|
|
return
|
|
for(var/obj/effect/fauna_spawner/S in GLOB.fauna_spawners)
|
|
if(S?.loc?.z == z)
|
|
S.start_spawning()
|
|
|
|
//Make your subtypes here
|
|
/obj/effect/fauna_spawner/phoron_deposit
|
|
name = "Phoron Deposit Spawner"
|
|
mob_choices = list(
|
|
list(type = /mob/living/simple_animal/hostile/carp/shark/reaver/eel/phoron_deposit, speed = 5), //Speed refers only to the speed that the mobs will move to the waypoint at. Lower values = faster
|
|
list(type = /mob/living/simple_animal/hostile/carp/shark/phoron_deposit, speed = 4),
|
|
list(type = /mob/living/simple_animal/hostile/carp/shark/reaver/phoron_deposit, speed = 5),
|
|
list(type = /mob/living/simple_animal/hostile/gnat/phoron_deposit, speed = 1),
|
|
list(type = /mob/living/simple_animal/hostile/carp, speed = 2)
|
|
)
|
|
|
|
/**
|
|
* Opposed to `fauna_spawner`, this spawner allows further customization and checks over spawned mobs, such as:
|
|
* * Having multiple spawn points, randomly chosen to spawn mobs.
|
|
* * Keeping track of total mob counts inside a single object.
|
|
*
|
|
* How does it work?
|
|
* * This type serves as a single spawner, it detects the spawn points in the same Z level and randomly chooses
|
|
*/
|
|
/obj/effect/fauna_spawner/organized
|
|
name = "Organized mob spawner"
|
|
desc = "You are not supposed to see this!"
|
|
icon_state = "master_spawner"
|
|
|
|
anchored = TRUE
|
|
unacidable = TRUE
|
|
simulated = FALSE
|
|
invisibility = 101
|
|
|
|
min_spawn_cooldown = 20
|
|
max_spawn_cooldown = 25
|
|
max_active_mobs = 15
|
|
|
|
/// Integer, fixed number of mobs that'll be spawned before spawner enters cooldown.
|
|
var/spawn_points_to_pick
|
|
|
|
/// The number range of mobs that can spawn before spawner enters cooldown. Ignored if 'spawn_points_to_pick' isn't null.
|
|
var/min_spawn = 2
|
|
var/max_spawn = 3
|
|
|
|
/// If true, object will avoid spawning multiple mobs on the same point.
|
|
var/one_spawn_per_point = FALSE
|
|
|
|
/obj/effect/fauna_spawner/organized/spawn_mob()
|
|
if (!mob_choices || !length(mob_choices))
|
|
return
|
|
var/obj/effect/landmark/organized_spawn_point/SP
|
|
var/list/available_points = GLOB.organized_spawn_points.Copy() // we make a copy so 'pick_n_take()' doesn't get rid of instances in global list
|
|
var/list/chosen_group = list()
|
|
if(LAZYLEN(available_points))
|
|
var/loop_amount
|
|
var/obj/effect/spawn_point
|
|
loop_amount = !spawn_points_to_pick ? rand(min_spawn, max_spawn) : spawn_points_to_pick // if no value is set we will randomly pick a number for each spawn time
|
|
for(var/i in 1 to loop_amount)
|
|
spawn_point = one_spawn_per_point ? pick_n_take(available_points) : pick(available_points)
|
|
if(spawn_point.z == src.z)
|
|
chosen_group += spawn_point
|
|
|
|
for(SP in chosen_group) //---- spawning mobs on chosen points
|
|
if(length(active_mobs) >= max_active_mobs) // double check if we exceeded the threshold
|
|
return
|
|
var/turf/T = get_turf(SP)
|
|
var/mob_type
|
|
var/move_speed = 5
|
|
var/choice
|
|
choice = pick(mob_choices)
|
|
if (islist(choice))
|
|
mob_type = choice["type"]
|
|
move_speed = choice["speed"]
|
|
else
|
|
mob_type = choice
|
|
var/mob/living/new_mob = new mob_type(T)
|
|
active_mobs += new_mob
|
|
|
|
RegisterSignal(new_mob, COMSIG_QDELETING, PROC_REF(mob_died))
|
|
if(src.waypoint && istype(new_mob, /mob/living/simple_animal/hostile))
|
|
var/mob/living/simple_animal/hostile/H = new_mob
|
|
H.target_waypoint = src.waypoint
|
|
INVOKE_ASYNC(src, PROC_REF(lead_the_mob), H, waypoint, move_speed)
|
|
|
|
/obj/effect/fauna_spawner/organized/proc/lead_the_mob(H, waypoint, move_speed)
|
|
if(isturf(src.waypoint.loc))
|
|
GLOB.move_manager.move_towards(H, src.waypoint.loc, move_speed, TRUE)
|
|
|
|
// ---- Put your subtypes here
|
|
|
|
/obj/effect/fauna_spawner/organized/quarantined_outpost
|
|
name = "Quarantined Outpost Spawner"
|
|
mob_choices = list(
|
|
list(type = /mob/living/simple_animal/hostile/revivable/husked_creature/quarantined_outpost/horde, speed = 5),
|
|
list(type = /mob/living/simple_animal/hostile/revivable/abomination/quarantined_outpost/horde, speed = 5)
|
|
)
|
|
one_spawn_per_point = TRUE
|
|
|
|
/obj/effect/landmark/organized_spawn_point
|
|
name = "spawn point"
|
|
icon = 'icons/effects/map_effects.dmi'
|
|
icon_state = "spawner_spawnpoint"
|
|
|
|
/obj/effect/landmark/organized_spawn_point/Initialize()
|
|
. = ..()
|
|
GLOB.organized_spawn_points += src
|
|
|
|
/obj/effect/landmark/organized_spawn_point/Destroy()
|
|
GLOB.organized_spawn_points -= src
|
|
return ..()
|
|
|
|
/obj/effect/landmark/mob_waypoint
|
|
name = "mob waypoint"
|
|
|
|
/obj/effect/landmark/mob_waypoint/Initialize(mapload)
|
|
. = ..()
|
|
var/list/z_levels = GetConnectedZlevels(z)
|
|
for(var/i in z_levels)
|
|
LAZYADDASSOCLIST(GLOB.mob_waypoints, "[i]", src)
|
|
|
|
/obj/effect/landmark/mob_waypoint/Destroy()
|
|
var/list/z_levels = GetConnectedZlevels(z)
|
|
for(var/i in z_levels)
|
|
LAZYREMOVEASSOC(GLOB.mob_waypoints, "[i]", src)
|
|
return ..()
|