mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-01-05 15:04:21 +00:00
99 lines
4.2 KiB
Plaintext
99 lines
4.2 KiB
Plaintext
// A subtype that involves spawning mobs like carp, rogue drones, spiders, etc.
|
|
|
|
/datum/event2/event/mob_spawning
|
|
var/list/spawned_mobs = list()
|
|
var/use_map_edge_with_landmarks = TRUE // Use both landmarks and spawning from the "edge" of the map. Otherise uses landmarks over map edge.
|
|
var/landmark_name = "carpspawn" // Which landmark to use for spawning.
|
|
|
|
// Spawns a specific mob from the "edge" of the map, and makes them go towards the station.
|
|
// Can also use landmarks, if desired.
|
|
/datum/event2/event/mob_spawning/proc/spawn_mobs_in_space(mob_type, number_of_groups, min_size_of_group, max_size_of_group, dir)
|
|
if(isnull(dir))
|
|
dir = pick(GLOB.cardinal)
|
|
|
|
var/list/valid_z_levels = get_location_z_levels()
|
|
valid_z_levels -= using_map.sealed_levels // Space levels only please!
|
|
|
|
// Check if any landmarks exist!
|
|
var/list/spawn_locations = list()
|
|
for(var/obj/effect/landmark/C in landmarks_list)
|
|
if(C.name == landmark_name && (C.z in valid_z_levels))
|
|
spawn_locations.Add(C.loc)
|
|
|
|
var/prioritize_landmarks = TRUE
|
|
if(use_map_edge_with_landmarks && prob(50))
|
|
prioritize_landmarks = FALSE // One in two chance to come from the edge instead.
|
|
|
|
if(spawn_locations.len && prioritize_landmarks) // Okay we've got landmarks, lets use those!
|
|
shuffle_inplace(spawn_locations)
|
|
number_of_groups = min(number_of_groups, spawn_locations.len)
|
|
var/i = 1
|
|
while (i <= number_of_groups)
|
|
var/group_size = rand(min_size_of_group, max_size_of_group)
|
|
for (var/j = 0, j < group_size, j++)
|
|
spawn_one_mob(spawn_locations[i], mob_type)
|
|
i++
|
|
return
|
|
|
|
// Okay we did *not* have any landmarks, or we're being told to do both, so lets do our best!
|
|
var/i = 1
|
|
while(i <= number_of_groups)
|
|
var/z_level = pick(valid_z_levels)
|
|
var/group_size = rand(min_size_of_group, max_size_of_group)
|
|
var/turf/map_center = locate(round(world.maxx/2), round(world.maxy/2), z_level)
|
|
var/turf/group_center = pick_random_edge_turf(dir, z_level, TRANSITIONEDGE + 2)
|
|
var/list/turfs = getcircle(group_center, 2)
|
|
for(var/j = 0, j < group_size, j++)
|
|
// On larger maps, BYOND gets in the way of letting simple_mobs path to the closest edge of the station.
|
|
// So instead we need to simulate the mob's travel, then spawn them somewhere still hopefully off screen.
|
|
|
|
// Find a turf to be the edge of the map.
|
|
var/turf/edge_of_map = turfs[(i % turfs.len) + 1]
|
|
|
|
// Now walk a straight line towards the center of the map, until we find a non-space tile.
|
|
var/turf/edge_of_station = null
|
|
|
|
var/list/space_line = list() // This holds all space tiles on the line. Will be used a bit later.
|
|
for(var/turf/T in getline(edge_of_map, map_center))
|
|
if(!T.is_space())
|
|
break // We found the station!
|
|
space_line += T
|
|
edge_of_station = T
|
|
|
|
// Now put the mob somewhere on the line, hopefully off screen.
|
|
// I wish this was higher than 8 but the BYOND internal A* algorithm gives up sometimes when using
|
|
// 16 or more.
|
|
// In the future, a new AI stance that handles long distance travel using getline() could work.
|
|
var/max_distance = 8
|
|
var/turf/spawn_turf = null
|
|
for(var/P in space_line)
|
|
var/turf/point = P
|
|
if(get_dist(point, edge_of_station) <= max_distance)
|
|
spawn_turf = P
|
|
break
|
|
|
|
if(spawn_turf)
|
|
// Finally, make the simple_mob go towards the edge of the station.
|
|
var/mob/living/simple_mob/M = spawn_one_mob(spawn_turf, mob_type)
|
|
if(edge_of_station)
|
|
M.ai_holder?.give_destination(edge_of_station) // Ask simple_mobs to fly towards the edge of the station.
|
|
i++
|
|
|
|
/datum/event2/event/mob_spawning/proc/spawn_one_mob(new_loc, mob_type)
|
|
var/mob/living/simple_mob/M = new mob_type(new_loc)
|
|
GLOB.destroyed_event.register(M, src, .proc/on_mob_destruction)
|
|
spawned_mobs += M
|
|
return M
|
|
|
|
// Counts living simple_mobs spawned by this event.
|
|
/datum/event2/event/mob_spawning/proc/count_spawned_mobs()
|
|
. = 0
|
|
for(var/I in spawned_mobs)
|
|
var/mob/living/simple_mob/M = I
|
|
if(!QDELETED(M) && M.stat != DEAD)
|
|
. += 1
|
|
|
|
// If simple_mob is bomphed, remove it from the list.
|
|
/datum/event2/event/mob_spawning/proc/on_mob_destruction(mob/M)
|
|
spawned_mobs -= M
|
|
GLOB.destroyed_event.unregister(M, src, .proc/on_mob_destruction) |