mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 11:37:40 +01:00
Rework Lavaland tunnel themes. (#26599)
* Rework Lavaland tunnel themes. * Fix deeprock mob density; ensure 1 vetus/bubblegum * goddamnit * bring spawn odds closer in line to head, fix tendril collapse range * Move define to global dir * don't need initial here * define magic number properly * make type of var clear * CHECK_TICK during procgen * less tendril cities, no tendrils in oasis centers * revert no_lava helpers for now * add NO_LAVA_GEN flag check back to safe_replace * add blackbox feedback for themes
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
/// Approximate lower bound of the walkable land area on Lavaland, north of the southern lava border.
|
||||
#define LAVALAND_MIN_CAVE_Y 10
|
||||
/// 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,
|
||||
/obj/structure/flora/ash/leaf_shroom = 2,
|
||||
/obj/structure/flora/ash/rock/style_random = 1,
|
||||
/obj/structure/flora/ash/stem_shroom = 2,
|
||||
/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
|
||||
if(!istype(F, flora_spawn))
|
||||
return
|
||||
new flora_spawn(T)
|
||||
|
||||
/datum/caves_theme
|
||||
var/name = "Not Specified"
|
||||
|
||||
var/seed
|
||||
var/perlin_accuracy = 5
|
||||
var/perlin_stamp_size = 10
|
||||
var/perlin_lower_range = 0
|
||||
var/perlin_upper_range = 0.3
|
||||
|
||||
/datum/caves_theme/New()
|
||||
seed = rand(1, 999999)
|
||||
|
||||
/datum/caves_theme/proc/setup()
|
||||
var/result = rustg_dbp_generate("[seed]", "[perlin_accuracy]", "[perlin_stamp_size]", "[world.maxx]", "[perlin_lower_range]", "[perlin_upper_range]")
|
||||
var/z = level_name_to_num(MINING)
|
||||
for(var/turf/T in block(1, 1, z, world.maxx, world.maxy, z))
|
||||
if(!istype(get_area(T), /area/lavaland/surface/outdoors/unexplored))
|
||||
continue
|
||||
if(!istype(T, /turf/simulated/mineral))
|
||||
continue
|
||||
var/c = result[world.maxx * (T.y - 1) + T.x]
|
||||
if(c == "1")
|
||||
T.ChangeTurf(/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface)
|
||||
on_change(T)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
/datum/caves_theme/proc/on_change(turf/T)
|
||||
if(prob(2))
|
||||
lavaland_caves_spawn_flora(T)
|
||||
else if(prob(1))
|
||||
lavaland_caves_spawn_mob(T)
|
||||
|
||||
/datum/caves_theme/proc/safe_replace(turf/T)
|
||||
if(T.flags & NO_LAVA_GEN)
|
||||
return FALSE
|
||||
if(!istype(get_area(T), /area/lavaland/surface/outdoors/unexplored))
|
||||
return FALSE
|
||||
if(istype(T, /turf/simulated/floor/chasm))
|
||||
return FALSE
|
||||
if(istype(T, /turf/simulated/floor/lava/lava_land_surface))
|
||||
return FALSE
|
||||
if(istype(T, /turf/simulated/floor/lava/mapping_lava))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/caves_theme/classic
|
||||
name = "Classic Caves"
|
||||
|
||||
/datum/caves_theme/burrows
|
||||
name = "Blocked Burrows"
|
||||
perlin_accuracy = 90
|
||||
perlin_stamp_size = 7
|
||||
perlin_lower_range = 0
|
||||
perlin_upper_range = 0.3
|
||||
|
||||
/datum/caves_theme/burrows/on_change(turf/T)
|
||||
if(prob(9))
|
||||
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)
|
||||
|
||||
/datum/caves_theme/deeprock/proc/maybe_make_room(turf/T)
|
||||
if(rand(1, 150) != 1)
|
||||
return
|
||||
|
||||
for(var/turf/oasis_centroid in oasis_centroids)
|
||||
if(get_dist(T, oasis_centroid) < oasis_padding)
|
||||
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()
|
||||
for(var/turf/NT in circlerangeturfs(T, tempradius))
|
||||
var/distance = (max(get_dist(T, NT), 1)) //Get dist throws -1 if same turf
|
||||
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)
|
||||
else if(prob(10))
|
||||
lavaland_caves_spawn_flora(changed)
|
||||
oasis_turfs |= NT
|
||||
|
||||
if(prob(50))
|
||||
tempradius = round(tempradius / 3)
|
||||
var/oasis_laketype = pickweight(lake_weights)
|
||||
if(oasis_laketype == /turf/simulated/floor/plating/asteroid)
|
||||
new /obj/effect/spawner/oasisrock(T, tempradius)
|
||||
for(var/turf/oasis in circlerangeturfs(T, tempradius))
|
||||
if(safe_replace(oasis))
|
||||
oasis.ChangeTurf(oasis_laketype)
|
||||
oasis_turfs -= oasis
|
||||
|
||||
// Move tendrils out of the oasis
|
||||
for(var/obj/structure/spawner/lavaland/O in circlerange(T, tempradius))
|
||||
O.forceMove(pick_n_take(oasis_turfs))
|
||||
|
||||
return T
|
||||
|
||||
/datum/caves_theme/deeprock
|
||||
name = "Deadly Deeprock"
|
||||
perlin_stamp_size = 12
|
||||
perlin_lower_range = 0
|
||||
perlin_upper_range = 0.2
|
||||
var/oasis_padding = 50
|
||||
var/list/oasis_centroids = list()
|
||||
var/lake_weights = list(
|
||||
/turf/simulated/floor/lava/lava_land_surface = 4,
|
||||
/turf/simulated/floor/lava/lava_land_surface/plasma = 4,
|
||||
/turf/simulated/floor/chasm/straight_down/lava_land_surface = 4,
|
||||
/turf/simulated/floor/lava/mapping_lava = 6,
|
||||
/turf/simulated/floor/beach/away/water/lavaland_air = 1,
|
||||
/turf/simulated/floor/plating/asteroid = 1
|
||||
)
|
||||
|
||||
/datum/caves_theme/deeprock/on_change(turf/T)
|
||||
maybe_make_room(T)
|
||||
if(prob(3))
|
||||
lavaland_caves_spawn_flora(T)
|
||||
else if(prob(2))
|
||||
lavaland_caves_spawn_mob(T)
|
||||
|
||||
|
||||
#undef OASIS_SPAWNER_PROB_MODIFIER
|
||||
#undef SPAWN_MEGAFAUNA
|
||||
|
||||
#undef LAVALAND_MIN_CAVE_Y
|
||||
#undef LAVALAND_MAX_CAVE_Y
|
||||
@@ -1,8 +1,3 @@
|
||||
/// Approximate lower bound of the walkable land area on Lavaland, north of the southern lava border.
|
||||
#define LAVALAND_MIN_CAVE_Y 10
|
||||
/// Approximate upper bound of the walkable land area on Lavaland, south of the Legion entrance.
|
||||
#define LAVALAND_MAX_CAVE_Y 222
|
||||
|
||||
/datum/lavaland_theme
|
||||
/// Name of lavaland theme
|
||||
var/name = "Not Specified"
|
||||
@@ -17,20 +12,6 @@
|
||||
else if(!ispath(primary_turf_type))
|
||||
stack_trace("Wrong turf type `[primary_turf_type.type]` in `[type]` lavaland theme")
|
||||
|
||||
/datum/lavaland_theme/proc/setup_caves()
|
||||
var/max_attempts = 100
|
||||
var/max_cave_spawns = 40
|
||||
var/z = level_name_to_num(MINING)
|
||||
while(max_attempts > 0 && max_cave_spawns > 0)
|
||||
var/x = rand(1, world.maxx)
|
||||
var/y = rand(LAVALAND_MIN_CAVE_Y, LAVALAND_MAX_CAVE_Y)
|
||||
var/turf/next_turf = locate(x, y, z)
|
||||
var/area/next_area = get_area(next_turf)
|
||||
if(istype(next_turf, /turf/simulated/mineral/random/volcanic) && istype(next_area, /area/lavaland/surface/outdoors/unexplored/danger))
|
||||
next_turf.ChangeTurf(/turf/simulated/floor/plating/asteroid/airless/cave/volcanic, FALSE, TRUE, TRUE)
|
||||
max_cave_spawns--
|
||||
max_attempts--
|
||||
|
||||
/**
|
||||
* This proc should do all theme specific thing.
|
||||
* Now it only generates rivers, but it can do all stuff you desire.
|
||||
@@ -66,5 +47,3 @@
|
||||
var/datum/river_spawner/spawner = new(level_name_to_num(MINING), spread_prob_ = 10, spread_prob_loss_ = 5)
|
||||
spawner.generate(nodes = 6, min_x = 50, min_y = 7, max_x = 250, max_y = 225)
|
||||
|
||||
#undef LAVALAND_MIN_CAVE_Y
|
||||
#undef LAVALAND_MAX_CAVE_Y
|
||||
|
||||
Reference in New Issue
Block a user