diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index b85e34bf..562c40c0 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -76,7 +76,7 @@ fs::path WorldFiles::getPacksFile() const { void WorldFiles::write(const World* world, const Content* content) { if (world) { - writeWorldInfo(world); + writeWorldInfo(world->getInfo()); if (!fs::exists(getPacksFile())) { writePacks(world->getPacks()); } @@ -116,19 +116,20 @@ void WorldFiles::writeIndices(const ContentIndices* indices) { files::write_json(getIndicesFile(), &root); } -void WorldFiles::writeWorldInfo(const World* world) { - files::write_json(getWorldFile(), world->serialize().get()); +void WorldFiles::writeWorldInfo(const WorldInfo& info) { + files::write_json(getWorldFile(), info.serialize().get()); } -bool WorldFiles::readWorldInfo(World* world) { +std::optional WorldFiles::readWorldInfo() { fs::path file = getWorldFile(); if (!fs::is_regular_file(file)) { logger.warning() << "world.json does not exists"; - return false; + return std::nullopt; } auto root = files::read_json(file); - world->deserialize(root.get()); - return true; + WorldInfo info {}; + info.deserialize(root.get()); + return info; } static void read_resources_data( diff --git a/src/files/WorldFiles.hpp b/src/files/WorldFiles.hpp index 311a5feb..12753d0c 100644 --- a/src/files/WorldFiles.hpp +++ b/src/files/WorldFiles.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,7 @@ class Player; class Content; class ContentIndices; class World; +struct WorldInfo; struct DebugSettings; namespace fs = std::filesystem; @@ -35,7 +37,7 @@ class WorldFiles { fs::path getIndicesFile() const; fs::path getPacksFile() const; - void writeWorldInfo(const World* world); + void writeWorldInfo(const WorldInfo& info); void writeIndices(const ContentIndices* indices); public: WorldFiles(const fs::path& directory); @@ -46,7 +48,7 @@ public: fs::path getResourcesFile() const; void createDirectories(); - bool readWorldInfo(World* world); + std::optional readWorldInfo(); bool readResourcesData(const Content* content); /// @brief Write all unsaved data to world files diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index 4b01e32f..fa827724 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -160,9 +160,10 @@ std::shared_ptr create_debug_panel( sub->add(box, glm::vec2(20, 0)); panel->add(sub); } - panel->add(create_label([=](){ + auto& worldInfo = level->getWorld()->getInfo(); + panel->add(create_label([&](){ int hour, minute, second; - timeutil::from_value(level->getWorld()->daytime, hour, minute, second); + timeutil::from_value(worldInfo.daytime, hour, minute, second); std::wstring timeString = util::lfill(std::to_wstring(hour), 2, L'0') + L":" + @@ -171,14 +172,14 @@ std::shared_ptr create_debug_panel( })); { auto bar = std::make_shared(0.0f, 1.0f, 1.0f, 0.005f, 8); - bar->setSupplier([=]() {return level->getWorld()->daytime;}); - bar->setConsumer([=](double val) {level->getWorld()->daytime = val;}); + bar->setSupplier([&]() {return worldInfo.daytime;}); + bar->setConsumer([&](double val) {worldInfo.daytime = val;}); panel->add(bar); } { auto bar = std::make_shared(0.0f, 1.0f, 0.0f, 0.005f, 8); - bar->setSupplier([=]() {return level->getWorld()->fog;}); - bar->setConsumer([=](double val) {level->getWorld()->fog = val;}); + bar->setSupplier([&]() {return worldInfo.fog;}); + bar->setConsumer([&](double val) {worldInfo.fog = val;}); panel->add(bar); } { diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index b8eb5011..a293ae2f 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -161,7 +161,7 @@ void WorldRenderer::setupWorldShader( shader->uniform1f("u_gamma", settings.graphics.gamma.get()); shader->uniform1f("u_fogFactor", fogFactor); shader->uniform1f("u_fogCurve", settings.graphics.fogCurve.get()); - shader->uniform1f("u_dayTime", level->getWorld()->daytime); + shader->uniform1f("u_dayTime", level->getWorld()->getInfo().daytime); shader->uniform3f("u_cameraPos", camera->position); shader->uniform1i("u_cubemap", 1); @@ -338,8 +338,10 @@ void WorldRenderer::draw( const Viewport& vp = pctx.getViewport(); camera->aspect = vp.getWidth() / static_cast(vp.getHeight()); - const EngineSettings& settings = engine->getSettings(); - skybox->refresh(pctx, world->daytime, 1.0f + world->fog * 2.0f, 4); + const auto& settings = engine->getSettings(); + const auto& worldInfo = world->getInfo(); + + skybox->refresh(pctx, worldInfo.daytime, 1.0f + worldInfo.fog * 2.0f, 4); auto assets = engine->getAssets(); auto linesShader = assets->get("lines"); @@ -352,7 +354,7 @@ void WorldRenderer::draw( Window::clearDepth(); // Drawing background sky plane - skybox->draw(pctx, camera, assets, world->daytime, world->fog); + skybox->draw(pctx, camera, assets, worldInfo.daytime, worldInfo.fog); // Actually world render with depth buffer on { @@ -375,7 +377,7 @@ void WorldRenderer::draw( auto screenShader = assets->get("screen"); screenShader->use(); screenShader->uniform1f("u_timer", timer); - screenShader->uniform1f("u_dayTime", level->getWorld()->daytime); + screenShader->uniform1f("u_dayTime", worldInfo.daytime); postProcessing->render(pctx, screenShader); } diff --git a/src/logic/scripting/lua/libworld.cpp b/src/logic/scripting/lua/libworld.cpp index ab87ee1c..168edb28 100644 --- a/src/logic/scripting/lua/libworld.cpp +++ b/src/logic/scripting/lua/libworld.cpp @@ -42,27 +42,27 @@ static int l_world_get_list(lua::State* L) { } static int l_world_get_total_time(lua::State* L) { - return lua::pushnumber(L, level->getWorld()->totalTime); + return lua::pushnumber(L, level->getWorld()->getInfo().totalTime); } static int l_world_get_day_time(lua::State* L) { - return lua::pushnumber(L, level->getWorld()->daytime); + return lua::pushnumber(L, level->getWorld()->getInfo().daytime); } static int l_world_set_day_time(lua::State* L) { auto value = lua::tonumber(L, 1); - level->getWorld()->daytime = fmod(value, 1.0); + level->getWorld()->getInfo().daytime = std::fmod(value, 1.0); return 0; } static int l_world_set_day_time_speed(lua::State* L) { auto value = lua::tonumber(L, 1); - level->getWorld()->daytimeSpeed = std::abs(value); + level->getWorld()->getInfo().daytimeSpeed = std::abs(value); return 0; } static int l_world_get_day_time_speed(lua::State* L) { - return lua::pushnumber(L, level->getWorld()->daytimeSpeed); + return lua::pushnumber(L, level->getWorld()->getInfo().daytimeSpeed); } static int l_world_get_seed(lua::State* L) { @@ -76,12 +76,12 @@ static int l_world_exists(lua::State* L) { } static int l_world_is_day(lua::State* L) { - auto daytime = level->getWorld()->daytime; + auto daytime = level->getWorld()->getInfo().daytime; return lua::pushboolean(L, daytime >= 0.2 && daytime <= 0.8); } static int l_world_is_night(lua::State* L) { - auto daytime = level->getWorld()->daytime; + auto daytime = level->getWorld()->getInfo().daytime; return lua::pushboolean(L, daytime < 0.2 || daytime > 0.8); } diff --git a/src/world/Level.cpp b/src/world/Level.cpp index 3c8e9dba..6d9b1f03 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -29,6 +29,7 @@ Level::Level( events(std::make_unique()), entities(std::make_unique(this)), settings(settings) { + auto& worldInfo = world->getInfo(); auto& cameraIndices = content->getIndices(ResourceType::CAMERA); for (size_t i = 0; i < cameraIndices.size(); i++) { auto camera = std::make_shared(); @@ -46,8 +47,8 @@ Level::Level( cameras.push_back(std::move(camera)); } - if (world->nextEntityId) { - entities->setNextID(world->nextEntityId); + if (worldInfo.nextEntityId) { + entities->setNextID(worldInfo.nextEntityId); } auto inv = std::make_shared( world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE diff --git a/src/world/World.cpp b/src/world/World.cpp index e15837b8..4e00183b 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -26,29 +26,22 @@ world_load_error::world_load_error(const std::string& message) } World::World( - std::string name, - std::string generator, - const fs::path& directory, - uint64_t seed, - EngineSettings& settings, + WorldInfo info, + std::unique_ptr worldFiles, const Content* content, const std::vector& packs -) - : name(std::move(name)), - generator(std::move(generator)), - seed(seed), - content(content), - packs(packs), - wfile(std::make_unique(directory, settings.debug)) { -} +) : info(std::move(info)), + content(content), + packs(packs), + wfile(std::move(worldFiles)) {} World::~World() { } void World::updateTimers(float delta) { - daytime += delta * daytimeSpeed * DAYIME_SPECIFIC_SPEED; - daytime = fmod(daytime, 1.0f); - totalTime += delta; + info.daytime += delta * info.daytimeSpeed * DAYIME_SPECIFIC_SPEED; + info.daytime = std::fmod(info.daytime, 1.0f); + info.totalTime += delta; } void World::writeResources(const Content* content) { @@ -71,7 +64,7 @@ void World::writeResources(const Content* content) { void World::write(Level* level) { const Content* content = level->content; level->chunks->saveAll(); - nextEntityId = level->entities->peekNextID(); + info.nextEntityId = level->entities->peekNextID(); wfile->write(this, content); auto playerFile = dynamic::Map(); @@ -95,8 +88,15 @@ std::unique_ptr World::create( const Content* content, const std::vector& packs ) { + WorldInfo info {}; + info.name = name; + info.generator = generator; + info.seed = seed; auto world = std::make_unique( - name, generator, directory, seed, settings, content, packs + info, + std::make_unique(directory, settings.debug), + content, + packs ); return std::make_unique(std::move(world), content, settings); } @@ -107,20 +107,21 @@ std::unique_ptr World::load( const Content* content, const std::vector& packs ) { + auto worldFilesPtr = std::make_unique(directory, settings.debug); + auto worldFiles = worldFilesPtr.get(); + auto info = worldFiles->readWorldInfo(); + if (!info.has_value()) { + throw world_load_error("could not to find world.json"); + } + logger.info() << "world version: " << info->major << "." << info->minor; + auto world = std::make_unique( - ".", - WorldGenerators::getDefaultGeneratorID(), - directory, - 0, - settings, + info.value(), + std::move(worldFilesPtr), content, packs ); auto& wfile = world->wfile; - - if (!wfile->readWorldInfo(world.get())) { - throw world_load_error("could not to find world.json"); - } wfile->readResourcesData(content); auto level = std::make_unique(std::move(world), content, settings); @@ -165,11 +166,11 @@ std::shared_ptr World::checkIndices( } void World::setName(const std::string& name) { - this->name = name; + this->info.name = name; } void World::setGenerator(const std::string& generator) { - this->generator = generator; + this->info.generator = generator; } bool World::hasPack(const std::string& id) const { @@ -180,26 +181,26 @@ bool World::hasPack(const std::string& id) const { } void World::setSeed(uint64_t seed) { - this->seed = seed; + this->info.seed = seed; } std::string World::getName() const { - return name; + return info.name; } uint64_t World::getSeed() const { - return seed; + return info.seed; } std::string World::getGenerator() const { - return generator; + return info.generator; } const std::vector& World::getPacks() const { return packs; } -void World::deserialize(dynamic::Map* root) { +void WorldInfo::deserialize(dynamic::Map* root) { name = root->get("name", name); generator = root->get("generator", generator); seed = root->get("seed", seed); @@ -208,10 +209,8 @@ void World::deserialize(dynamic::Map* root) { generator = WorldGenerators::getDefaultGeneratorID(); } if (auto verobj = root->map("version")) { - int major = 0, minor = -1; verobj->num("major", major); verobj->num("minor", minor); - logger.info() << "world version: " << major << "." << minor; } if (auto timeobj = root->map("time")) { timeobj->num("day-time", daytime); @@ -225,7 +224,7 @@ void World::deserialize(dynamic::Map* root) { nextEntityId = root->get("next-entity-id", 1); } -std::unique_ptr World::serialize() const { +std::unique_ptr WorldInfo::serialize() const { auto root = std::make_unique(); auto& versionobj = root->putMap("version"); diff --git a/src/world/World.hpp b/src/world/World.hpp index 7f30e52c..6556dbcc 100644 --- a/src/world/World.hpp +++ b/src/world/World.hpp @@ -24,20 +24,12 @@ public: world_load_error(const std::string& message); }; -/// @brief holds all world data except the level (chunks and objects) -class World : Serializable { +struct WorldInfo : public Serializable { std::string name; std::string generator; uint64_t seed; - const Content* const content; - std::vector packs; - int64_t nextInventoryId = 0; - void writeResources(const Content* content); -public: - std::unique_ptr wfile; - /// @brief Day/night loop timer in range 0..1 where /// 0.0 - is midnight and /// 0.5 - is noon @@ -54,12 +46,28 @@ public: entityid_t nextEntityId = 0; + int major = 0, minor = -1; + + std::unique_ptr serialize() const override; + void deserialize(dynamic::Map* src) override; +}; + +/// @brief holds all world data except the level (chunks and objects) +class World { + WorldInfo info {}; + + const Content* const content; + std::vector packs; + + int64_t nextInventoryId = 0; + + void writeResources(const Content* content); +public: + std::unique_ptr wfile; + World( - std::string name, - std::string generator, - const fs::path& directory, - uint64_t seed, - EngineSettings& settings, + WorldInfo info, + std::unique_ptr wfile, const Content* content, const std::vector& packs ); @@ -134,6 +142,14 @@ public: /// @brief Get world generator id std::string getGenerator() const; + WorldInfo& getInfo() { + return info; + } + + const WorldInfo& getInfo() const { + return info; + } + /// @brief Get vector of all content-packs installed in world const std::vector& getPacks() const; @@ -147,7 +163,4 @@ public: const Content* getContent() const { return content; } - - std::unique_ptr serialize() const override; - void deserialize(dynamic::Map* src) override; };