Files
VOREStation/code/modules/gamemaster/event2/events/mob_spawning.dm
T
Cameron Lennox 84dc5535dc var/global/list -> GLOB. conversion (#17928)
* These two are easy

* !!!runlevel_flags

the fact it was global.runlevel_flags.len has me a bit...iffy on this.

* !!!json_cache

Same as above. used global.

* player_list & observer_mob_list

* mechas_list

* this wasn't even used

* surgery_steps

* event_triggers

* landmarks_list

* dead_mob_list

* living_mob_list

* ai_list

* cable_list

* cleanbot_reserved_turfs

* listening_objects

* silicon_mob_list

* human_mob_list

* Update global_lists.dm

* joblist

* mob_list

* Update global_lists.dm

* holomap_markers

* mapping_units

* mapping_beacons

* hair_styles_list

* facial_hair_styles_list

* Update global_lists.dm

* facial_hair_styles_male_list

* facial_hair_styles_female_list

* body_marking_styles_list

* body_marking_nopersist_list

* ear_styles_list

* hair_styles_male_list

* tail_styles_list

* wing_styles_list

* escape_list & rune_list & endgame_exits

these were all really small

* endgame_safespawns

* stool_cache

* emotes_by_key

* random_maps & map_count

* item_tf_spawnpoints

* narsie_list

* active_radio_jammers

* unused

* paikeys

* pai_software_by_key & default_pai_software

* plant_seed_sprites

* magazine_icondata_keys  & magazine_icondata_states

* unused

* ashtray_cache

* light_type_cache

* HOLIDAY!!!

this one was annoying

* faction stuff (red?!)

* Update preferences_factions.dm

* vs edit removal

* backbaglist, pdachoicelist, exclude_jobs

* item_digestion_blacklist, edible_tech, blacklisted_artifact_effect, selectable_footstep, hexNums, syndicate_access

* string_slot_flags and hexdigits->hexNums

* possible_changeling_IDs

* vr_mob_tf_options

* vr_mob_spawner_options

* pipe_colors

* vr_mob_spawner_options

* common_tools

* newscaster_standard_feeds

* Update periodic_news.dm

* changeling_fabricated_clothing

* semirandom_mob_spawner_decisions

* id_card_states

* Update syndicate_ids.dm

* overlay_cache & gear_distributed_to

* more

* radio_channels_by_freq

* Update global_lists.dm

* proper

* default_medbay_channels & default_internal_channels

default_internal_channels is weird as it has a mapbased proc() but that proc is never called...

* valid_ringtones

* move this

* possible_plants

* more

* separate these

moves xeno2chemlist from a hook to a new global list.

* tube_dir_list

* valid_bloodreagents & monitor_states

* Junk

* valid_bloodtypes

* breach_burn_descriptors & burn

* more!!

appliance_available_recipes seems uber cursed, re-look at later

* Appliance code is cursed

* wide_chassis & flying_chassis

* allows_eye_color

* all_tooltip_styles

* direction_table

* gun_choices

* severity_to_string

* old event_viruses

* description_icons

* MOVE_KEY_MAPPINGS

* more more

* pai & robot modules

* Update global_lists.dm

* GEOSAMPLES

Also swaps a .len to LAZYLEN()

* shieldgens

* reagent recipies

* global ammo types

* rad collector

* old file and unused global

* nif_look_messages

* FESH

* nifsoft

* chamelion

* the death of sortAtom

* globulins

* lazylen that

* Update global_lists.dm

* LAZY

* Theese too

* quick fix

---------

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
2025-07-14 20:14:31 +02:00

99 lines
4.1 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 GLOB.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/turf/point as anything in space_line)
if(get_dist(point, edge_of_station) <= max_distance)
spawn_turf = point
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)
RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(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/mob/living/simple_mob/M as anything in spawned_mobs)
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)
SIGNAL_HANDLER
spawned_mobs -= M
UnregisterSignal(M, COMSIG_OBSERVER_DESTROYED)