diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 7204712058b..d45e5682a63 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -108,3 +108,19 @@ require only minor tweaks. #define PLACE_LAVA_RUIN "lavaland" //On lavaland ruin z levels(s) #define PLACE_BELOW "below" //On z levl below - centered on same tile #define PLACE_ISOLATED "isolated" //On isolated ruin z level + + +///Map generation defines +#define PERLIN_LAYER_HEIGHT "perlin_height" +#define PERLIN_LAYER_HUMIDITY "perlin_humidity" +#define PERLIN_LAYER_HEAT "perlin_heat" + +#define BIOME_LOW_HEAT "low_heat" +#define BIOME_LOWMEDIUM_HEAT "lowmedium_heat" +#define BIOME_HIGHMEDIUM_HEAT "highmedium_heat" +#define BIOME_HIGH_HEAT "high_heat" + +#define BIOME_LOW_HUMIDITY "low_humidity" +#define BIOME_LOWMEDIUM_HUMIDITY "lowmedium_humidity" +#define BIOME_HIGHMEDIUM_HUMIDITY "highmedium_humidity" +#define BIOME_HIGH_HUMIDITY "high_humidity" diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 18f9de9a6d1..28ef539fb01 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -34,6 +34,9 @@ SUBSYSTEM_DEF(mapping) var/list/reservation_ready = list() var/clearing_reserved_turfs = FALSE + ///All possible biomes in assoc list as type || instance + var/list/biomes = list() + // Z-manager stuff var/station_start // should only be used for maploading-related tasks var/space_levels_so_far = 0 @@ -61,6 +64,7 @@ SUBSYSTEM_DEF(mapping) if(!config || config.defaulted) to_chat(world, "Unable to load next or default map config, defaulting to Meta Station") config = old_config + initialize_biomes() loadWorld() repopulate_sorted_areas() process_teleport_locs() //Sets up the wizard teleport locations @@ -551,7 +555,11 @@ GLOBAL_LIST_EMPTY(the_station_areas) used_turfs.Cut() reserve_turfs(clearing) - +///Initialize all biomes, assoc as type || instance +/datum/controller/subsystem/mapping/proc/initialize_biomes() + for(var/biome_path in subtypesof(/datum/biome)) + var/datum/biome/biome_instance = new biome_path() + biomes[biome_path] += biome_instance /datum/controller/subsystem/mapping/proc/reg_in_areas_in_z(list/areas) for(var/B in areas) diff --git a/code/datums/mapgen/JungleGenerator.dm b/code/datums/mapgen/JungleGenerator.dm new file mode 100644 index 00000000000..25348640ef7 --- /dev/null +++ b/code/datums/mapgen/JungleGenerator.dm @@ -0,0 +1,91 @@ +//the random offset applied to square coordinates, causes intermingling at biome borders +#define BIOME_RANDOM_SQUARE_DRIFT 2 + +/datum/map_generator/jungle_generator + ///2D list of all biomes based on heat and humidity combos. + var/list/possible_biomes = list( + BIOME_LOW_HEAT = list( + BIOME_LOW_HUMIDITY = /datum/biome/plains, + BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/mudlands, + BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/mudlands, + BIOME_HIGH_HUMIDITY = /datum/biome/water + ), + BIOME_LOWMEDIUM_HEAT = list( + BIOME_LOW_HUMIDITY = /datum/biome/plains, + BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/jungle, + BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/jungle, + BIOME_HIGH_HUMIDITY = /datum/biome/mudlands + ), + BIOME_HIGHMEDIUM_HEAT = list( + BIOME_LOW_HUMIDITY = /datum/biome/plains, + BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/plains, + BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/jungle/deep, + BIOME_HIGH_HUMIDITY = /datum/biome/jungle + ), + BIOME_HIGH_HEAT = list( + BIOME_LOW_HUMIDITY = /datum/biome/wasteland, + BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/plains, + BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/jungle, + BIOME_HIGH_HUMIDITY = /datum/biome/jungle/deep + ) + ) + ///Used to select "zoom" level into the perlin noise, higher numbers result in slower transitions + var/perlin_zoom = 65 + +///Seeds the rust-g perlin noise with a random number. +/datum/map_generator/jungle_generator/generate_terrain(var/list/turfs) + . = ..() + var/height_seed = rand(0, 50000) + var/humidity_seed = rand(0, 50000) + var/heat_seed = rand(0, 50000) + + for(var/t in turfs) //Go through all the turfs and generate them + var/turf/gen_turf = t + var/drift_x = (gen_turf.x + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)) / perlin_zoom + var/drift_y = (gen_turf.y + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)) / perlin_zoom + + var/height = text2num(rustg_noise_get_at_coordinates("[height_seed]", "[drift_x]", "[drift_y]")) + + + var/datum/biome/selected_biome + if(height <= 0.85) //If height is less than 0.85, we generate biomes based on the heat and humidity of the area. + var/humidity = text2num(rustg_noise_get_at_coordinates("[humidity_seed]", "[drift_x]", "[drift_y]")) + var/heat = text2num(rustg_noise_get_at_coordinates("[heat_seed]", "[drift_x]", "[drift_y]")) + var/heat_level //Type of heat zone we're in LOW-MEDIUM-HIGH + var/humidity_level //Type of humidity zone we're in LOW-MEDIUM-HIGH + + switch(heat) + if(0 to 0.25) + heat_level = BIOME_LOW_HEAT + if(0.25 to 0.5) + heat_level = BIOME_LOWMEDIUM_HEAT + if(0.5 to 0.75) + heat_level = BIOME_HIGHMEDIUM_HEAT + if(0.75 to 1) + heat_level = BIOME_HIGH_HEAT + switch(humidity) + if(0 to 0.25) + humidity_level = BIOME_LOW_HUMIDITY + if(0.25 to 0.5) + humidity_level = BIOME_LOWMEDIUM_HUMIDITY + if(0.5 to 0.75) + humidity_level = BIOME_HIGHMEDIUM_HUMIDITY + if(0.75 to 1) + humidity_level = BIOME_HIGH_HUMIDITY + selected_biome = possible_biomes[heat_level][humidity_level] + else //Over 0.85; It's a mountain + selected_biome = /datum/biome/mountain + selected_biome = SSmapping.biomes[selected_biome] //Get the instance of this biome from SSmapping + selected_biome.generate_turf(gen_turf) + CHECK_TICK + +/turf/open/genturf + name = "ungenerated turf" + desc = "If you see this, and you're not a ghost, yell at coders" + icon = 'icons/turf/debug.dmi' + icon_state = "genturf" + +/area/mine/planetgeneration + name = "planet generation area" + dynamic_lighting = DYNAMIC_LIGHTING_DISABLED + map_generator = /datum/map_generator/jungle_generator diff --git a/code/datums/mapgen/_MapGenerator.dm b/code/datums/mapgen/_MapGenerator.dm new file mode 100644 index 00000000000..aa4406bf789 --- /dev/null +++ b/code/datums/mapgen/_MapGenerator.dm @@ -0,0 +1,6 @@ +///This type is responsible for any map generation behavior that is done in areas, override this to allow for area-specific map generation. This generation is ran by areas in initialize. +/datum/map_generator + +///This proc will be ran by areas on Initialize, and provides the areas turfs as argument to allow for generation. +/datum/map_generator/proc/generate_terrain(var/list/turfs) + return diff --git a/code/datums/mapgen/biomes/_biome.dm b/code/datums/mapgen/biomes/_biome.dm new file mode 100644 index 00000000000..bf0f02cfbaa --- /dev/null +++ b/code/datums/mapgen/biomes/_biome.dm @@ -0,0 +1,50 @@ +///This datum handles the transitioning from a turf to a specific biome, and handles spawning decorative structures and mobs. +/datum/biome + ///Type of turf this biome creates + var/turf_type + ///Chance of having a structure from the flora types list spawn + var/flora_density = 0 + ///Chance of having a mob from the fauna types list spawn + var/fauna_density = 0 + ///list of type paths of objects that can be spawned when the turf spawns flora + var/list/flora_types = list(/obj/structure/flora/grass/jungle) + ///list of type paths of mobs that can be spawned when the turf spawns fauna + var/list/fauna_types = list() + +///This proc handles the creation of a turf of a specific biome type +/datum/biome/proc/generate_turf(var/turf/gen_turf) + gen_turf.ChangeTurf(turf_type, null, CHANGETURF_DEFER_CHANGE) + if(length(fauna_types) && prob(fauna_density)) + var/mob/fauna = pick(fauna_types) + new fauna(gen_turf) + + if(length(flora_types) && prob(flora_density)) + var/obj/structure/flora = pick(flora_types) + new flora(gen_turf) + +/datum/biome/mudlands + turf_type = /turf/open/floor/plating/dirt/jungle/dark + flora_types = list(/obj/structure/flora/grass/jungle,/obj/structure/flora/grass/jungle/b, /obj/structure/flora/rock/jungle, /obj/structure/flora/rock/pile/largejungle) + flora_density = 3 + +/datum/biome/plains + turf_type = /turf/open/floor/plating/grass/jungle + flora_types = list(/obj/structure/flora/grass/jungle,/obj/structure/flora/grass/jungle/b, /obj/structure/flora/tree/jungle, /obj/structure/flora/rock/jungle, /obj/structure/flora/junglebush, /obj/structure/flora/junglebush/b, /obj/structure/flora/junglebush/c, /obj/structure/flora/junglebush/large, /obj/structure/flora/rock/pile/largejungle) + flora_density = 15 + +/datum/biome/jungle + turf_type = /turf/open/floor/plating/grass/jungle + flora_types = list(/obj/structure/flora/grass/jungle,/obj/structure/flora/grass/jungle/b, /obj/structure/flora/tree/jungle, /obj/structure/flora/rock/jungle, /obj/structure/flora/junglebush, /obj/structure/flora/junglebush/b, /obj/structure/flora/junglebush/c, /obj/structure/flora/junglebush/large, /obj/structure/flora/rock/pile/largejungle) + flora_density = 40 + +/datum/biome/jungle/deep + flora_density = 65 + +/datum/biome/wasteland + turf_type = /turf/open/floor/plating/dirt/jungle/wasteland + +/datum/biome/water + turf_type = /turf/open/water/jungle + +/datum/biome/mountain + turf_type = /turf/closed/mineral/random/jungle diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 91da87f1a24..d3fe5b6b218 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -67,6 +67,9 @@ /// Wire assignment for airlocks in this area var/airlock_wires = /datum/wires/airlock + + ///This datum, if set, allows terrain generation behavior to be ran on Initialize() + var/datum/map_generator/map_generator /** @@ -157,6 +160,9 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/LateInitialize() power_change() // all machines set to current power level, also updates icon update_beauty() + if(map_generator) + map_generator = new map_generator() + map_generator.generate_terrain(get_area_turfs(src)) /** * Register this area as belonging to a z level diff --git a/code/game/turfs/open/floor/plating/dirt.dm b/code/game/turfs/open/floor/plating/dirt.dm deleted file mode 100644 index 9cfbe8433b3..00000000000 --- a/code/game/turfs/open/floor/plating/dirt.dm +++ /dev/null @@ -1,21 +0,0 @@ -/turf/open/floor/plating/dirt - gender = PLURAL - name = "dirt" - desc = "Upon closer examination, it's still dirt." - icon = 'icons/turf/floors.dmi' - icon_state = "dirt" - baseturfs = /turf/open/chasm/jungle - initial_gas_mix = OPENTURF_LOW_PRESSURE - planetary_atmos = TRUE - attachment_holes = FALSE - footstep = FOOTSTEP_SAND - barefootstep = FOOTSTEP_SAND - clawfootstep = FOOTSTEP_SAND - heavyfootstep = FOOTSTEP_GENERIC_HEAVY - tiled_dirt = FALSE - -/turf/open/floor/plating/dirt/dark - icon_state = "greenerdirt" - -/turf/open/floor/plating/dirt/try_replace_tile(obj/item/stack/tile/T, mob/user, params) - return diff --git a/code/game/turfs/open/floor/plating/planet.dm b/code/game/turfs/open/floor/plating/planet.dm new file mode 100644 index 00000000000..9f6c54a029f --- /dev/null +++ b/code/game/turfs/open/floor/plating/planet.dm @@ -0,0 +1,59 @@ +/turf/open/floor/plating/dirt + gender = PLURAL + name = "dirt" + desc = "Upon closer examination, it's still dirt." + icon = 'icons/turf/floors.dmi' + icon_state = "dirt" + baseturfs = /turf/open/chasm/jungle + initial_gas_mix = OPENTURF_LOW_PRESSURE + planetary_atmos = TRUE + attachment_holes = FALSE + footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + tiled_dirt = FALSE + +/turf/open/floor/plating/dirt/dark + icon_state = "greenerdirt" + +/turf/open/floor/plating/dirt/try_replace_tile(obj/item/stack/tile/T, mob/user, params) + return + +/turf/open/floor/plating/dirt/jungle + slowdown = 0.5 + initial_gas_mix = OPENTURF_DEFAULT_ATMOS + +/turf/open/floor/plating/dirt/jungle/dark + icon_state = "greenerdirt" + +/turf/open/floor/plating/dirt/jungle/wasteland //Like a more fun version of living in Arizona. + name = "cracked earth" + desc = "Looks a bit dry." + icon = 'icons/turf/floors.dmi' + icon_state = "wasteland" + slowdown = 1 + var/floor_variance = 15 + +/turf/open/floor/plating/dirt/jungle/wasteland/Initialize() + .=..() + if(prob(floor_variance)) + icon_state = "[initial(icon_state)][rand(0,12)]" + +/turf/open/floor/plating/grass/jungle + name = "jungle grass" + initial_gas_mix = OPENTURF_DEFAULT_ATMOS + planetary_atmos = TRUE + desc = "Greener on the other side." + icon = 'icons/turf/floors.dmi' + icon_state = "junglegrass" + +/turf/open/floor/plating/grass/jungle/Initialize() + .=..() + icon_state = "[initial(icon_state)][rand(1,3)]" + +/turf/closed/mineral/random/jungle + mineralSpawnChanceList = list(/obj/item/stack/ore/uranium = 5, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 10, + /obj/item/stack/ore/silver = 12, /obj/item/stack/ore/plasma = 20, /obj/item/stack/ore/iron = 40, /obj/item/stack/ore/titanium = 11, + /obj/item/stack/ore/bluespace_crystal = 1) + baseturfs = /turf/open/floor/plating/dirt/dark diff --git a/code/game/turfs/open/water.dm b/code/game/turfs/open/water.dm index 957fb3df19b..b29cb95c11d 100644 --- a/code/game/turfs/open/water.dm +++ b/code/game/turfs/open/water.dm @@ -15,3 +15,6 @@ barefootstep = FOOTSTEP_WATER clawfootstep = FOOTSTEP_WATER heavyfootstep = FOOTSTEP_WATER + +/turf/open/water/jungle + initial_gas_mix = OPENTURF_DEFAULT_ATMOS diff --git a/icons/turf/debug.dmi b/icons/turf/debug.dmi new file mode 100644 index 00000000000..e419b2bf46d Binary files /dev/null and b/icons/turf/debug.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index f74f8f6e64f..8e16539f601 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/tgstation.dme b/tgstation.dme index a243b83d3a5..e4167adc208 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -604,6 +604,9 @@ #include "code\datums\looping_sounds\item_sounds.dm" #include "code\datums\looping_sounds\machinery_sounds.dm" #include "code\datums\looping_sounds\weather.dm" +#include "code\datums\mapgen\_MapGenerator.dm" +#include "code\datums\mapgen\JungleGenerator.dm" +#include "code\datums\mapgen\biomes\_biome.dm" #include "code\datums\martial\_martial.dm" #include "code\datums\martial\boxing.dm" #include "code\datums\martial\cqc.dm" @@ -1331,8 +1334,8 @@ #include "code\game\turfs\open\floor\plating.dm" #include "code\game\turfs\open\floor\reinf_floor.dm" #include "code\game\turfs\open\floor\plating\asteroid.dm" -#include "code\game\turfs\open\floor\plating\dirt.dm" #include "code\game\turfs\open\floor\plating\misc_plating.dm" +#include "code\game\turfs\open\floor\plating\planet.dm" #include "code\game\turfs\open\space\space.dm" #include "code\game\turfs\open\space\transit.dm" #include "code\modules\actionspeed\_actionspeed_modifier.dm"