From d746150bcf8e13498169fd167ad32c05f3d3f7c1 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Tue, 15 Apr 2025 10:14:32 -0400 Subject: [PATCH] move tendrils and fauna into spawn pools, enforce minimum megafauna spawn distance from base (#28968) * move tendrils into a spawn pool * update formula from feedback * increase certainty we get enough spawn pool placements * bleh * whitespace * fuck it everyone gets a pool --- .../LavaRuins/lavaland_surface_nt.dmm | 13 +- .../spawners/random/pool/lavaland_pools.dm | 133 ++++++++++++++++++ .../mission_code/ruins/gps_ruin.dm | 3 + code/modules/lavaland/caves_theme.dm | 77 ++-------- paradise.dme | 1 + 5 files changed, 154 insertions(+), 73 deletions(-) create mode 100644 code/game/objects/effects/spawners/random/pool/lavaland_pools.dm diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_nt.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_nt.dmm index 4ab4d26fd34..ab7240c8943 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_nt.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_nt.dmm @@ -25,14 +25,6 @@ /obj/machinery/door/airlock/maintenance, /turf/simulated/floor/plating, /area/mine/outpost/maintenance/south) -"am" = ( -/obj/effect/spawner/random/dirt/maybe, -/obj/item/gps/ruin{ - pixel_x = 32; - gpstag = "Nanotrasen Mining Outpost" - }, -/turf/simulated/floor/plating, -/area/mine/outpost/maintenance/east) "ar" = ( /obj/structure/disposalpipe/segment{ dir = 8 @@ -9118,6 +9110,9 @@ "Yk" = ( /obj/structure/reagent_dispensers/oil, /obj/item/reagent_containers/drinks/oilcan, +/obj/item/gps/ruin/mining_base{ + pixel_x = 32 + }, /turf/simulated/floor/plating, /area/mine/outpost/maintenance/south) "Yl" = ( @@ -19807,7 +19802,7 @@ IE xT jZ wP -am +hA OI OJ BL diff --git a/code/game/objects/effects/spawners/random/pool/lavaland_pools.dm b/code/game/objects/effects/spawners/random/pool/lavaland_pools.dm new file mode 100644 index 00000000000..92c342a1288 --- /dev/null +++ b/code/game/objects/effects/spawners/random/pool/lavaland_pools.dm @@ -0,0 +1,133 @@ +/// Wrapper spawner for lavaland fauna +/obj/effect/spawner/random/lavaland_fauna + loot = list( + /obj/effect/spawner/random/pool/lavaland_fauna, + /obj/effect/spawner/random/pool/lavaland_fauna/megafauna, + /obj/effect/spawner/random/pool/lavaland_fauna/megafauna/unique, + /obj/effect/spawner/random/pool/tendril_spawner, + ) + +/datum/spawn_pool/lavaland_fauna + id = "lavaland_fauna_spawn_pool" + +/datum/spawn_pool/lavaland_fauna/New() + . = ..() + available_points = rand(100, 150) + +/datum/spawn_pool/lavaland_megafauna + id = "lavaland_megafauna_spawn_pool" + +/datum/spawn_pool/lavaland_megafauna/New() + . = ..() + available_points = roll("8d3") + +/obj/effect/spawner/random/pool/lavaland_fauna + spawn_pool_id = "lavaland_fauna_spawn_pool" + record_spawn = TRUE + + var/fauna_scan_range = 12 + var/megafauna_scan_range = 12 + var/turf/mining_base_gps + + loot = list( + list( + /obj/effect/landmark/mob_spawner/goliath, + /obj/effect/landmark/mob_spawner/legion, + /obj/effect/landmark/mob_spawner/watcher, + ) = 3, + + list( + /obj/effect/landmark/mob_spawner/abandoned_minebot, + /obj/effect/landmark/mob_spawner/goldgrub, + /obj/effect/landmark/mob_spawner/gutlunch, + ) = 1, + ) + +/obj/effect/spawner/random/pool/lavaland_fauna/Initialize(mapload) + . = ..() + if(SSmapping.caves_theme) + fauna_scan_range = SSmapping.caves_theme.fauna_scan_range + megafauna_scan_range = SSmapping.caves_theme.megafauna_scan_range + + for(var/obj/item/gps/ruin/mining_base/base_gps in GLOB.poi_list) + mining_base_gps = get_turf(base_gps) + break + +/obj/effect/spawner/random/pool/lavaland_fauna/record_item(type_path_to_make) + if(ispath(type_path_to_make, /obj/effect/spawner/random/pool)) + return + + SSblackbox.record_feedback("tally", "lavaland_mob_spawns", 1, "[type_path_to_make]") + +/obj/effect/spawner/random/pool/lavaland_fauna/check_safe(type_path_to_make) + var/turf/T = get_turf(src) + + for(var/thing in urange(fauna_scan_range, T)) + // avoid spawning a mob if there's another one within the scan range + if(istype(thing, /obj/effect/landmark/mob_spawner)) + return FALSE + + return ..() + +/obj/effect/spawner/random/pool/lavaland_fauna/megafauna + spawn_pool_id = "lavaland_megafauna_spawn_pool" + point_value = 1 + loot = list( + /mob/living/simple_animal/hostile/megafauna/dragon = 4, + /mob/living/simple_animal/hostile/megafauna/colossus = 2, + ) + +/obj/effect/spawner/random/pool/lavaland_fauna/megafauna/check_safe(type_path_to_make) + var/turf/T = get_turf(src) + var/area/A = get_area(T) + var/okay_area = istype(A, /area/lavaland/surface/outdoors/unexplored/danger) + var/okay_turf = TRUE + + if(mining_base_gps && mining_base_gps.z == T.z) + okay_turf = get_dist(mining_base_gps, T) > 64 + + if(!okay_area || !okay_turf) + return FALSE + + for(var/thing in urange(fauna_scan_range, T)) + // avoid spawning a megafauna if there's another one within the scan range + if(ismegafauna(thing) && get_dist(T, thing) <= megafauna_scan_range) + return FALSE + + return ..() + +/obj/effect/spawner/random/pool/lavaland_fauna/megafauna/unique + unique_picks = TRUE + loot = list( + /mob/living/simple_animal/hostile/megafauna/bubblegum, + /mob/living/simple_animal/hostile/megafauna/ancient_robot, + ) + +/datum/spawn_pool/tendrils + id = "lavaland_tendril_spawn_pool" + +/datum/spawn_pool/tendrils/New() + . = ..() + available_points = roll("5d4") + roll("1d6") + +/obj/effect/spawner/random/pool/tendril_spawner + spawn_pool_id = "lavaland_tendril_spawn_pool" + point_value = 1 + loot = list( + /obj/structure/spawner/lavaland, + /obj/structure/spawner/lavaland/goliath, + /obj/structure/spawner/lavaland/legion, + ) + record_spawn = TRUE + +/obj/effect/spawner/random/pool/tendril_spawner/record_item(type_path_to_make) + SSblackbox.record_feedback("tally", "lavaland_mob_spawns", 1, "[type_path_to_make]") + +/obj/effect/spawner/random/pool/tendril_spawner/check_safe(type_path_to_make) + var/turf/T = get_turf(src) + for(var/thing in urange(10, T)) + // prevents tendrils spawning in each other's collapse range + if(istype(thing, /obj/structure/spawner/lavaland) && get_dist(T, thing) <= LAVALAND_TENDRIL_COLLAPSE_RANGE) + return FALSE + + return ..() diff --git a/code/modules/awaymissions/mission_code/ruins/gps_ruin.dm b/code/modules/awaymissions/mission_code/ruins/gps_ruin.dm index 51fa3975740..f8108011183 100644 --- a/code/modules/awaymissions/mission_code/ruins/gps_ruin.dm +++ b/code/modules/awaymissions/mission_code/ruins/gps_ruin.dm @@ -11,3 +11,6 @@ /obj/item/gps/ruin/attack_hand(mob/user) attack_self__legacy__attackchain(user) + +/obj/item/gps/ruin/mining_base + gpstag = "Nanotrasen Mining Outpost" diff --git a/code/modules/lavaland/caves_theme.dm b/code/modules/lavaland/caves_theme.dm index ef323ab6b25..ccd59594fd1 100644 --- a/code/modules/lavaland/caves_theme.dm +++ b/code/modules/lavaland/caves_theme.dm @@ -3,33 +3,9 @@ /// Approximate upper bound of the walkable land area on Lavaland, south of the Legion entrance. #define LAVALAND_MAX_CAVE_Y 222 -#define SPAWN_MEGAFAUNA "bluh bluh huge boss" - /// Effective probability modifier for spawning flora and fauna in oases. #define OASIS_SPAWNER_PROB_MODIFIER 43 -GLOBAL_LIST_INIT(megafauna_spawn_list, list( - /mob/living/simple_animal/hostile/megafauna/dragon = 4, - /mob/living/simple_animal/hostile/megafauna/colossus = 2, - /mob/living/simple_animal/hostile/megafauna/bubblegum = 6, - /mob/living/simple_animal/hostile/megafauna/ancient_robot = 4, -)) - -GLOBAL_LIST_INIT(caves_default_mob_spawns, list( - /obj/effect/landmark/mob_spawner/abandoned_minebot = 6, - /obj/effect/landmark/mob_spawner/goldgrub = 10, - /obj/effect/landmark/mob_spawner/goliath = 50, - /obj/effect/landmark/mob_spawner/gutlunch = 4, - /obj/effect/landmark/mob_spawner/legion = 30, - /obj/effect/landmark/mob_spawner/watcher = 40, - - /obj/structure/spawner/lavaland = 2, - /obj/structure/spawner/lavaland/goliath = 3, - /obj/structure/spawner/lavaland/legion = 3, - - SPAWN_MEGAFAUNA = 6, -)) - GLOBAL_LIST_INIT(caves_default_flora_spawns, list( /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/cap_shroom = 2, @@ -39,39 +15,6 @@ GLOBAL_LIST_INIT(caves_default_flora_spawns, list( /obj/structure/flora/ash/tall_shroom = 2, )) -/proc/lavaland_caves_spawn_mob(turf/T, mob_scan_range = 12, megafauna_scan_range = 7) - var/mob_spawn = pickweight(GLOB.caves_default_mob_spawns) - - while(mob_spawn == SPAWN_MEGAFAUNA) - if(istype(get_area(T), /area/lavaland/surface/outdoors/unexplored/danger)) //this is danger. it's boss time. - mob_spawn = pickweight(GLOB.megafauna_spawn_list) - else //this is not danger, don't spawn a boss, spawn something else - mob_spawn = pickweight(GLOB.caves_default_mob_spawns) - - for(var/thing in urange(mob_scan_range, T)) - if(!(ishostile(thing) || istype(thing, /obj/structure/spawner) || istype(thing, /obj/effect/landmark/mob_spawner))) - continue - // don't spawn a megafauna if there's already one within view - if((ispath(mob_spawn, /mob/living/simple_animal/hostile/megafauna) || ismegafauna(thing)) && (get_dist(T, thing) <= megafauna_scan_range)) - return - // if the random is a standard mob, avoid spawning if there's another one within the scan range - if(ispath(mob_spawn, /obj/effect/landmark/mob_spawner) && istype(thing, /obj/effect/landmark/mob_spawner)) - return - // prevents tendrils spawning in each other's collapse range - if((ispath(mob_spawn, /obj/structure/spawner/lavaland) && istype(thing, /obj/structure/spawner/lavaland)) && get_dist(T, thing) <= LAVALAND_TENDRIL_COLLAPSE_RANGE) - return - - // there can be only one bubblegum, so don't waste spawns on it - if(ispath(mob_spawn, /mob/living/simple_animal/hostile/megafauna/bubblegum)) - GLOB.megafauna_spawn_list.Remove(mob_spawn) - - // same as above, we do not want multiple of these robots - if(ispath(mob_spawn, /mob/living/simple_animal/hostile/megafauna/ancient_robot)) - GLOB.megafauna_spawn_list.Remove(mob_spawn) - - new mob_spawn(T) - SSblackbox.record_feedback("tally", "lavaland_mob_spawns", 1, "[mob_spawn]") - /proc/lavaland_caves_spawn_flora(turf/T) var/flora_spawn = pickweight(GLOB.caves_default_flora_spawns) for(var/obj/structure/flora/ash/F in range(4, T)) //Allows for growing patches, but not ridiculous stacks of flora @@ -88,6 +31,9 @@ GLOBAL_LIST_INIT(caves_default_flora_spawns, list( var/perlin_lower_range = 0 var/perlin_upper_range = 0.3 + var/fauna_scan_range = 12 + var/megafauna_scan_range =7 + /datum/caves_theme/New() seed = rand(1, 999999) @@ -110,7 +56,7 @@ GLOBAL_LIST_INIT(caves_default_flora_spawns, list( if(prob(2)) lavaland_caves_spawn_flora(T) else if(prob(1)) - lavaland_caves_spawn_mob(T) + new /obj/effect/spawner/random/lavaland_fauna(T) /datum/caves_theme/proc/safe_replace(turf/T) if(T.flags & NO_LAVA_GEN) @@ -138,13 +84,18 @@ GLOBAL_LIST_INIT(caves_default_flora_spawns, list( perlin_lower_range = 0 perlin_upper_range = 0.3 +/datum/caves_theme/burrows/New() + . = ..() + fauna_scan_range = rand(4, 7) + megafauna_scan_range = rand(4, 7) + /datum/caves_theme/burrows/on_change(turf/T) if(prob(7)) new /obj/structure/flora/ash/rock/style_random(T) else if(prob(5)) lavaland_caves_spawn_flora(T) else if(prob(1)) - lavaland_caves_spawn_mob(T) + new /obj/effect/spawner/random/lavaland_fauna(T) /datum/caves_theme/deeprock/proc/maybe_make_room(turf/T) if(rand(1, 150) != 1) @@ -155,7 +106,6 @@ GLOBAL_LIST_INIT(caves_default_flora_spawns, list( return oasis_centroids |= T - var/new_scan_range = rand(4, 7) var/tempradius = rand(10, 15) var/probmodifer = OASIS_SPAWNER_PROB_MODIFIER * tempradius var/list/oasis_turfs = list() @@ -164,7 +114,7 @@ GLOBAL_LIST_INIT(caves_default_flora_spawns, list( if(safe_replace(NT) && prob(min(probmodifer / distance, 100))) var/turf/changed = NT.ChangeTurf(/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface) if(prob(5)) - lavaland_caves_spawn_mob(changed, new_scan_range, new_scan_range) + new /obj/effect/spawner/random/lavaland_fauna(T) else if(prob(10)) lavaland_caves_spawn_flora(changed) oasis_turfs |= NT @@ -180,7 +130,7 @@ GLOBAL_LIST_INIT(caves_default_flora_spawns, list( oasis_turfs -= oasis // Move tendrils out of the oasis - for(var/obj/structure/spawner/lavaland/O in circlerange(T, tempradius)) + for(var/obj/effect/spawner/random/pool/tendril_spawner/O in circlerange(T, tempradius)) O.forceMove(pick_n_take(oasis_turfs)) return T @@ -206,11 +156,10 @@ GLOBAL_LIST_INIT(caves_default_flora_spawns, list( if(prob(3)) lavaland_caves_spawn_flora(T) else if(prob(2)) - lavaland_caves_spawn_mob(T) + new /obj/effect/spawner/random/lavaland_fauna(T) #undef OASIS_SPAWNER_PROB_MODIFIER -#undef SPAWN_MEGAFAUNA #undef LAVALAND_MIN_CAVE_Y #undef LAVALAND_MAX_CAVE_Y diff --git a/paradise.dme b/paradise.dme index 16c91939a54..96d6995744a 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1111,6 +1111,7 @@ #include "code\game\objects\effects\spawners\random\random_spawner.dm" #include "code\game\objects\effects\spawners\random\toy_spawners.dm" #include "code\game\objects\effects\spawners\random\trash_spawners.dm" +#include "code\game\objects\effects\spawners\random\pool\lavaland_pools.dm" #include "code\game\objects\effects\spawners\random\pool\misc_pools.dm" #include "code\game\objects\effects\spawners\random\pool\pool_spawner.dm" #include "code\game\objects\effects\spawners\random\pool\space_loot.dm"