From efa27496abdbd21bf9837f518444cf783e1133dd Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 19 Aug 2024 17:13:50 +0300 Subject: [PATCH] add biome as table & 'biome_parameters' variable --- res/generators/default.lua | 21 +++--- src/logic/scripting/lua/lua_util.hpp | 28 ++++++++ .../scripting/scripting_world_generation.cpp | 64 ++++++++++--------- src/world/generator/GeneratorDef.hpp | 6 +- src/world/generator/WorldGenerator.cpp | 2 +- 5 files changed, 81 insertions(+), 40 deletions(-) diff --git a/res/generators/default.lua b/res/generators/default.lua index 05df5ce9..010489a0 100644 --- a/res/generators/default.lua +++ b/res/generators/default.lua @@ -1,14 +1,19 @@ sea_level = 64 -sea_layers = { - {block="base:water", height=-1}, -} +-- 1 - temperature +-- 2 - humidity +biome_parameters = 2 -layers = { - {block="base:grass_block", height=1, below_sea_level=false}, - {block="base:dirt", height=5, below_sea_level=false}, - {block="base:stone", height=-1}, - {block="base:bazalt", height=1}, +biome = { + sea_layers = { + {block="base:water", height=-1}, + }, + layers = { + {block="base:grass_block", height=1, below_sea_level=false}, + {block="base:dirt", height=5, below_sea_level=false}, + {block="base:stone", height=-1}, + {block="base:bazalt", height=1}, + } } local function _generate_heightmap(x, y, w, h, seed, s) diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index d957e7be..a02fdd03 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -589,4 +589,32 @@ namespace lua { } return def; } + + inline Integer get_integer_field( + lua::State* L, const std::string& name, Integer def, int idx=-1 + ) { + if (getfield(L, name, idx)) { + auto value = tointeger(L, -1); + pop(L); + return value; + } + return def; + } + + inline Integer get_integer_field( + lua::State* L, const std::string& name, + Integer def, Integer min, Integer max, int idx=-1 + ) { + if (getfield(L, name, idx)) { + auto value = tointeger(L, -1); + if (value < min || value > max) { + throw std::runtime_error( + "value is out of range [" + +std::to_string(min)+", "+std::to_string(max)+"]"); + } + pop(L); + return value; + } + return def; + } } diff --git a/src/logic/scripting/scripting_world_generation.cpp b/src/logic/scripting/scripting_world_generation.cpp index a1abee83..9a2535bb 100644 --- a/src/logic/scripting/scripting_world_generation.cpp +++ b/src/logic/scripting/scripting_world_generation.cpp @@ -6,19 +6,23 @@ #include "lua/lua_custom_types.hpp" #include "content/Content.hpp" #include "voxels/Block.hpp" +#include "voxels/Chunk.hpp" #include "world/generator/GeneratorDef.hpp" class LuaGeneratorScript : public GeneratorScript { scriptenv env; Biome biome; + uint biomeParameters; uint seaLevel; public: LuaGeneratorScript( scriptenv env, Biome biome, + uint biomeParameters, uint seaLevel) : env(std::move(env)), biome(std::move(biome)), + biomeParameters(biomeParameters), seaLevel(seaLevel) {} @@ -54,6 +58,10 @@ public: return biome; } + uint getBiomeParameters() const override { + return biomeParameters; + } + uint getSeaLevel() const override { return seaLevel; } @@ -62,17 +70,9 @@ public: static BlocksLayer load_layer( lua::State* L, int idx, uint& lastLayersHeight, bool& hasResizeableLayer ) { - lua::requirefield(L, "block"); - auto name = lua::require_string(L, -1); - lua::pop(L); - lua::requirefield(L, "height"); - int height = lua::tointeger(L, -1); - lua::pop(L); - bool belowSeaLevel = true; - if (lua::getfield(L, "below_sea_level")) { - belowSeaLevel = lua::toboolean(L, -1); - lua::pop(L); - } + auto name = lua::require_string_field(L, "block"); + int height = lua::require_integer_field(L, "height"); + bool belowSeaLevel = lua::get_boolean_field(L, "below_sea_level", true); if (hasResizeableLayer) { lastLayersHeight += height; @@ -111,6 +111,22 @@ static inline BlocksLayers load_layers( return BlocksLayers {std::move(layers), lastLayersHeight}; } +static inline Biome load_biome( + lua::State* L, const std::string& name, int idx +) { + lua::pushvalue(L, idx); + BlocksLayers groundLayers; + BlocksLayers seaLayers; + try { + groundLayers = load_layers(L, "layers"); + seaLayers = load_layers(L, "sea_layers"); + } catch (const std::runtime_error& err) { + throw std::runtime_error("biome "+name+": "+err.what()); + } + lua::pop(L); + return Biome {name, std::move(groundLayers), std::move(seaLayers)}; +} + std::unique_ptr scripting::load_generator( const fs::path& file ) { @@ -122,28 +138,16 @@ std::unique_ptr scripting::load_generator( lua::pushenv(L, *env); - uint seaLevel = 0; - if (lua::getfield(L, "sea_level")) { - seaLevel = lua::tointeger(L, -1); - lua::pop(L); - } + uint biomeParameters = lua::get_integer_field(L, "biome_parameters", 0, 0, 16); + uint seaLevel = lua::get_integer_field(L, "sea_level", 0, 0, CHUNK_H); + lua::requirefield(L, "biome"); + Biome biome = load_biome(L, "default", -1); + lua::pop(L); - uint lastGroundLayersHeight = 0; - uint lastSeaLayersHeight = 0; - bool hasResizeableGroundLayer = false; - bool hasResizeableSeaLayer = false; - - BlocksLayers groundLayers; - BlocksLayers seaLayers; - try { - groundLayers = load_layers(L, "layers"); - seaLayers = load_layers(L, "sea_layers"); - } catch (const std::runtime_error& err) { - throw std::runtime_error(file.u8string()+": "+err.what()); - } lua::pop(L); return std::make_unique( std::move(env), - Biome {"default", std::move(groundLayers), std::move(seaLayers)}, + std::move(biome), + biomeParameters, seaLevel); } diff --git a/src/world/generator/GeneratorDef.hpp b/src/world/generator/GeneratorDef.hpp index 356d876d..79c537ed 100644 --- a/src/world/generator/GeneratorDef.hpp +++ b/src/world/generator/GeneratorDef.hpp @@ -17,7 +17,7 @@ struct BlocksLayer { /// @brief Layer can present under the sea level (default: true) else will /// extend the next layer - bool below_sea_level; + bool belowSeaLevel; struct { /// @brief Layer block index @@ -54,6 +54,10 @@ public: virtual const Biome& getBiome() const = 0; + /// @return Number of biome parameters, that biome choosing depending on + virtual uint getBiomeParameters() const = 0; + + /// @return Sea level (top of seaLayers) virtual uint getSeaLevel() const = 0; /// @brief Build the runtime cache diff --git a/src/world/generator/WorldGenerator.cpp b/src/world/generator/WorldGenerator.cpp index c506dc9a..3773b6f9 100644 --- a/src/world/generator/WorldGenerator.cpp +++ b/src/world/generator/WorldGenerator.cpp @@ -26,7 +26,7 @@ static inline void generate_pole( uint layerExtension = 0; for (const auto& layer : layers.layers) { // skip layer if can't be generated under sea level - if (y < seaLevel && !layer.below_sea_level) { + if (y < seaLevel && !layer.belowSeaLevel) { layerExtension = std::max(0, layer.height); continue; }