Auto content packs detection
This commit is contained in:
parent
bcfdc55277
commit
3ad903449e
@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "base",
|
||||
"title": "Base",
|
||||
"version": "0.15",
|
||||
"version": "0.16",
|
||||
"description": "basic content package"
|
||||
}
|
||||
|
||||
@ -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<path> roots {resdir};
|
||||
std::vector<fs::path> 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<ImageData> 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<path> resRoots;
|
||||
vector<fs::path> 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();
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ public:
|
||||
std::vector<ContentPack>& getContentPacks();
|
||||
void setLanguage(std::string locale);
|
||||
void loadContent();
|
||||
void loadAllPacks();
|
||||
};
|
||||
|
||||
#endif // SRC_ENGINE_H_
|
||||
@ -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<ivec2, WorldRegion*>& 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<ivec2, WorldRegion*>& 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<ivec2, WorldRegion*>& 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<ivec2, WorldRegion*>& 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;
|
||||
|
||||
@ -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<glm::ivec2, WorldRegion*>& 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);
|
||||
};
|
||||
|
||||
|
||||
@ -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<ContentPack> 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<LevelScreen>(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<LevelScreen>(engine, level));
|
||||
}));
|
||||
panel->add(guiutil::backButton(menu));
|
||||
|
||||
@ -27,9 +27,11 @@ World::World(string name,
|
||||
path directory,
|
||||
uint64_t seed,
|
||||
EngineSettings& settings,
|
||||
const Content* content)
|
||||
const Content* content,
|
||||
const std::vector<ContentPack> 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<ContentPack>& 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> world (new World(".", directory, 0, settings, content));
|
||||
const Content* content,
|
||||
const std::vector<ContentPack>& packs) {
|
||||
unique_ptr<World> 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<ContentPack>& World::getPacks() const {
|
||||
return packs;
|
||||
}
|
||||
|
||||
@ -2,12 +2,15 @@
|
||||
#define WORLD_WORLD_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include <stdexcept>
|
||||
#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<ContentPack> 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<ContentPack> 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<ContentPack>& packs);
|
||||
static Level* load(std::filesystem::path directory,
|
||||
EngineSettings& settings,
|
||||
const Content* content);
|
||||
const Content* content,
|
||||
const std::vector<ContentPack>& packs);
|
||||
|
||||
const std::vector<ContentPack>& getPacks() const;
|
||||
};
|
||||
|
||||
#endif /* WORLD_WORLD_H_ */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user