From 510c45ffe94dc219b26ae91aa15c5b68bec822b1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 17 Aug 2024 19:06:14 +0300 Subject: [PATCH] add sea_level variable --- res/generators/default.lua | 2 + src/logic/scripting/scripting.cpp | 99 +++++++++++++++++--------- src/world/generator/GeneratorDef.hpp | 2 + src/world/generator/WorldGenerator.cpp | 4 +- 4 files changed, 70 insertions(+), 37 deletions(-) diff --git a/res/generators/default.lua b/res/generators/default.lua index c35470a9..a28b2e33 100644 --- a/res/generators/default.lua +++ b/res/generators/default.lua @@ -1,3 +1,5 @@ +sea_level = 64 + layers = { {block="base:grass_block", height=1, below_sea_level=false}, {block="base:dirt", height=5, below_sea_level=false}, diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index dd497b90..8705fb50 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -630,12 +630,13 @@ int scripting::get_values_on_stack() { return lua::gettop(lua::get_main_thread()); } -static void load_script( +[[nodiscard]] +static int load_script( int env, const std::string& type, const fs::path& file ) { std::string src = files::read_string(file); logger.info() << "script (" << type << ") " << file.u8string(); - lua::execute(lua::get_main_thread(), env, src, file.u8string()); + return lua::execute(lua::get_main_thread(), env, src, file.u8string()); } void scripting::load_block_script( @@ -645,7 +646,7 @@ void scripting::load_block_script( block_funcs_set& funcsset ) { int env = *senv; - load_script(env, "block", file); + lua::pop(lua::get_main_thread(), load_script(env, "block", file)); funcsset.init = register_event(env, "init", prefix + ".init"); funcsset.update = register_event(env, "on_update", prefix + ".update"); funcsset.randupdate = @@ -665,7 +666,7 @@ void scripting::load_item_script( item_funcs_set& funcsset ) { int env = *senv; - load_script(env, "item", file); + lua::pop(lua::get_main_thread(), load_script(env, "item", file)); funcsset.init = register_event(env, "init", prefix + ".init"); funcsset.on_use = register_event(env, "on_use", prefix + ".use"); funcsset.on_use_on_block = @@ -688,9 +689,18 @@ class LuaGeneratorScript : public GeneratorScript { scriptenv env; std::vector layers; uint lastLayersHeight; + uint seaLevel; public: - LuaGeneratorScript(scriptenv env, std::vector layers, uint lastLayersHeight) - : env(std::move(env)), layers(std::move(layers)), lastLayersHeight(lastLayersHeight) {} + LuaGeneratorScript( + scriptenv env, + std::vector layers, + uint lastLayersHeight, + uint seaLevel) + : env(std::move(env)), + layers(std::move(layers)), + lastLayersHeight(lastLayersHeight), + seaLevel(seaLevel) + {} std::shared_ptr generateHeightmap( const glm::ivec2& offset, const glm::ivec2& size @@ -723,17 +733,55 @@ public: uint getLastLayersHeight() const override { return lastLayersHeight; } + + uint getSeaLevel() const override { + return seaLevel; + } }; +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); + } + + if (hasResizeableLayer) { + lastLayersHeight += height; + } + if (height == -1) { + if (hasResizeableLayer) { + throw std::runtime_error("only one resizeable layer allowed"); + } + hasResizeableLayer = true; + } + return BlocksLayer {name, height, belowSeaLevel, {}}; +} + std::unique_ptr scripting::load_generator( const fs::path& file ) { auto env = create_environment(); - load_script(*env, "generator", file); - auto L = lua::get_main_thread(); + + lua::pop(L, load_script(*env, "generator", file)); + lua::pushenv(L, *env); + uint seaLevel = 0; + if (lua::getfield(L, "sea_level")) { + seaLevel = lua::tointeger(L, -1); + lua::pop(L); + } + uint lastLayersHeight = 0; bool hasResizeableLayer = false; @@ -741,41 +789,22 @@ std::unique_ptr scripting::load_generator( if (lua::getfield(L, "layers")) { int len = lua::objlen(L, -1); for (int i = 1; i <= len; i++) { + lua::rawgeti(L, i); try { - lua::rawgeti(L, i); - 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 below_sea_level = true; - if (lua::getfield(L, "below_sea_level")) { - below_sea_level = lua::toboolean(L, -1); - lua::pop(L); - } - lua::pop(L); - - if (hasResizeableLayer) { - lastLayersHeight += height; - } - if (height == -1) { - if (hasResizeableLayer) { - throw std::runtime_error("only one resizeable layer allowed"); - } - hasResizeableLayer = true; - } - layers.push_back(BlocksLayer {name, height, below_sea_level, {}}); + layers.push_back( + load_layer(L, -1, lastLayersHeight, hasResizeableLayer)); } catch (const std::runtime_error& err) { lua::pop(L, 2); throw std::runtime_error( "layer #"+std::to_string(i)+": "+err.what()); } + lua::pop(L); } lua::pop(L); } lua::pop(L); - return std::make_unique(std::move(env), std::move(layers), lastLayersHeight); + return std::make_unique( + std::move(env), std::move(layers), lastLayersHeight, seaLevel); } void scripting::load_world_script( @@ -785,7 +814,7 @@ void scripting::load_world_script( world_funcs_set& funcsset ) { int env = *senv; - load_script(env, "world", file); + lua::pop(lua::get_main_thread(), load_script(env, "world", file)); register_event(env, "init", prefix + ".init"); register_event(env, "on_world_open", prefix + ".worldopen"); register_event(env, "on_world_tick", prefix + ".worldtick"); @@ -804,7 +833,7 @@ void scripting::load_layout_script( uidocscript& script ) { int env = *senv; - load_script(env, "layout", file); + lua::pop(lua::get_main_thread(), load_script(env, "layout", file)); script.onopen = register_event(env, "on_open", prefix + ".open"); script.onprogress = register_event(env, "on_progress", prefix + ".progress"); diff --git a/src/world/generator/GeneratorDef.hpp b/src/world/generator/GeneratorDef.hpp index 263f8b4f..4b90997d 100644 --- a/src/world/generator/GeneratorDef.hpp +++ b/src/world/generator/GeneratorDef.hpp @@ -30,6 +30,8 @@ public: /// @brief Total height of all layers after resizeable one virtual uint getLastLayersHeight() const = 0; + virtual uint getSeaLevel() const = 0; + virtual void prepare(const Content* content) = 0; }; diff --git a/src/world/generator/WorldGenerator.cpp b/src/world/generator/WorldGenerator.cpp index eb88c0f0..6c72aac0 100644 --- a/src/world/generator/WorldGenerator.cpp +++ b/src/world/generator/WorldGenerator.cpp @@ -20,17 +20,17 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ, int seed) { auto heightmap = def.script->generateHeightmap( {chunkX*CHUNK_W, chunkZ*CHUNK_D}, {CHUNK_W, CHUNK_D} ); - uint seaLevel = 64; auto values = heightmap->getValues(); const auto& layers = def.script->getLayers(); uint lastLayersHeight = def.script->getLastLayersHeight(); + uint seaLevel = def.script->getSeaLevel(); auto baseWater = content->blocks.require("base:water").rt.id; std::memset(voxels, 0, sizeof(voxel) * CHUNK_VOL); for (uint z = 0; z < CHUNK_D; z++) { for (uint x = 0; x < CHUNK_W; x++) { - int height = values[z * CHUNK_W + x] * 255 + 10; + int height = values[z * CHUNK_W + x] * CHUNK_H; for (uint y = height+1; y <= seaLevel; y++) { voxels[vox_index(x, y, z)].id = baseWater; }