diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_cube.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_cube.dmm index 3e64a36fdb4..6c3818b43ec 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_cube.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_cube.dmm @@ -1,13 +1,13 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "b" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( /obj/effect/decal/remains/human, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "d" = ( /turf/closed/indestructible/riveted, @@ -15,7 +15,7 @@ "e" = ( /obj/machinery/wish_granter, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 8d98ff05bd5..7b1b55341c5 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -17,6 +17,9 @@ SUBSYSTEM_DEF(mapping) var/list/ruins_templates = list() + ///Assoc list of all ruins spawned, key center of ruin spawn -> value ruin instance + var/list/active_ruins = alist() + ///List of ruins, separated by their theme var/list/themed_ruins = list() diff --git a/code/datums/mapgen/CaveGenerator.dm b/code/datums/mapgen/CaveGenerator.dm index 63b47165db4..316f9659e91 100644 --- a/code/datums/mapgen/CaveGenerator.dm +++ b/code/datums/mapgen/CaveGenerator.dm @@ -86,15 +86,31 @@ /// Radius around megafauna within which we avoid spawning tendrils var/megafauna_exclusion_radius = 7 - ///Chance of cells starting closed - var/initial_closed_chance = 45 - ///Amount of smoothing iterations - var/smoothing_iterations = 20 - ///How much neighbours does a dead cell need to become alive - var/birth_limit = 4 - ///How little neighbours does a alive cell need to die - var/death_limit = 3 + ///Cave gen settings below!! + + /// Minimum dimension of a BSP leaf in the generator. Raising this creates larger pockets but can end up making for big corridors + var/min_bsp_size = 25 + /// Maximum aspect ratio for BSP splits for lavaland generator + var/max_ratio = 1.5 + /// Room edge padding within BSP leaf for lavaland generator + var/padding = 1 + /// How much of each BSP leaf is considered untouchable by the cellular automata. Raising this generally means bigger pockets + var/room_fill_percent = 30 + /// Width of corridors between rooms for lavaland generator. Raising this just means corridors are AT LEAST this wide. but cellular automata can make them bigger + var/corridor_width = 1 + /// Chance to add extra MST edges for loops for lavaland generator. This basically results in more corridors / mazier generation + var/loop_percent = 15 + /// Initial random floor density for lavaland generator + var/noise_percent = 51 + /// Cellular Automata smoothing iterations for lavaland generator + var/ca_steps = 8 + /// Neighbors to create floor (>=) for lavaland generator + var/birth_limit = 6 + /// Neighbors to survive as floor (>=) for lavaland generator + var/survival_limit = 4 + ///Whether out-of-boudns counts as being alive. Setting this to FALSE results in the edges of the generator generating more closed. Default behavior tends to open up tunnels outside. + var/edges_are_alive = TRUE /datum/map_generator/cave_generator/New() . = ..() @@ -138,10 +154,11 @@ return generate_terrain_with_biomes(turfs, generate_in) var/start_time = REALTIMEOFDAY - string_gen = rustg_cnoise_generate("[initial_closed_chance]", "[smoothing_iterations]", "[birth_limit]", "[death_limit]", "[world.maxx]", "[world.maxy]") //Generate the raw CA data + + string_gen = generate_cave(generate_in) for(var/turf/gen_turf as anything in turfs) //Go through all the turfs and generate them - var/closed = string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x] != "0" + var/closed = string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x] != "1" var/turf/new_turf = pick(closed ? closed_turf_types : open_turf_types) // The assumption is this will be faster then changeturf, and changeturf isn't required since by this point @@ -190,7 +207,7 @@ heat_seed = rand(0, 50000) var/start_time = REALTIMEOFDAY - string_gen = rustg_cnoise_generate("[initial_closed_chance]", "[smoothing_iterations]", "[birth_limit]", "[death_limit]", "[world.maxx]", "[world.maxy]") //Generate the raw CA data + string_gen = generate_cave(generate_in) var/humidity_gen = list() humidity_gen[BIOME_HIGH_HUMIDITY] = rustg_dbp_generate("[humidity_seed]", "60", "[biome_stamp_size]", "[world.maxx]", "[high_heat_threshold]", "1.1") @@ -210,7 +227,7 @@ var/list/to_generate = list() for(var/turf/gen_turf as anything in turfs) //Go through all the turfs and generate them - var/closed = string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x] != "0" + var/closed = string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x] != "1" var/datum/biome/selected_biome // Here comes the meat of the biome code. @@ -405,6 +422,32 @@ to_chat(world, span_boldannounce("[message]"), MESSAGE_TYPE_DEBUG) log_world(message) + +///Generates the cave shape using Rust-G +/datum/map_generator/cave_generator/proc/generate_cave(area/generate_in) + + ///Loop through all the active ruins for this z-level and make a json format out of it so we can send it to the generator + var/list/active_ruins_list = list() + + for(var/turf/bottom_left_turf in SSmapping.active_ruins) + var/datum/map_template/ruin/active_ruin = SSmapping.active_ruins[bottom_left_turf] + if(bottom_left_turf.z != generate_in.z) + continue + active_ruins_list += list(list( + "x" = max(1, bottom_left_turf.x - active_ruin.terrain_padding), + "y" = max(1, bottom_left_turf.y - active_ruin.terrain_padding), + "w" = active_ruin.width + active_ruin.terrain_padding * 2, + "h" = active_ruin.height + active_ruin.terrain_padding * 2, + "isEnclosed" = active_ruin.enclosed_for_terrain, + )) + + var/active_ruin_string = json_encode(active_ruins_list) + + var/string_gen = rustg_cave_system_generator_generate("[world.maxx]", "[world.maxy]", active_ruin_string, "[min_bsp_size]","[max_ratio]", "[padding]", "[room_fill_percent]", "[corridor_width]","[loop_percent]", "[noise_percent]", "[ca_steps]", "[birth_limit]", "[survival_limit]", "[edges_are_alive]") + + return string_gen + + /datum/map_generator/cave_generator/jungle possible_biomes = list( BIOME_LOW_HEAT = list( diff --git a/code/datums/mapgen/Cavegens/IcemoonCaves.dm b/code/datums/mapgen/Cavegens/IcemoonCaves.dm index 91efa9988be..45f429c0fe8 100644 --- a/code/datums/mapgen/Cavegens/IcemoonCaves.dm +++ b/code/datums/mapgen/Cavegens/IcemoonCaves.dm @@ -39,10 +39,7 @@ weighted_open_turf_types = list(/turf/open/misc/asteroid/snow/icemoon = 1) flora_spawn_chance = 60 weighted_mob_spawn_list = null - initial_closed_chance = 0 - birth_limit = 5 - death_limit = 4 - smoothing_iterations = 10 + noise_percent = 100 // Full floor feature_spawn_chance = 0.15 weighted_feature_spawn_list = list( @@ -62,7 +59,7 @@ /// Surface snow generator variant for forested station trait, WITH FORESTSSSS /datum/map_generator/cave_generator/icemoon/surface/forested - initial_closed_chance = 10 + noise_percent = 65 //Few small rocks, but mostly open floor for the trees to spawn on flora_spawn_chance = 80 weighted_flora_spawn_list = list( @@ -80,7 +77,6 @@ weighted_mob_spawn_list = list(/mob/living/basic/deer/ice = 99, /mob/living/basic/tree = 1, /obj/effect/spawner/random/lavaland_mob/raptor = 15) /datum/map_generator/cave_generator/icemoon/surface/rocky - initial_closed_chance = 53 mob_spawn_chance = 0.5 /datum/map_generator/cave_generator/icemoon/surface/noruins //use this for when you don't want ruins to spawn in a certain area diff --git a/code/datums/mapgen/Cavegens/LavalandGenerator.dm b/code/datums/mapgen/Cavegens/LavalandGenerator.dm index 40c25b51c28..b40ea70beda 100644 --- a/code/datums/mapgen/Cavegens/LavalandGenerator.dm +++ b/code/datums/mapgen/Cavegens/LavalandGenerator.dm @@ -23,8 +23,7 @@ high_heat_threshold = 0.15 high_humidity_threshold = 0.15 biome_stamp_size = 60 - smoothing_iterations = 50 - + /datum/map_generator/cave_generator/lavaland/ruin_version biome_population = FALSE weighted_open_turf_types = list(/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins = 1) diff --git a/code/datums/ruins.dm b/code/datums/ruins.dm index 703991f596e..5741904e490 100644 --- a/code/datums/ruins.dm +++ b/code/datums/ruins.dm @@ -28,6 +28,10 @@ var/suffix = null ///What flavor or ruin is this? eg ZTRAIT_SPACE_RUINS var/ruin_type = null + ///is this ruin "enclosed" by walls. This is relevant for terrain gen with cellular automata to know whether this ruin will spawn inside of walls, or should spawn in the open. + var/enclosed_for_terrain = FALSE + ///Padding to be used to ensure extra space around the ruin for terrain gen purposes. If a ruin is NOT enclosed and this is set to 1; there will be at least one layer of open terrain around the ruin. If a ruin IS enclosed and this is set to 1; there will be at least one layer of wall terrain around the ruin. + var/terrain_padding = 0 /datum/map_template/ruin/New() if(!name && id) diff --git a/code/datums/ruins/icemoon.dm b/code/datums/ruins/icemoon.dm index 5e293a70747..35d1856d8ac 100644 --- a/code/datums/ruins/icemoon.dm +++ b/code/datums/ruins/icemoon.dm @@ -23,6 +23,7 @@ id = "lust" description = "Not exactly what you expected." suffix = "icemoon_surface_lust.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/icemoon/asteroid name = "Ice-Ruin Asteroid Site" @@ -103,6 +104,7 @@ suffix = "icemoon_surface_mining_site.dmm" always_place = TRUE always_spawn_with = list(/datum/map_template/ruin/icemoon/underground/mining_site_below = PLACE_BELOW) + enclosed_for_terrain = TRUE /datum/map_template/ruin/icemoon/underground/mining_site_below name = "Ice-Ruin Mining Site Underground" @@ -111,6 +113,7 @@ suffix = "icemoon_underground_mining_site.dmm" has_ceiling = FALSE unpickable = TRUE + enclosed_for_terrain = TRUE // below ground only @@ -124,18 +127,21 @@ id = "abandonedvillage" description = "Who knows what lies within?" suffix = "icemoon_underground_abandoned_village.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/icemoon/underground/library name = "Ice-Ruin Buried Library" id = "buriedlibrary" description = "A once grand library, now lost to the confines of the Ice Moon." suffix = "icemoon_underground_library.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/icemoon/underground/wrath name = "Ice-Ruin Ruin of Wrath" id = "wrath" description = "You'll fight and fight and just keep fighting." suffix = "icemoon_underground_wrath.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/icemoon/underground/hermit name = "Ice-Ruin Frozen Shack" @@ -148,6 +154,7 @@ id = "lavalandsite" description = "I guess we never really left you huh?" suffix = "icemoon_underground_lavaland.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/icemoon/underground/puzzle name = "Ice-Ruin Ancient Puzzle" @@ -180,6 +187,7 @@ id = "mailroom" description = "This is where all of your paychecks went. Signed, the management." suffix = "icemoon_underground_mailroom.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/icemoon/underground/biodome name = "Ice-Ruin Syndicate Bio-Dome" @@ -204,6 +212,7 @@ id = "syndie_lab" description = "A small laboratory and living space for Syndicate agents." suffix = "icemoon_underground_syndielab.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/icemoon/underground/o31 name = "Ice-Ruin Outpost 31" @@ -224,6 +233,7 @@ id = "hotsprings" description = "Just relax and take a dip, nothing will go wrong, I swear!" suffix = "icemoon_underground_hotsprings.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/icemoon/underground/vent name = "Ice-Ruin Icemoon Ore Vent" diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index cd3c1065ec4..206158c15d1 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -15,6 +15,7 @@ description = "Seemingly plucked from a tropical destination, this beach is calm and cool, with the salty waves roaring softly in the background. \ Comes with a rustic wooden bar and suicidal bartender." suffix = "lavaland_biodome_beach.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/biodome/winter name = "Lava-Ruin Biodome Winter" @@ -43,6 +44,7 @@ suffix = "lavaland_surface_cube.dmm" cost = 10 allow_duplicates = FALSE + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/seed_vault name = "Lava-Ruin Seed Vault" @@ -52,6 +54,7 @@ suffix = "lavaland_surface_seed_vault.dmm" cost = 10 allow_duplicates = FALSE + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/ash_walker name = "Lava-Ruin Ash Walker Nest" @@ -61,6 +64,7 @@ suffix = "lavaland_surface_ash_walker1.dmm" cost = 20 allow_duplicates = FALSE + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/syndicate_base name = "Lava-Ruin Syndicate Lava Base" @@ -87,6 +91,7 @@ cost = 5 suffix = "lavaland_surface_gaia.dmm" allow_duplicates = FALSE + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/sin cost = 10 @@ -124,6 +129,7 @@ suffix = "lavaland_surface_sloth.dmm" // Generates nothing but atmos runtimes and salt cost = 0 + terrain_padding = 2 /datum/map_template/ruin/lavaland/ratvar name = "Lava-Ruin Dead God" @@ -140,6 +146,7 @@ suffix = "lavaland_surface_hierophant.dmm" always_place = TRUE allow_duplicates = FALSE + terrain_padding = 2 /datum/map_template/ruin/lavaland/blood_drunk_miner name = "Lava-Ruin Blood-Drunk Miner" @@ -148,14 +155,17 @@ suffix = "lavaland_surface_blooddrunk1.dmm" cost = 0 allow_duplicates = FALSE //will only spawn one variant of the ruin + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/blood_drunk_miner/guidance name = "Lava-Ruin Blood-Drunk Miner (Guidance)" suffix = "lavaland_surface_blooddrunk2.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/blood_drunk_miner/hunter name = "Lava-Ruin Blood-Drunk Miner (Hunter)" suffix = "lavaland_surface_blooddrunk3.dmm" + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/blood_drunk_miner/random name = "Lava-Ruin Blood-Drunk Miner (Random)" @@ -172,6 +182,7 @@ description = "Turns out that keeping your abductees unconscious is really important. Who knew?" suffix = "lavaland_surface_ufo_crash.dmm" cost = 5 + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/xeno_nest name = "Lava-Ruin Xenomorph Nest" @@ -180,6 +191,7 @@ Quality memes." suffix = "lavaland_surface_xeno_nest.dmm" cost = 20 + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/fountain name = "Lava-Ruin Fountain Hall" @@ -227,6 +239,7 @@ suffix = "lavaland_surface_random_ripley.dmm" allow_duplicates = FALSE cost = 5 + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/dark_wizards name = "Lava-Ruin Dark Wizard Altar" @@ -234,6 +247,7 @@ description = "A ruin with dark wizards. What secret do they guard?" suffix = "lavaland_surface_wizard.dmm" cost = 5 + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/strong_stone name = "Lava-Ruin Strong Stone" @@ -266,6 +280,7 @@ suffix = "lavaland_surface_elephant_graveyard.dmm" allow_duplicates = FALSE cost = 10 + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/bileworm_nest name = "Lava-Ruin Bileworm Nest" @@ -274,6 +289,7 @@ cost = 5 suffix = "lavaland_surface_bileworm_nest.dmm" allow_duplicates = FALSE + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/lava_phonebooth name = "Lava-Ruin Phonebooth" @@ -323,6 +339,8 @@ description = "Not every shuttle makes it back to CentCom." suffix = "lavaland_surface_shuttle_wreckage.dmm" allow_duplicates = FALSE + enclosed_for_terrain = TRUE + /datum/map_template/ruin/lavaland/crashsite name = "Lava-Ruin Pod Crashsite" @@ -330,6 +348,7 @@ description = "They launched too early" suffix = "lavaland_surface_crashsite.dmm" allow_duplicates = FALSE + enclosed_for_terrain = TRUE /datum/map_template/ruin/lavaland/shoe_facotry name = "Lava-Ruin Shoe Factory" diff --git a/code/modules/mapping/ruins.dm b/code/modules/mapping/ruins.dm index 94d5dd6195c..c6ce163abf5 100644 --- a/code/modules/mapping/ruins.dm +++ b/code/modules/mapping/ruins.dm @@ -212,6 +212,9 @@ var/top_right_y = bottom_left_y + current_pick.height - 1 log_mapping("Successfully placed [current_pick.name] ruin ([bottom_left_x],[bottom_left_y],[placed_turf.z] to [top_right_x],[top_right_y],[placed_turf.z]).") + ///Keep track of the active ruins so we can take it in account for map generation. Using bottom lef turf as key + SSmapping.active_ruins[locate(bottom_left_x, bottom_left_y, placed_turf.z)] = current_pick + //Update the available list for(var/datum/map_template/ruin/R in ruins_available) if(R.cost > budget || R.mineral_cost > mineral_budget)