add biome as table & 'biome_parameters' variable

This commit is contained in:
MihailRis 2024-08-19 17:13:50 +03:00
parent 784712c06a
commit efa27496ab
5 changed files with 81 additions and 40 deletions

View File

@ -1,14 +1,19 @@
sea_level = 64 sea_level = 64
sea_layers = { -- 1 - temperature
{block="base:water", height=-1}, -- 2 - humidity
} biome_parameters = 2
layers = { biome = {
{block="base:grass_block", height=1, below_sea_level=false}, sea_layers = {
{block="base:dirt", height=5, below_sea_level=false}, {block="base:water", height=-1},
{block="base:stone", height=-1}, },
{block="base:bazalt", 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) local function _generate_heightmap(x, y, w, h, seed, s)

View File

@ -589,4 +589,32 @@ namespace lua {
} }
return def; 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;
}
} }

View File

@ -6,19 +6,23 @@
#include "lua/lua_custom_types.hpp" #include "lua/lua_custom_types.hpp"
#include "content/Content.hpp" #include "content/Content.hpp"
#include "voxels/Block.hpp" #include "voxels/Block.hpp"
#include "voxels/Chunk.hpp"
#include "world/generator/GeneratorDef.hpp" #include "world/generator/GeneratorDef.hpp"
class LuaGeneratorScript : public GeneratorScript { class LuaGeneratorScript : public GeneratorScript {
scriptenv env; scriptenv env;
Biome biome; Biome biome;
uint biomeParameters;
uint seaLevel; uint seaLevel;
public: public:
LuaGeneratorScript( LuaGeneratorScript(
scriptenv env, scriptenv env,
Biome biome, Biome biome,
uint biomeParameters,
uint seaLevel) uint seaLevel)
: env(std::move(env)), : env(std::move(env)),
biome(std::move(biome)), biome(std::move(biome)),
biomeParameters(biomeParameters),
seaLevel(seaLevel) seaLevel(seaLevel)
{} {}
@ -54,6 +58,10 @@ public:
return biome; return biome;
} }
uint getBiomeParameters() const override {
return biomeParameters;
}
uint getSeaLevel() const override { uint getSeaLevel() const override {
return seaLevel; return seaLevel;
} }
@ -62,17 +70,9 @@ public:
static BlocksLayer load_layer( static BlocksLayer load_layer(
lua::State* L, int idx, uint& lastLayersHeight, bool& hasResizeableLayer lua::State* L, int idx, uint& lastLayersHeight, bool& hasResizeableLayer
) { ) {
lua::requirefield(L, "block"); auto name = lua::require_string_field(L, "block");
auto name = lua::require_string(L, -1); int height = lua::require_integer_field(L, "height");
lua::pop(L); bool belowSeaLevel = lua::get_boolean_field(L, "below_sea_level", true);
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);
}
if (hasResizeableLayer) { if (hasResizeableLayer) {
lastLayersHeight += height; lastLayersHeight += height;
@ -111,6 +111,22 @@ static inline BlocksLayers load_layers(
return BlocksLayers {std::move(layers), lastLayersHeight}; 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<GeneratorScript> scripting::load_generator( std::unique_ptr<GeneratorScript> scripting::load_generator(
const fs::path& file const fs::path& file
) { ) {
@ -122,28 +138,16 @@ std::unique_ptr<GeneratorScript> scripting::load_generator(
lua::pushenv(L, *env); lua::pushenv(L, *env);
uint seaLevel = 0; uint biomeParameters = lua::get_integer_field(L, "biome_parameters", 0, 0, 16);
if (lua::getfield(L, "sea_level")) { uint seaLevel = lua::get_integer_field(L, "sea_level", 0, 0, CHUNK_H);
seaLevel = lua::tointeger(L, -1); lua::requirefield(L, "biome");
lua::pop(L); 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); lua::pop(L);
return std::make_unique<LuaGeneratorScript>( return std::make_unique<LuaGeneratorScript>(
std::move(env), std::move(env),
Biome {"default", std::move(groundLayers), std::move(seaLayers)}, std::move(biome),
biomeParameters,
seaLevel); seaLevel);
} }

View File

@ -17,7 +17,7 @@ struct BlocksLayer {
/// @brief Layer can present under the sea level (default: true) else will /// @brief Layer can present under the sea level (default: true) else will
/// extend the next layer /// extend the next layer
bool below_sea_level; bool belowSeaLevel;
struct { struct {
/// @brief Layer block index /// @brief Layer block index
@ -54,6 +54,10 @@ public:
virtual const Biome& getBiome() const = 0; 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; virtual uint getSeaLevel() const = 0;
/// @brief Build the runtime cache /// @brief Build the runtime cache

View File

@ -26,7 +26,7 @@ static inline void generate_pole(
uint layerExtension = 0; uint layerExtension = 0;
for (const auto& layer : layers.layers) { for (const auto& layer : layers.layers) {
// skip layer if can't be generated under sea level // 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); layerExtension = std::max(0, layer.height);
continue; continue;
} }