diff --git a/dev/tests/example.lua b/dev/tests/example.lua index e69de29b..6c9546a8 100644 --- a/dev/tests/example.lua +++ b/dev/tests/example.lua @@ -0,0 +1,2 @@ +test.new_world("demo", "2019", "core:default") +print(world.get_generator()) diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 9a5aa08a..d8a593b0 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -12,6 +12,7 @@ end if test then test.sleep = sleep test.name = __VC_TEST_NAME + test.new_world = core.new_world end ------------------------------------------------ diff --git a/src/Mainloop.cpp b/src/Mainloop.cpp index 180e75f5..102aa7cd 100644 --- a/src/Mainloop.cpp +++ b/src/Mainloop.cpp @@ -3,7 +3,9 @@ #include "debug/Logger.hpp" #include "engine.hpp" #include "frontend/screens/MenuScreen.hpp" +#include "frontend/screens/LevelScreen.hpp" #include "window/Window.hpp" +#include "world/Level.hpp" static debug::Logger logger("mainloop"); @@ -13,6 +15,10 @@ Mainloop::Mainloop(Engine& engine) : engine(engine) { void Mainloop::run() { auto& time = engine.getTime(); + engine.setLevelConsumer([this](auto level) { + engine.setScreen(std::make_shared(&engine, std::move(level))); + }); + logger.info() << "starting menu screen"; engine.setScreen(std::make_shared(&engine)); diff --git a/src/TestMainloop.cpp b/src/TestMainloop.cpp index 617a65cd..955f4b26 100644 --- a/src/TestMainloop.cpp +++ b/src/TestMainloop.cpp @@ -1,8 +1,10 @@ #include "TestMainloop.hpp" #include "logic/scripting/scripting.hpp" +#include "logic/LevelController.hpp" #include "interfaces/Process.hpp" #include "debug/Logger.hpp" +#include "world/Level.hpp" #include "engine.hpp" static debug::Logger logger("mainloop"); @@ -12,6 +14,8 @@ inline constexpr int TPS = 20; TestMainloop::TestMainloop(Engine& engine) : engine(engine) { } +TestMainloop::~TestMainloop() = default; + void TestMainloop::run() { const auto& coreParams = engine.getCoreParameters(); auto& time = engine.getTime(); @@ -20,6 +24,9 @@ void TestMainloop::run() { logger.info() << "nothing to do"; return; } + engine.setLevelConsumer([this](auto level) { + setLevel(std::move(level)); + }); logger.info() << "starting test " << coreParams.testFile; auto process = scripting::start_coroutine(coreParams.testFile); @@ -29,3 +36,7 @@ void TestMainloop::run() { } logger.info() << "test finished"; } + +void TestMainloop::setLevel(std::unique_ptr level) { + this->controller = std::make_unique(&engine, std::move(level)); +} diff --git a/src/TestMainloop.hpp b/src/TestMainloop.hpp index b0acc9a7..06ffae25 100644 --- a/src/TestMainloop.hpp +++ b/src/TestMainloop.hpp @@ -1,11 +1,19 @@ #pragma once +#include + +class Level; +class LevelController; class Engine; class TestMainloop { Engine& engine; + std::unique_ptr controller; public: TestMainloop(Engine& engine); + ~TestMainloop(); void run(); + + void setLevel(std::unique_ptr level); }; diff --git a/src/engine.cpp b/src/engine.cpp index 622a2fdb..072bd5f6 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -19,6 +19,7 @@ #include "frontend/menu.hpp" #include "frontend/screens/Screen.hpp" #include "frontend/screens/MenuScreen.hpp" +#include "frontend/screens/LevelScreen.hpp" #include "graphics/render/ModelsGenerator.hpp" #include "graphics/core/DrawContext.hpp" #include "graphics/core/ImageData.hpp" @@ -35,6 +36,7 @@ #include "window/Events.hpp" #include "window/input.hpp" #include "window/Window.hpp" +#include "world/Level.hpp" #include "Mainloop.hpp" #include "TestMainloop.hpp" @@ -120,7 +122,7 @@ Engine::Engine(CoreParameters coreParameters) } keepAlive(settings.ui.language.observe([=](auto lang) { setLanguage(lang); - }, !langNotSet)); + }, true)); scripting::initialize(this); basePacks = files::read_list(resdir/fs::path("config/builtins.list")); @@ -272,6 +274,10 @@ PacksManager Engine::createPacksManager(const fs::path& worldFolder) { return manager; } +void Engine::setLevelConsumer(consumer> levelConsumer) { + this->levelConsumer = std::move(levelConsumer); +} + void Engine::loadAssets() { logger.info() << "loading assets"; Shader::preprocessor->setPaths(resPaths.get()); @@ -380,8 +386,10 @@ void Engine::loadContent() { ContentLoader::loadScripts(*content); langs::setup(resdir, langs::current->getId(), contentPacks); - loadAssets(); - onAssetsLoaded(); + if (!isHeadless()) { + loadAssets(); + onAssetsLoaded(); + } } void Engine::resetContent() { @@ -445,6 +453,10 @@ void Engine::setLanguage(std::string locale) { } } +void Engine::onWorldOpen(std::unique_ptr level) { + levelConsumer(std::move(level)); +} + gui::GUI* Engine::getGUI() { return gui.get(); } diff --git a/src/engine.hpp b/src/engine.hpp index fee92e81..55104cb1 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -21,6 +21,7 @@ #include #include +class Level; class Screen; class EnginePaths; class ResPaths; @@ -71,6 +72,7 @@ class Engine : public util::ObjectsKeeper { std::vector basePacks; std::unique_ptr gui; Time time; + consumer> levelConsumer; void loadControls(); void loadSettings(); @@ -132,6 +134,8 @@ public: /// @brief Get engine resource paths controller ResPaths* getResPaths(); + void onWorldOpen(std::unique_ptr level); + /// @brief Get current Content instance const Content* getContent() const; @@ -155,6 +159,8 @@ public: PacksManager createPacksManager(const fs::path& worldFolder); + void setLevelConsumer(consumer> levelConsumer); + SettingsHandler& getSettingsHandler(); network::Network& getNetwork(); diff --git a/src/logic/EngineController.cpp b/src/logic/EngineController.cpp index edd6efb7..27e254f3 100644 --- a/src/logic/EngineController.cpp +++ b/src/logic/EngineController.cpp @@ -150,9 +150,7 @@ static void load_world(Engine* engine, const std::shared_ptr& worldF auto& settings = engine->getSettings(); auto level = World::load(worldFiles, settings, content, packs); - engine->setScreen( - std::make_shared(engine, std::move(level)) - ); + engine->onWorldOpen(std::move(level)); } catch (const world_load_error& error) { guiutil::alert( engine->getGUI(), @@ -229,7 +227,10 @@ void EngineController::createWorld( EnginePaths* paths = engine->getPaths(); auto folder = paths->getWorldsFolder() / fs::u8path(name); - if (!menus::call(engine, [this, paths, folder]() { + if (engine->isHeadless()) { + engine->loadContent(); + paths->setCurrentWorldFolder(folder); + } else if (!menus::call(engine, [this, paths, folder]() { engine->loadContent(); paths->setCurrentWorldFolder(folder); })) { @@ -244,7 +245,7 @@ void EngineController::createWorld( engine->getContent(), engine->getContentPacks() ); - engine->setScreen(std::make_shared(engine, std::move(level))); + engine->onWorldOpen(std::move(level)); } void EngineController::reopenWorld(World* world) { diff --git a/src/world/World.cpp b/src/world/World.cpp index 4eb2631a..cde3b3ce 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -95,6 +95,8 @@ std::unique_ptr World::create( content, packs ); + logger.info() << "created world '" << name << "' (" << directory.u8string() << ")"; + logger.info() << "world seed: " << seed << " generator: " << generator; auto level = std::make_unique(std::move(world), content, settings); level->players->create(); return level;