From ae5671364af3c2dd5fea94ac06b07a905bd6e8da Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 14 Aug 2024 18:44:32 +0300 Subject: [PATCH] add heightmap-based test generation --- res/generators/default.lua | 15 ++ res/generators/flat.lua | 30 --- src/content/Content.hpp | 4 + src/engine.cpp | 9 - src/logic/ChunksController.cpp | 9 +- src/logic/scripting/lua/libcore.cpp | 12 +- src/logic/scripting/lua/lua_custom_types.hpp | 2 +- .../scripting/lua/lua_type_heightmap.cpp | 8 +- src/logic/scripting/scripting.cpp | 5 +- src/voxels/DefaultWorldGenerator.cpp | 241 ------------------ src/voxels/DefaultWorldGenerator.hpp | 15 -- src/voxels/FlatWorldGenerator.cpp | 28 -- src/voxels/FlatWorldGenerator.hpp | 15 -- src/voxels/WorldGenerator.cpp | 39 ++- src/voxels/WorldGenerator.hpp | 23 +- src/world/World.cpp | 5 +- src/world/WorldGenerators.cpp | 29 --- src/world/WorldGenerators.hpp | 33 --- 18 files changed, 82 insertions(+), 440 deletions(-) create mode 100644 res/generators/default.lua delete mode 100644 res/generators/flat.lua delete mode 100644 src/voxels/DefaultWorldGenerator.cpp delete mode 100644 src/voxels/DefaultWorldGenerator.hpp delete mode 100644 src/voxels/FlatWorldGenerator.cpp delete mode 100644 src/voxels/FlatWorldGenerator.hpp delete mode 100644 src/world/WorldGenerators.cpp delete mode 100644 src/world/WorldGenerators.hpp diff --git a/res/generators/default.lua b/res/generators/default.lua new file mode 100644 index 00000000..564339b0 --- /dev/null +++ b/res/generators/default.lua @@ -0,0 +1,15 @@ +function generate_heightmap(x, y, w, h) + local umap = Heightmap(w, h) + local vmap = Heightmap(w, h) + umap:noise({x+521, y+73}, 0.05, 1, 20.8) + umap:noise({x+51, y+75}, 0.05, 1, 21.8) + vmap:noise({x+521, y+70}, 0.1, 3, 35.8) + vmap:noise({x+95, y+246}, 0.15, 3, 35.8) + + local map = Heightmap(w, h) + map:noise({x, y}, 0.02, 6, 0.2) + map:noise({x, y}, 0.06, 7, 0.5, umap, vmap) + map:mul(0.3) + map:add(0.3) + return map +end diff --git a/res/generators/flat.lua b/res/generators/flat.lua deleted file mode 100644 index 2d8c47b4..00000000 --- a/res/generators/flat.lua +++ /dev/null @@ -1,30 +0,0 @@ -function generate_heightmap(x, y, w, h) - local umap = Heightmap(w, h) - local vmap = Heightmap(w, h) - umap:noise({x+521, y+73}, 0.05, 1, 20.8) - umap:noise({x+51, y+75}, 0.05, 1, 21.8) - vmap:noise({x+521, y+70}, 0.1, 3, 35.8) - vmap:noise({x+95, y+246}, 0.15, 3, 35.8) - - local bmap = Heightmap(w, h) - bmap:noise({x+3, y+6}, 0.1, 1, 3) - - local map = Heightmap(w, h) - map:noise({x, y}, 0.06, 5, 0.2, umap, vmap) - map:noise({x, y}, 0.12, 6, 0.5, umap, vmap) - map:mul(bmap) - map:mul(0.7) - - local rivermap = Heightmap(w, h) - rivermap:noise({x+21, y+12}, 0.1, 3) - rivermap:abs() - rivermap:min(0.5) - rivermap:mul(2.0) - rivermap:pow(0.6) - map:add(1.2) - map:mul(rivermap) - map:add(-1.0) - map:mul(0.5) - - return map -end diff --git a/src/content/Content.hpp b/src/content/Content.hpp index 8e152a51..06d4fb47 100644 --- a/src/content/Content.hpp +++ b/src/content/Content.hpp @@ -120,6 +120,10 @@ public: } return *found->second; } + + const auto& getDefs() const { + return defs; + } }; class ResourceIndices { diff --git a/src/engine.cpp b/src/engine.cpp index 787a257b..6a98e1d3 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -30,13 +30,10 @@ #include "logic/scripting/scripting.hpp" #include "util/listutil.hpp" #include "util/platform.hpp" -#include "voxels/DefaultWorldGenerator.hpp" -#include "voxels/FlatWorldGenerator.hpp" #include "window/Camera.hpp" #include "window/Events.hpp" #include "window/input.hpp" #include "window/Window.hpp" -#include "world/WorldGenerators.hpp" #include "settings.hpp" #include @@ -50,11 +47,6 @@ static debug::Logger logger("engine"); namespace fs = std::filesystem; -static void add_world_generators() { - WorldGenerators::addGenerator("core:default"); - WorldGenerators::addGenerator("core:flat"); -} - static void create_channel(Engine* engine, std::string name, NumberSetting& setting) { if (name != "master") { audio::create_channel(name); @@ -114,7 +106,6 @@ Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, Engin keepAlive(settings.ui.language.observe([=](auto lang) { setLanguage(lang); }, true)); - add_world_generators(); scripting::initialize(this); basePacks = files::read_list(resdir/fs::path("config/builtins.list")); diff --git a/src/logic/ChunksController.cpp b/src/logic/ChunksController.cpp index 66d9f539..29d9e65f 100644 --- a/src/logic/ChunksController.cpp +++ b/src/logic/ChunksController.cpp @@ -18,7 +18,6 @@ #include "voxels/WorldGenerator.hpp" #include "world/Level.hpp" #include "world/World.hpp" -#include "world/WorldGenerators.hpp" const uint MAX_WORK_PER_FRAME = 128; const uint MIN_SURROUNDING = 9; @@ -28,10 +27,10 @@ ChunksController::ChunksController(Level* level, uint padding) chunks(level->chunks.get()), lighting(level->lighting.get()), padding(padding), - generator(WorldGenerators::createGenerator( - level->getWorld()->getGenerator(), level->content - )) { -} + generator(std::make_unique( + level->content->generators.require(level->getWorld()->getGenerator()), + level->content + )) {} ChunksController::~ChunksController() = default; diff --git a/src/logic/scripting/lua/libcore.cpp b/src/logic/scripting/lua/libcore.cpp index 2e1034a0..a1f4ee20 100644 --- a/src/logic/scripting/lua/libcore.cpp +++ b/src/logic/scripting/lua/libcore.cpp @@ -3,6 +3,7 @@ #include "constants.hpp" #include "engine.hpp" +#include "content/Content.hpp" #include "files/engine_paths.hpp" #include "files/settings_io.hpp" #include "frontend/menu.hpp" @@ -11,8 +12,8 @@ #include "logic/LevelController.hpp" #include "window/Events.hpp" #include "window/Window.hpp" +#include "voxels/WorldGenerator.hpp" #include "world/Level.hpp" -#include "world/WorldGenerators.hpp" #include "api_lua.hpp" using namespace scripting; @@ -173,18 +174,19 @@ static int l_quit(lua::State*) { /// @brief Get the default world generator /// @return The ID of the default world generator static int l_get_default_generator(lua::State* L) { - return lua::pushstring(L, WorldGenerators::getDefaultGeneratorID()); + return lua::pushstring(L, WorldGenerator::DEFAULT); } /// @brief Get a list of all world generators /// @return A table with the IDs of all world generators static int l_get_generators(lua::State* L) { - const auto& generators = WorldGenerators::getGeneratorsIDs(); + const auto& generators = content->generators.getDefs(); lua::createtable(L, generators.size(), 0); int i = 0; - for (auto& id : generators) { - lua::pushstring(L, id); + for (auto& [name, _] : generators) { + std::cout << name << std::endl; + lua::pushstring(L, name); lua::rawseti(L, i + 1); i++; } diff --git a/src/logic/scripting/lua/lua_custom_types.hpp b/src/logic/scripting/lua/lua_custom_types.hpp index 951d52cf..1e6406b6 100644 --- a/src/logic/scripting/lua/lua_custom_types.hpp +++ b/src/logic/scripting/lua/lua_custom_types.hpp @@ -37,7 +37,7 @@ namespace lua { LuaHeightmap(uint width, uint height) : map(std::make_shared(width, height)) {} - virtual ~LuaHeightmap() = default; + virtual ~LuaHeightmap(); uint getWidth() const { return map->getWidth(); diff --git a/src/logic/scripting/lua/lua_type_heightmap.cpp b/src/logic/scripting/lua/lua_type_heightmap.cpp index 357011f3..506177ea 100644 --- a/src/logic/scripting/lua/lua_type_heightmap.cpp +++ b/src/logic/scripting/lua/lua_type_heightmap.cpp @@ -6,6 +6,7 @@ #include #include "util/functional_util.hpp" +#define FNL_IMPL #include "maths/FastNoiseLite.h" #include "coders/png.hpp" #include "files/util.hpp" @@ -16,6 +17,9 @@ using namespace lua; static fnl_state noise = fnlCreateState(); +LuaHeightmap::~LuaHeightmap() {; +} + static int l_dump(lua::State* L) { if (auto heightmap = touserdata(L, 1)) { auto filename = tostring(L, 2); @@ -95,7 +99,7 @@ static int l_noise(lua::State* L) { template class Op> static int l_binop_func(lua::State* L) { Op op; - if (auto heightmap = touserdata(L, 1)) { + if (auto heightmap = touserdata(L, 1)) { uint w = heightmap->getWidth(); uint h = heightmap->getHeight(); auto heights = heightmap->getValues(); @@ -124,7 +128,7 @@ static int l_binop_func(lua::State* L) { template class Op> static int l_unaryop_func(lua::State* L) { Op op; - if (auto heightmap = touserdata(L, 1)) { + if (auto heightmap = touserdata(L, 1)) { uint w = heightmap->getWidth(); uint h = heightmap->getHeight(); auto heights = heightmap->getValues(); diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 03267e20..b50880bd 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -698,9 +698,12 @@ public: lua::pushivec_stack(L, offset); lua::pushivec_stack(L, size); if (lua::call_nothrow(L, 4)) { - return lua::touserdata(L, -1)->getHeightmap(); + auto map = lua::touserdata(L, -1)->getHeightmap(); + lua::pop(L, 2); + return map; } } + lua::pop(L); return std::make_shared(size.x, size.y); } }; diff --git a/src/voxels/DefaultWorldGenerator.cpp b/src/voxels/DefaultWorldGenerator.cpp deleted file mode 100644 index dc5361e8..00000000 --- a/src/voxels/DefaultWorldGenerator.cpp +++ /dev/null @@ -1,241 +0,0 @@ -#include "DefaultWorldGenerator.hpp" - -#include "Block.hpp" -#include "Chunk.hpp" -#include "voxel.hpp" - -#define FNL_IMPL -#include -#include - -#include -#include -#include -#include -#include - -#include "content/Content.hpp" -#include "core_defs.hpp" -#include "maths/FastNoiseLite.h" -#include "maths/util.hpp" -#include "maths/voxmaths.hpp" - -// will be refactored in generators update - -const int SEA_LEVEL = 55; - -enum class MAPS { SAND, TREE, CLIFF, HEIGHT }; -#define MAPS_LEN 4 - -class Map2D { - int x, z; - int w, d; - float* heights[MAPS_LEN]; -public: - Map2D(int x, int z, int w, int d) : x(x), z(z), w(w), d(d) { - for (int i = 0; i < MAPS_LEN; i++) heights[i] = new float[w * d]; - } - ~Map2D() { - for (int i = 0; i < MAPS_LEN; i++) delete[] heights[i]; - } - - inline float get(MAPS map, int x, int z) { - x -= this->x; - z -= this->z; - if (x < 0 || z < 0 || x >= w || z >= d) { - throw std::runtime_error("out of heightmap"); - } - return heights[(int)map][z * w + x]; - } - - inline void set(MAPS map, int x, int z, float value) { - x -= this->x; - z -= this->z; - if (x < 0 || z < 0 || x >= w || z >= d) { - throw std::runtime_error("out of heightmap"); - } - heights[(int)map][z * w + x] = value; - } -}; - -float calc_height(fnl_state* noise, int cur_x, int cur_z) { - float height = 0; - - height += fnlGetNoise2D( - noise, cur_x * 0.0125f * 8 - 125567, cur_z * 0.0125f * 8 + 3546 - ); - height += fnlGetNoise2D( - noise, cur_x * 0.025f * 8 + 4647, cur_z * 0.025f * 8 - 3436 - ) * - 0.5f; - height += fnlGetNoise2D( - noise, cur_x * 0.05f * 8 - 834176, cur_z * 0.05f * 8 + 23678 - ) * - 0.25f; - height += - fnlGetNoise2D( - noise, - cur_x * 0.2f * 8 + - fnlGetNoise2D( - noise, cur_x * 0.1f * 8 - 23557, cur_z * 0.1f * 8 - 6568 - ) * 50, - cur_z * 0.2f * 8 + - fnlGetNoise2D( - noise, cur_x * 0.1f * 8 + 4363, cur_z * 0.1f * 8 + 4456 - ) * 50 - ) * - fnlGetNoise2D(noise, cur_x * 0.01f - 834176, cur_z * 0.01f + 23678) * - 0.25; - height += - fnlGetNoise2D(noise, cur_x * 0.1f * 8 - 3465, cur_z * 0.1f * 8 + 4534) * - 0.125f; - height *= - fnlGetNoise2D(noise, cur_x * 0.1f + 1000, cur_z * 0.1f + 1000) * 0.5f + - 0.5f; - height += 1.0f; - height *= 64.0f; - return height; -} - -int generate_tree( - fnl_state* noise, - PseudoRandom* random, - Map2D& heights, - // Map2D& humidity, - int cur_x, - int cur_y, - int cur_z, - int tileSize, - blockid_t idWood, - blockid_t idLeaves -) { - const int tileX = floordiv(cur_x, tileSize); - const int tileZ = floordiv(cur_z, tileSize); - - random->setSeed(tileX * 4325261 + tileZ * 12160951 + tileSize * 9431111); - - int randomX = (random->rand() % (tileSize / 2)) - tileSize / 4; - int randomZ = (random->rand() % (tileSize / 2)) - tileSize / 4; - - int centerX = tileX * tileSize + tileSize / 2 + randomX; - int centerZ = tileZ * tileSize + tileSize / 2 + randomZ; - - bool gentree = - (random->rand() % 10) < heights.get(MAPS::TREE, centerX, centerZ) * 13; - if (!gentree) return 0; - - int height = (int)(heights.get(MAPS::HEIGHT, centerX, centerZ)); - if (height < SEA_LEVEL + 1) return 0; - int lx = cur_x - centerX; - int radius = random->rand() % 4 + 2; - int ly = cur_y - height - 3 * radius; - int lz = cur_z - centerZ; - if (lx == 0 && lz == 0 && cur_y - height < (3 * radius + radius / 2)) - return idWood; - if (lx * lx + ly * ly / 2 + lz * lz < radius * radius) return idLeaves; - return 0; -} - -void DefaultWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed) { - const int treesTile = 12; - fnl_state noise = fnlCreateState(); - noise.noise_type = FNL_NOISE_OPENSIMPLEX2; - noise.seed = seed * 60617077 % 25896307; - PseudoRandom randomtree; - PseudoRandom randomgrass; - - int padding = 8; - Map2D heights( - cx * CHUNK_W - padding, - cz * CHUNK_D - padding, - CHUNK_W + padding * 2, - CHUNK_D + padding * 2 - ); - - for (int z = -padding; z < CHUNK_D + padding; z++) { - for (int x = -padding; x < CHUNK_W + padding; x++) { - int cur_x = x + cx * CHUNK_W; - int cur_z = z + cz * CHUNK_D; - float height = calc_height(&noise, cur_x, cur_z); - float hum = fnlGetNoise2D(&noise, cur_x * 0.3 + 633, cur_z * 0.3); - float sand = - fnlGetNoise2D(&noise, cur_x * 0.1 - 633, cur_z * 0.1 + 1000); - float cliff = pow((sand + abs(sand)) / 2, 2); - float w = pow(fmax(-abs(height - SEA_LEVEL) + 4, 0) / 6, 2) * cliff; - float h1 = -abs(height - SEA_LEVEL - 0.03); - float h2 = abs(height - SEA_LEVEL + 0.04); - float h = (h1 + h2) * 100; - height += (h * w); - heights.set(MAPS::HEIGHT, cur_x, cur_z, height); - heights.set(MAPS::TREE, cur_x, cur_z, hum); - heights.set(MAPS::SAND, cur_x, cur_z, sand); - heights.set(MAPS::CLIFF, cur_x, cur_z, cliff); - } - } - - for (int z = 0; z < CHUNK_D; z++) { - int cur_z = z + cz * CHUNK_D; - for (int x = 0; x < CHUNK_W; x++) { - int cur_x = x + cx * CHUNK_W; - float height = heights.get(MAPS::HEIGHT, cur_x, cur_z); - - for (int cur_y = 0; cur_y < CHUNK_H; cur_y++) { - // int cur_y = y; - int id = cur_y < SEA_LEVEL ? idWater : BLOCK_AIR; - blockstate state {}; - if ((cur_y == (int)height) && (SEA_LEVEL - 2 < cur_y)) { - id = idGrassBlock; - } else if (cur_y < (height - 6)) { - id = idStone; - } else if (cur_y < height) { - id = idDirt; - } else { - int tree = generate_tree( - &noise, - &randomtree, - heights, - cur_x, - cur_y, - cur_z, - treesTile, - idWood, - idLeaves - ); - if (tree) { - id = tree; - state.rotation = BLOCK_DIR_UP; - } - } - float sand = fmax( - heights.get(MAPS::SAND, cur_x, cur_z), - heights.get(MAPS::CLIFF, cur_x, cur_z) - ); - if (((height - (1.1 - 0.2 * pow(height - 54, 4)) + (5 * sand)) < - cur_y + (height - 0.01 - (int)height)) && - (cur_y < height)) { - id = idSand; - } - if (cur_y <= 2) id = idBazalt; - - randomgrass.setSeed(cur_x, cur_z); - if ((id == 0) && ((height > SEA_LEVEL + 0.4) || (sand > 0.1)) && - ((int)(height + 1) == cur_y) && - ((unsigned short)randomgrass.rand() > 56000)) { - id = idGrass; - } - if ((id == 0) && (height > SEA_LEVEL + 0.4) && - ((int)(height + 1) == cur_y) && - ((unsigned short)randomgrass.rand() > 65000)) { - id = idFlower; - } - if ((height > SEA_LEVEL + 1) && ((int)(height + 1) == cur_y) && - ((unsigned short)randomgrass.rand() > 65533)) { - id = idWood; - state.rotation = BLOCK_DIR_UP; - } - voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].id = id; - voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].state = state; - } - } - } -} diff --git a/src/voxels/DefaultWorldGenerator.hpp b/src/voxels/DefaultWorldGenerator.hpp deleted file mode 100644 index a53770c8..00000000 --- a/src/voxels/DefaultWorldGenerator.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "typedefs.hpp" -#include "WorldGenerator.hpp" - -struct voxel; -class Content; - -class DefaultWorldGenerator : WorldGenerator { -public: - DefaultWorldGenerator(const Content* content) : WorldGenerator(content) { - } - - void generate(voxel* voxels, int x, int z, int seed); -}; diff --git a/src/voxels/FlatWorldGenerator.cpp b/src/voxels/FlatWorldGenerator.cpp deleted file mode 100644 index d97ab545..00000000 --- a/src/voxels/FlatWorldGenerator.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "FlatWorldGenerator.hpp" - -#include "content/Content.hpp" -#include "core_defs.hpp" -#include "Chunk.hpp" -#include "voxel.hpp" - -void FlatWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed) { - for (int z = 0; z < CHUNK_D; z++) { - for (int x = 0; x < CHUNK_W; x++) { - for (int cur_y = 0; cur_y < CHUNK_H; cur_y++) { - int id = BLOCK_AIR; - blockstate state {}; - - if (cur_y == 2) { - id = idBazalt; - } else if (cur_y == 6) { - id = idGrassBlock; - } else if (cur_y > 2 && cur_y <= 5) { - id = idDirt; - } - - voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].id = id; - voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].state = state; - } - } - } -} diff --git a/src/voxels/FlatWorldGenerator.hpp b/src/voxels/FlatWorldGenerator.hpp deleted file mode 100644 index 8d10ae4b..00000000 --- a/src/voxels/FlatWorldGenerator.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "typedefs.hpp" -#include "WorldGenerator.hpp" - -struct voxel; -class Content; - -class FlatWorldGenerator : WorldGenerator { -public: - FlatWorldGenerator(const Content* content) : WorldGenerator(content) { - } - - void generate(voxel* voxels, int x, int z, int seed); -}; diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index 525a04ca..4217edd5 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -4,16 +4,33 @@ #include "Block.hpp" #include "Chunk.hpp" #include "voxel.hpp" +#include "world/generator/GeneratorDef.hpp" -WorldGenerator::WorldGenerator(const Content* content) - : idStone(content->blocks.require("base:stone").rt.id), - idDirt(content->blocks.require("base:dirt").rt.id), - idGrassBlock(content->blocks.require("base:grass_block").rt.id), - idSand(content->blocks.require("base:sand").rt.id), - idWater(content->blocks.require("base:water").rt.id), - idWood(content->blocks.require("base:wood").rt.id), - idLeaves(content->blocks.require("base:leaves").rt.id), - idGrass(content->blocks.require("base:grass").rt.id), - idFlower(content->blocks.require("base:flower").rt.id), - idBazalt(content->blocks.require("base:bazalt").rt.id) { +WorldGenerator::WorldGenerator( + const GeneratorDef& def, + const Content* content +) : def(def), content(content) { +} + +#include "util/timeutil.hpp" +void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ, int seed) { + timeutil::ScopeLogTimer log(555); + auto heightmap = def.script->generateHeightmap( + {chunkX*CHUNK_W, chunkZ*CHUNK_D}, {CHUNK_W, CHUNK_D} + ); + auto& baseStone = content->blocks.require("base:stone"); + auto& baseWater = content->blocks.require("base:water"); + for (uint z = 0; z < CHUNK_D; z++) { + for (uint x = 0; x < CHUNK_W; x++) { + auto height = heightmap->getValues()[z * CHUNK_W + x] * 255 + 10; + for (uint y = 0; y < CHUNK_H; y++) { + voxels[vox_index(x, y, z)].state = {}; + if (y > height) { + voxels[vox_index(x, y, z)].id = y <= 64 ? baseWater.rt.id : 0; + } else { + voxels[vox_index(x, y, z)].id = baseStone.rt.id; + } + } + } + } } diff --git a/src/voxels/WorldGenerator.hpp b/src/voxels/WorldGenerator.hpp index 7a8c98f3..6f3f22fc 100644 --- a/src/voxels/WorldGenerator.hpp +++ b/src/voxels/WorldGenerator.hpp @@ -6,22 +6,19 @@ struct voxel; class Content; +class GeneratorDef; class WorldGenerator { -protected: - blockid_t const idStone; - blockid_t const idDirt; - blockid_t const idGrassBlock; - blockid_t const idSand; - blockid_t const idWater; - blockid_t const idWood; - blockid_t const idLeaves; - blockid_t const idGrass; - blockid_t const idFlower; - blockid_t const idBazalt; + const GeneratorDef& def; + const Content* content; public: - WorldGenerator(const Content* content); + WorldGenerator( + const GeneratorDef& def, + const Content* content + ); virtual ~WorldGenerator() = default; - virtual void generate(voxel* voxels, int x, int z, int seed) = 0; + virtual void generate(voxel* voxels, int x, int z, int seed); + + inline static std::string DEFAULT = "core:default"; }; diff --git a/src/world/World.cpp b/src/world/World.cpp index f8358960..a694d146 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -15,7 +15,8 @@ #include "voxels/Chunk.hpp" #include "voxels/Chunks.hpp" #include "voxels/ChunksStorage.hpp" -#include "WorldGenerators.hpp" +#include "voxels/WorldGenerator.hpp" +#include "world/generator/GeneratorDef.hpp" #include "Level.hpp" static debug::Logger logger("world"); @@ -205,7 +206,7 @@ void WorldInfo::deserialize(dynamic::Map* root) { seed = root->get("seed", seed); if (generator.empty()) { - generator = WorldGenerators::getDefaultGeneratorID(); + generator = WorldGenerator::DEFAULT; } if (auto verobj = root->map("version")) { verobj->num("major", major); diff --git a/src/world/WorldGenerators.cpp b/src/world/WorldGenerators.cpp deleted file mode 100644 index c64ab756..00000000 --- a/src/world/WorldGenerators.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "WorldGenerators.hpp" - -#include - -#include "content/Content.hpp" -#include "voxels/FlatWorldGenerator.hpp" -#include "voxels/WorldGenerator.hpp" - -std::vector WorldGenerators::getGeneratorsIDs() { - std::vector ids; - for (auto& entry : generators) { - ids.push_back(entry.first); - } - return ids; -} - -std::string WorldGenerators::getDefaultGeneratorID() { - return "core:default"; -} - -std::unique_ptr WorldGenerators::createGenerator( - const std::string& id, const Content* content -) { - auto found = generators.find(id); - if (found == generators.end()) { - throw std::runtime_error("unknown generator id: " + id); - } - return std::unique_ptr(found->second(content)); -} diff --git a/src/world/WorldGenerators.hpp b/src/world/WorldGenerators.hpp deleted file mode 100644 index 91c3a121..00000000 --- a/src/world/WorldGenerators.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "voxels/WorldGenerator.hpp" - -class Content; - -typedef WorldGenerator* (*gen_constructor)(const Content*); - -class WorldGenerators { - static inline std::map generators; -public: - template - static void addGenerator(std::string id); - - static std::vector getGeneratorsIDs(); - - static std::string getDefaultGeneratorID(); - - static std::unique_ptr createGenerator( - const std::string& id, const Content* content - ); -}; - -template -void WorldGenerators::addGenerator(std::string id) { - generators[id] = [](const Content* content) { - return (WorldGenerator*)new T(content); - }; -}