diff --git a/res/content/base/package.json b/res/content/base/package.json index f6b17a98..a9f081fa 100644 --- a/res/content/base/package.json +++ b/res/content/base/package.json @@ -1,6 +1,6 @@ { "id": "base", "title": "Base", - "version": "0.15", + "version": "0.16", "description": "basic content package" } diff --git a/src/engine.cpp b/src/engine.cpp index d49c2738..23c72787 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -40,10 +40,11 @@ using std::unique_ptr; using std::shared_ptr; using std::string; using std::vector; -using std::filesystem::path; using glm::vec3; using gui::GUI; +namespace fs = std::filesystem; + Engine::Engine(EngineSettings& settings, EnginePaths* paths) : settings(settings), paths(paths) { if (Window::initialize(settings.display)){ @@ -53,7 +54,7 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths) auto resdir = paths->getResources(); std::cout << "-- loading assets" << std::endl; - std::vector roots {resdir}; + std::vector roots {resdir}; resPaths.reset(new ResPaths(resdir, roots)); assets.reset(new Assets()); AssetsLoader loader(assets.get(), resPaths.get()); @@ -89,7 +90,7 @@ void Engine::updateHotkeys() { if (Events::jpressed(keycode::F2)) { unique_ptr image(Window::takeScreenshot()); image->flipY(); - path filename = paths->getScreenshotFile("png"); + fs::path filename = paths->getScreenshotFile("png"); png::write_image(filename.string(), image.get()); std::cout << "saved screenshot as " << filename << std::endl; } @@ -173,7 +174,7 @@ void Engine::loadContent() { ContentBuilder contentBuilder; setup_definitions(&contentBuilder); - vector resRoots; + vector resRoots; for (auto& pack : contentPacks) { ContentLoader loader(&pack); loader.load(&contentBuilder); @@ -197,3 +198,10 @@ void Engine::loadContent() { } assets->extend(*new_assets.get()); } + +void Engine::loadAllPacks() { + auto resdir = paths->getResources(); + contentPacks.clear(); + ContentPack::scan(resdir/fs::path("content"), contentPacks); + loadContent(); +} diff --git a/src/engine.h b/src/engine.h index cc544bf1..1c1a58fd 100644 --- a/src/engine.h +++ b/src/engine.h @@ -58,6 +58,7 @@ public: std::vector& getContentPacks(); void setLanguage(std::string locale); void loadContent(); + void loadAllPacks(); }; #endif // SRC_ENGINE_H_ \ No newline at end of file diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index 5264313a..6732ffd8 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -42,7 +42,6 @@ using std::ios; using std::string; using std::unique_ptr; using std::unordered_map; -using std::filesystem::path; namespace fs = std::filesystem; WorldRegion::WorldRegion() { @@ -88,7 +87,7 @@ uint WorldRegion::getSize(uint x, uint z) { return sizes[z * REGION_SIZE + x]; } -WorldFiles::WorldFiles(path directory, const DebugSettings& settings) +WorldFiles::WorldFiles(fs::path directory, const DebugSettings& settings) : directory(directory), generatorTestMode(settings.generatorTestMode), doWriteLights(settings.doWriteLights) { @@ -178,17 +177,17 @@ void WorldFiles::put(Chunk* chunk){ } } -path WorldFiles::getRegionsFolder() const { - return directory/path("regions"); +fs::path WorldFiles::getRegionsFolder() const { + return directory/fs::path("regions"); } -path WorldFiles::getLightsFolder() const { - return directory/path("lights"); +fs::path WorldFiles::getLightsFolder() const { + return directory/fs::path("lights"); } -path WorldFiles::getRegionFilename(int x, int y) const { +fs::path WorldFiles::getRegionFilename(int x, int y) const { string filename = std::to_string(x) + "_" + std::to_string(y) + ".bin"; - return path(filename); + return fs::path(filename); } bool WorldFiles::parseRegionFilename(const string& name, int& x, int& y) { @@ -206,16 +205,20 @@ bool WorldFiles::parseRegionFilename(const string& name, int& x, int& y) { return true; } -path WorldFiles::getPlayerFile() const { - return directory/path("player.json"); +fs::path WorldFiles::getPlayerFile() const { + return directory/fs::path("player.json"); } -path WorldFiles::getWorldFile() const { - return directory/path("world.json"); +fs::path WorldFiles::getWorldFile() const { + return directory/fs::path("world.json"); } -path WorldFiles::getIndicesFile() const { - return directory/path("indices.json"); +fs::path WorldFiles::getIndicesFile() const { + return directory/fs::path("indices.json"); +} + +fs::path WorldFiles::getPacksFile() const { + return directory/fs::path("packs.list"); } ubyte* WorldFiles::getChunk(int x, int z){ @@ -230,7 +233,7 @@ light_t* WorldFiles::getLights(int x, int z) { } ubyte* WorldFiles::getData(unordered_map& regions, - const path& folder, + const fs::path& folder, int x, int z) { int regionX = floordiv(x, REGION_SIZE); int regionZ = floordiv(z, REGION_SIZE); @@ -255,7 +258,7 @@ ubyte* WorldFiles::getData(unordered_map& regions, return nullptr; } -ubyte* WorldFiles::readChunkData(int x, int z, uint32_t& length, path filename){ +ubyte* WorldFiles::readChunkData(int x, int z, uint32_t& length, fs::path filename){ if (generatorTestMode) return nullptr; @@ -293,7 +296,7 @@ ubyte* WorldFiles::readChunkData(int x, int z, uint32_t& length, path filename){ return data; } -void WorldFiles::writeRegion(int x, int y, WorldRegion* entry, path filename){ +void WorldFiles::writeRegion(int x, int y, WorldRegion* entry, fs::path filename){ ubyte** region = entry->getChunks(); uint32_t* sizes = entry->getSizes(); for (size_t i = 0; i < REGION_VOL; i++) { @@ -336,7 +339,7 @@ void WorldFiles::writeRegion(int x, int y, WorldRegion* entry, path filename){ } void WorldFiles::writeRegions(unordered_map& regions, - const path& folder) { + const fs::path& folder) { for (auto it : regions){ WorldRegion* region = it.second; if (region->getChunks() == nullptr || !region->isUnsaved()) @@ -347,25 +350,32 @@ void WorldFiles::writeRegions(unordered_map& regions, } void WorldFiles::write(const World* world, const Content* content) { - { - path directory = getRegionsFolder(); - if (!fs::is_directory(directory)) { - fs::create_directories(directory); - } - } - { - path directory = getLightsFolder(); - if (!fs::is_directory(directory)) { - fs::create_directories(directory); - } - } - if (world) + fs::path regionsFolder = getRegionsFolder(); + fs::path lightsFolder = getLightsFolder(); + + fs::create_directories(regionsFolder); + fs::create_directories(lightsFolder); + + if (world) { writeWorldInfo(world); + writePacks(world); + } if (generatorTestMode) return; + writeIndices(content->indices); - writeRegions(regions, getRegionsFolder()); - writeRegions(lights, getLightsFolder()); + writeRegions(regions, regionsFolder); + writeRegions(lights, lightsFolder); +} + +void WorldFiles::writePacks(const World* world) { + const auto& packs = world->getPacks(); + std::stringstream ss; + ss << "# autogenerated; do not modify\n"; + for (const auto& pack : packs) { + ss << pack.id << "\n"; + } + files::write_string(getPacksFile(), ss.str()); } void WorldFiles::writeIndices(const ContentIndices* indices) { @@ -397,7 +407,7 @@ void WorldFiles::writeWorldInfo(const World* world) { } bool WorldFiles::readWorldInfo(World* world) { - path file = getWorldFile(); + fs::path file = getWorldFile(); if (!fs::is_regular_file(file)) { std::cerr << "warning: world.json does not exists" << std::endl; return false; @@ -443,7 +453,7 @@ void WorldFiles::writePlayer(Player* player){ } bool WorldFiles::readPlayer(Player* player) { - path file = getPlayerFile(); + fs::path file = getPlayerFile(); if (!fs::is_regular_file(file)) { std::cerr << "warning: player.json does not exists" << std::endl; return false; diff --git a/src/files/WorldFiles.h b/src/files/WorldFiles.h index 547534df..e50ccdeb 100644 --- a/src/files/WorldFiles.h +++ b/src/files/WorldFiles.h @@ -54,6 +54,7 @@ class WorldFiles { std::filesystem::path getPlayerFile() const; std::filesystem::path getWorldFile() const; std::filesystem::path getIndicesFile() const; + std::filesystem::path getPacksFile() const; WorldRegion* getRegion(std::unordered_map& regions, int x, int z); @@ -114,6 +115,7 @@ public: void writePlayer(Player* player); /* @param world world info to save (nullable) */ void write(const World* world, const Content* content); + void writePacks(const World* world); void writeIndices(const ContentIndices* indices); }; diff --git a/src/frontend/menu.cpp b/src/frontend/menu.cpp index 9f471e24..aaada578 100644 --- a/src/frontend/menu.cpp +++ b/src/frontend/menu.cpp @@ -66,39 +66,6 @@ Button* create_button(std::wstring text, return btn; } -void show_content_select(GUI* gui, Engine* engine) { - PagesControl* menu = gui->getMenu(); - Panel* panel = new Panel(vec2(200, 200), vec4(8.0f), 8.0f); - - auto resdir = engine->getPaths()->getResources(); - std::vector allpacks; - ContentPack::scan(resdir / fs::path("content"), allpacks); - - for (ContentPack& pack : allpacks) { - bool selected = false; - for (ContentPack& spack : engine->getContentPacks()) { - if (spack.id == pack.id) { - selected = true; - break; - } - } - Panel* checkpanel = new Panel(vec2(400, 32), vec4(5.0f), 1.0f); - checkpanel->color(vec4(0.0f)); - checkpanel->orientation(Orientation::horizontal); - - CheckBox* checkbox = new CheckBox(selected); - checkbox->margin(vec4(0.0f, 0.0f, 5.0f, 0.0f)); - - checkpanel->add(checkbox); - checkpanel->add(new Label(langs::get(util::str2wstr_utf8(pack.title), L"pack-title"))); - - panel->add(checkpanel); - } - panel->add(guiutil::backButton(menu)); - menu->add("content-select", panel); - menu->set("content-select"); -} - void show_content_missing(Engine* engine, const Content* content, ContentLUT* lut) { auto* gui = engine->getGUI(); auto* menu = gui->getMenu(); @@ -214,7 +181,7 @@ void open_world(std::string name, Engine* engine) { show_convert_request(engine, content, lut, folder); } } else { - Level* level = World::load(folder, settings, content); + Level* level = World::load(folder, settings, content, packs); engine->setScreen(std::make_shared(engine, level)); } } @@ -249,8 +216,6 @@ void create_main_menu_panel(Engine* engine, PagesControl* menu) { panel->add(guiutil::gotoButton(L"New World", "new-world", menu)); panel->add(create_worlds_panel(engine)); panel->add(guiutil::gotoButton(L"Settings", "settings", menu)); - panel->add(guiutil::gotoButton(L"Content", "content", menu)); - panel->add((new Button(langs::get(L"Quit", L"menu"), vec4(10.f))) ->listenAction([](GUI* gui) { Window::setShouldClose(true); @@ -295,11 +260,6 @@ void create_new_world_panel(Engine* engine, PagesControl* menu) { panel->add(seedInput); } - panel->add((new Button(langs::get(L"Content", L"menu"), vec4(10.0f))) - ->listenAction([=](GUI* gui){ - show_content_select(gui, engine); - })); - vec4 basecolor = worldNameInput->color(); panel->add(create_button( L"Create World", vec4(10), vec4(1, 20, 1, 1), [=](GUI*) { @@ -330,18 +290,13 @@ void create_new_world_panel(Engine* engine, PagesControl* menu) { auto folder = paths->getWorldsFolder()/fs::u8path(nameutf8); fs::create_directories(folder); - // TODO: complete and move somewhere - auto resdir = engine->getPaths()->getResources(); - auto& packs = engine->getContentPacks(); - packs.clear(); - packs.push_back(ContentPack::read(resdir/fs::path("content/base"))); - engine->loadContent(); - + engine->loadAllPacks(); Level* level = World::create(nameutf8, - folder, - seed, - engine->getSettings(), - engine->getContent()); + folder, + seed, + engine->getSettings(), + engine->getContent(), + engine->getContentPacks()); engine->setScreen(std::make_shared(engine, level)); })); panel->add(guiutil::backButton(menu)); diff --git a/src/world/World.cpp b/src/world/World.cpp index 3a1c8df3..4ba78793 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -27,9 +27,11 @@ World::World(string name, path directory, uint64_t seed, EngineSettings& settings, - const Content* content) + const Content* content, + const std::vector packs) : settings(settings), content(content), + packs(packs), name(name), seed(seed) { wfile = new WorldFiles(directory, settings.debug); @@ -71,8 +73,9 @@ Level* World::create(string name, path directory, uint64_t seed, EngineSettings& settings, - const Content* content) { - World* world = new World(name, directory, seed, settings, content); + const Content* content, + const std::vector& packs) { + World* world = new World(name, directory, seed, settings, content, packs); Player* player = new Player(vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED); return new Level(world, content, player, settings); } @@ -88,8 +91,9 @@ ContentLUT* World::checkIndices(const path& directory, Level* World::load(path directory, EngineSettings& settings, - const Content* content) { - unique_ptr world (new World(".", directory, 0, settings, content)); + const Content* content, + const std::vector& packs) { + unique_ptr world (new World(".", directory, 0, settings, content, packs)); auto& wfile = world->wfile; if (!wfile->readWorldInfo(world.get())) { @@ -103,3 +107,7 @@ Level* World::load(path directory, world.release(); return level; } + +const std::vector& World::getPacks() const { + return packs; +} diff --git a/src/world/World.h b/src/world/World.h index ac37d5c2..6f2c7743 100644 --- a/src/world/World.h +++ b/src/world/World.h @@ -2,12 +2,15 @@ #define WORLD_WORLD_H_ #include +#include #include #include #include "../typedefs.h" #include "../settings.h" #include "../util/timeutil.h" +#include "../content/ContentPack.h" + class Content; class WorldFiles; class Chunks; @@ -23,6 +26,7 @@ public: class World { EngineSettings& settings; const Content* const content; + std::vector packs; public: std::string name; WorldFiles* wfile; @@ -39,7 +43,8 @@ public: std::filesystem::path directory, uint64_t seed, EngineSettings& settings, - const Content* content); + const Content* content, + std::vector packs); ~World(); void updateTimers(float delta); @@ -52,10 +57,14 @@ public: std::filesystem::path directory, uint64_t seed, EngineSettings& settings, - const Content* content); + const Content* content, + const std::vector& packs); static Level* load(std::filesystem::path directory, EngineSettings& settings, - const Content* content); + const Content* content, + const std::vector& packs); + + const std::vector& getPacks() const; }; #endif /* WORLD_WORLD_H_ */