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:
warriorstar-orion
2024-10-10 00:05:29 +00:00
committed by GitHub
parent 89bf882c98
commit 62b65f8a91
27 changed files with 5213 additions and 5563 deletions
+2 -6
View File
@@ -592,12 +592,6 @@
/// Mutes the democracy mode messages send to orbiters at the end of each cycle. Useful for when the cooldown is so low it'd get spammy.
#define MUTE_DEADCHAT_DEMOCRACY_MESSAGES (1<<2)
// Lavaland cave design defines
#define BLOCKED_BURROWS "Blocked Burrows"
#define CLASSIC_CAVES "Classic Caves"
#define DEADLY_DEEPROCK "Deadly Deeprock"
///Sleep check QDEL. Like sleep check death, but checks deleting. Good for non mobs.
#define SLEEP_CHECK_QDEL(X) sleep(X); if(QDELETED(src)) return;
// Request console message priority defines
@@ -735,4 +729,6 @@ do { \
#define INGREDIENT_CHECK_FAILURE 0
#define INGREDIENT_CHECK_SURPLUS -1
#define LAVALAND_TENDRIL_COLLAPSE_RANGE 2 //! The radius of the chasm created by killed tendrils.
#define ALPHA_VISIBLE 255 // the max alpha
@@ -15,7 +15,7 @@ SUBSYSTEM_DEF(mapping)
///What do we have as the lavaland theme today?
var/datum/lavaland_theme/lavaland_theme
///What primary cave theme we have picked for cave generation today.
var/cave_theme
var/datum/caves_theme/caves_theme
// Tells if all maintenance airlocks have emergency access enabled
var/maint_all_access = FALSE
// Tells if all station airlocks have emergency access enabled
@@ -55,10 +55,15 @@ SUBSYSTEM_DEF(mapping)
var/datum/lavaland_theme/lavaland_theme_type = pick(subtypesof(/datum/lavaland_theme))
ASSERT(lavaland_theme_type)
lavaland_theme = new lavaland_theme_type
log_startup_progress("We're in the mood for [initial(lavaland_theme.name)] today...") //We load this first. In the event some nerd ever makes a surface map, and we don't have it in lavaland in the event lavaland is disabled.
log_startup_progress("We're in the mood for [lavaland_theme.name] today...") //We load this first. In the event some nerd ever makes a surface map, and we don't have it in lavaland in the event lavaland is disabled.
SSblackbox.record_feedback("text", "procgen_settings", 1, "[lavaland_theme_type]")
var/caves_theme_type = pick(subtypesof(/datum/caves_theme))
ASSERT(caves_theme_type)
caves_theme = new caves_theme_type
log_startup_progress("We feel like [caves_theme.name] today...")
SSblackbox.record_feedback("text", "procgen_settings", 1, "[caves_theme_type]")
cave_theme = pick(BLOCKED_BURROWS, CLASSIC_CAVES, DEADLY_DEEPROCK)
log_startup_progress("We feel like [cave_theme] today...")
// Load all Z level templates
preloadTemplates()
preloadTemplates(path = "code/modules/unit_tests/atmos/")
@@ -89,7 +94,8 @@ SUBSYSTEM_DEF(mapping)
seedRuins(list(level_name_to_num(MINING)), GLOB.configuration.ruins.lavaland_ruin_budget, /area/lavaland/surface/outdoors/unexplored, GLOB.lava_ruins_templates)
if(lavaland_theme)
lavaland_theme.setup()
lavaland_theme.setup_caves()
if(caves_theme)
caves_theme.setup()
var/time_spent = stop_watch(lavaland_setup_timer)
log_startup_progress("Successfully populated lavaland in [time_spent]s.")
else
+3
View File
@@ -160,6 +160,9 @@
name = "Lavaland Wastes"
outdoors = TRUE
/area/lavaland/surface/outdoors/legion_arena
name = "Legion Arena"
/// monsters and ruins spawn here
/area/lavaland/surface/outdoors/unexplored
icon_state = "unexplored"
@@ -88,7 +88,7 @@ GLOBAL_LIST_EMPTY(tendrils)
shake_camera(M, 15, 1)
playsound(get_turf(src),'sound/effects/explosionfar.ogg', 200, TRUE)
visible_message("<span class='boldannounceic'>The tendril falls inward, the ground around it widening into a yawning chasm!</span>")
for(var/turf/T in range(2,src))
for(var/turf/T in range(LAVALAND_TENDRIL_COLLAPSE_RANGE, src))
if(!T.density)
T.TerraformTurf(/turf/simulated/floor/chasm/straight_down/lava_land_surface)
qdel(src)
@@ -1,7 +1,6 @@
/**********************Asteroid**************************/
#define RECURSION_MAX 100
/turf/simulated/floor/plating/asteroid
gender = PLURAL
name = "asteroid sand"
@@ -186,168 +185,6 @@
nitrogen = 0
turf_type = /turf/simulated/floor/plating/asteroid/airless
#define SPAWN_MEGAFAUNA "bluh bluh huge boss"
#define SPAWN_BUBBLEGUM 6
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 = SPAWN_BUBBLEGUM, /mob/living/simple_animal/hostile/megafauna/ancient_robot = 4))
/turf/simulated/floor/plating/asteroid/airless/cave
var/length = 100
var/list/mob_spawn_list
var/list/megafauna_spawn_list
var/list/flora_spawn_list
var/sanity = 1
var/forward_cave_dir = 1
var/backward_cave_dir = 2
var/going_backwards = TRUE
var/has_data = FALSE
/// Very important for making sure prod won't die due to poor RNG from cave spawns
var/recursions = 0
var/data_having_type = /turf/simulated/floor/plating/asteroid/airless/cave/has_data
turf_type = /turf/simulated/floor/plating/asteroid/airless
/// subtype for producing a tunnel with given data
/turf/simulated/floor/plating/asteroid/airless/cave/has_data
has_data = TRUE
/turf/simulated/floor/plating/asteroid/airless/cave/volcanic
mob_spawn_list = list(/obj/effect/landmark/mob_spawner/goliath = 50, /obj/structure/spawner/lavaland/goliath = 3,
/obj/effect/landmark/mob_spawner/watcher = 40, /obj/structure/spawner/lavaland = 2,
/obj/effect/landmark/mob_spawner/legion = 30, /obj/structure/spawner/lavaland/legion = 3,
SPAWN_MEGAFAUNA = 6, /obj/effect/landmark/mob_spawner/goldgrub = 10, /obj/effect/landmark/mob_spawner/gutlunch = 4,
/obj/effect/landmark/mob_spawner/abandoned_minebot = 6)
data_having_type = /turf/simulated/floor/plating/asteroid/airless/cave/volcanic/has_data
turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface
oxygen = LAVALAND_OXYGEN
nitrogen = LAVALAND_NITROGEN
temperature = LAVALAND_TEMPERATURE
/// subtype for producing a tunnel with given data
/turf/simulated/floor/plating/asteroid/airless/cave/volcanic/has_data
has_data = TRUE
/turf/simulated/floor/plating/asteroid/airless/cave/Initialize(mapload)
if(!mob_spawn_list)
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3)
if(!megafauna_spawn_list)
megafauna_spawn_list = GLOB.megafauna_spawn_list
if(!flora_spawn_list)
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2, /obj/structure/flora/ash/cap_shroom = 2, /obj/structure/flora/ash/stem_shroom = 2, /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2, /obj/structure/flora/ash/rock/style_random = 1)
if(SSmapping.cave_theme == BLOCKED_BURROWS)
flora_spawn_list += list(/obj/structure/flora/ash/rock/style_random = 3) //Let us see how this goes
. = ..()
if(!has_data)
produce_tunnel_from_data()
/turf/simulated/floor/plating/asteroid/airless/cave/proc/get_cave_data(set_length, exclude_dir = -1)
// If set_length (arg1) isn't defined, get a random length; otherwise assign our length to the length arg.
if(!set_length)
length = rand(25, 50)
else
length = set_length
// Get our directiosn
forward_cave_dir = pick(GLOB.alldirs - exclude_dir)
// Get the opposite direction of our facing direction
backward_cave_dir = angle2dir(dir2angle(forward_cave_dir) + 180)
/turf/simulated/floor/plating/asteroid/airless/cave/proc/produce_tunnel_from_data(tunnel_length, excluded_dir = -1)
if(!tunnel_length)//This is a sub cave do not overide repeat do not overide
get_cave_data(tunnel_length, excluded_dir)
switch(SSmapping.cave_theme)
if(BLOCKED_BURROWS) //Longer on average
get_cave_data(rand(40, 60), excluded_dir)
if(CLASSIC_CAVES) //Classic
get_cave_data(tunnel_length, excluded_dir)
if(DEADLY_DEEPROCK) //Smaller into large rooms with more mobs.
get_cave_data(rand(20, 40), excluded_dir)
if(prob(25)) //Less caves due to big openings. This may lead to fauna inside 1x1 rooms. We'll call that a suprise mechanic
SpawnFloor(src, 75) //now with extra suprise
return
// Make our tunnels
make_tunnel(forward_cave_dir)
if(going_backwards)
make_tunnel(backward_cave_dir)
// Kill ourselves by replacing ourselves with a normal floor.
SpawnFloor(src)
/turf/simulated/floor/plating/asteroid/airless/cave/proc/make_tunnel(dir)
var/turf/simulated/mineral/tunnel = src
var/next_angle = pick(45, -45)
for(var/i in 1 to length)
++recursions
if(recursions > RECURSION_MAX)
break
if(!sanity)
break
var/list/L = list(45)
if(ISODD(dir2angle(dir)) && (!(SSmapping.cave_theme == BLOCKED_BURROWS) || prob(15)))
L += -45
// Expand the edges of our tunnel
for(var/edge_angle in L)
var/turf/simulated/mineral/edge = get_step(tunnel, angle2dir(dir2angle(dir) + edge_angle))
if(istype(edge))
SpawnFloor(edge)
if(!sanity)
break
// Move our tunnel forward
tunnel = get_step(tunnel, dir)
// Separate ruin area check here because of the raw ChangeTurf call that
// doesn't go through SpawnFloor/Flora/Monster.
if(istype(tunnel) && !istype(tunnel.loc, /area/ruin))
// Small chance to have forks in our tunnel; otherwise dig our tunnel.
var/caveprob = 20
switch(SSmapping.cave_theme)
if(BLOCKED_BURROWS) //Longer on average
caveprob = 30 //More splitting
if(DEADLY_DEEPROCK) //Smaller into large rooms with more mobs.
caveprob = 10 //Less splitting
if(i > 3 && prob(caveprob))
var/turf/simulated/floor/plating/asteroid/airless/cave/C = tunnel.ChangeTurf(data_having_type, FALSE, TRUE)
C.recursions = recursions
C.going_backwards = FALSE
C.produce_tunnel_from_data(rand(10, 15), dir)
else
SpawnFloor(tunnel)
else //if(!istype(tunnel, src.parent)) // We hit space/normal/wall, stop our tunnel.
break
// Chance to change our direction left or right.
if(i > 2 && prob(33))
// We can't go a full loop though
if(!SSmapping.cave_theme == BLOCKED_BURROWS || prob(60))
next_angle = -next_angle
setDir(angle2dir(dir2angle(dir) )+ next_angle)
if(length -2 == i && !has_data) //Branches will not make this
SpawnRoom(tunnel)
/turf/simulated/floor/plating/asteroid/airless/cave/proc/SpawnRoom(turf/T)
switch(SSmapping.cave_theme)
if(DEADLY_DEEPROCK)
var/tempradius = rand(10, 15)
var/probmodifer = 43 * tempradius //Yes this is a magic number, it is a magic number that works well.
for(var/turf/NT in circlerangeturfs(T, tempradius))
var/distance = (max(get_dist(T, NT), 1)) //Get dist throws -1 if same turf
if(prob(min(probmodifer / distance, 100)))
if((ismineralturf(NT) || istype(NT, /turf/simulated/floor/plating/asteroid)) && !istype(NT.loc, /area/ruin)) //No spawning on lava / other ruins
SpawnFloor(NT, 50) //Room has higher probabilty.
if(prob(25))
tempradius = round(tempradius / 3)
var/turf/oasis_lake = pickweight(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))
if(oasis_lake == /turf/simulated/floor/plating/asteroid)
new /obj/effect/spawner/oasisrock(T, tempradius)
for(var/turf/oasis in circlerangeturfs(T, tempradius))
if(istype(oasis.loc, /area/ruin))
continue
oasis.ChangeTurf(oasis_lake, ignore_air = TRUE)
/obj/effect/spawner/oasisrock
name = "Oasis rock spawner"
var/passed_radius
@@ -375,86 +212,6 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me
O.forceMove(pick_n_take(valid_turfs))
qdel(src)
/turf/simulated/floor/plating/asteroid/airless/cave/proc/SpawnFloor(turf/T, monsterprob = 30)
if(istype(T.loc, /area/ruin))
return
for(var/S in RANGE_TURFS(1, src))
var/turf/NT = S
if(!NT || isspaceturf(NT) || istype(NT.loc, /area/lavaland/surface/outdoors/explored))
sanity = 0
break
if(!sanity)
return
SpawnFlora(T)
SpawnMonster(T, monsterprob)
T.ChangeTurf(turf_type, FALSE, FALSE, TRUE)
/turf/simulated/floor/plating/asteroid/airless/cave/proc/SpawnMonster(turf/T, monsterprob = 30)
if(istype(T.loc, /area/ruin))
return
if(prob(monsterprob))
if(!istype(loc, /area/lavaland/surface/outdoors/unexplored))
return
var/randumb = pickweight(mob_spawn_list)
while(randumb == SPAWN_MEGAFAUNA)
if(istype(loc, /area/lavaland/surface/outdoors/unexplored/danger)) //this is danger. it's boss time.
var/maybe_boss = pickweight(megafauna_spawn_list)
if(megafauna_spawn_list[maybe_boss])
randumb = maybe_boss
else //this is not danger, don't spawn a boss, spawn something else
randumb = pickweight(mob_spawn_list)
var/scanrange = 12
var/megafaunarange = 7
switch(SSmapping.cave_theme)
if(DEADLY_DEEPROCK)
if(prob(50) && monsterprob > 30)
scanrange = rand(4, 7)
megafaunarange = scanrange
for(var/thing in urange(scanrange, T)) //prevents mob clumps
if(!ishostile(thing) && !istype(thing, /obj/structure/spawner))
continue
if((ismegafauna(randumb) || ismegafauna(thing)) && get_dist(T, thing) <= megafaunarange)
return //if there's a megafauna within standard view don't spawn anything at all
if(ispath(randumb, /obj/effect/landmark/mob_spawner) || istype(thing, /mob/living/simple_animal/hostile/asteroid))
return //if the random is a standard mob, avoid spawning if there's another one within 12 tiles
if((ispath(randumb, /obj/structure/spawner/lavaland) || istype(thing, /obj/structure/spawner/lavaland)) && get_dist(T, thing) <= 2)
return //prevents tendrils spawning in each other's collapse range
if(ispath(randumb, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it
megafauna_spawn_list.Remove(randumb)
if(ispath(randumb, /mob/living/simple_animal/hostile/megafauna/ancient_robot)) //same as above, we do not want multiple of these robots
megafauna_spawn_list.Remove(randumb)
new randumb(T)
SSblackbox.record_feedback("tally", "lavaland_mob_spawns", 1, "[randumb]")
#undef SPAWN_MEGAFAUNA
#undef SPAWN_BUBBLEGUM
#undef RECURSION_MAX
/turf/simulated/floor/plating/asteroid/airless/cave/proc/SpawnFlora(turf/T)
if(istype(T.loc, /area/ruin))
return
var/floraprob = 12
switch(SSmapping.cave_theme)
if(BLOCKED_BURROWS)
floraprob = 30 //Lots of folliage, lots of blockage
if(prob(floraprob))
if(istype(loc, /area/lavaland/surface/outdoors/explored))
return
var/randumb = pickweight(flora_spawn_list)
for(var/obj/structure/flora/ash/F in range(4, T)) //Allows for growing patches, but not ridiculous stacks of flora
if(!istype(F, randumb))
return
new randumb(T)
/turf/simulated/floor/plating/asteroid/snow
gender = PLURAL
name = "snow"
+1 -1
View File
@@ -137,7 +137,7 @@
/turf/simulated/mineral/random
var/mineralSpawnChanceList = list(/turf/simulated/mineral/uranium = 5, /turf/simulated/mineral/diamond = 1, /turf/simulated/mineral/gold = 10,
/turf/simulated/mineral/silver = 12, /turf/simulated/mineral/plasma = 20, /turf/simulated/mineral/iron = 40, /turf/simulated/mineral/titanium = 11,
/turf/simulated/mineral/gibtonite = 4, /turf/simulated/floor/plating/asteroid/airless/cave = 2, /turf/simulated/mineral/bscrystal = 1)
/turf/simulated/mineral/gibtonite = 4, /turf/simulated/mineral/bscrystal = 1)
//Currently, Adamantine won't spawn as it has no uses. -Durandan
var/mineralChance = 13
+214
View File
@@ -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
-21
View File
@@ -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