Content packs structure update

This commit is contained in:
MihailRis 2023-12-16 12:47:20 +03:00
parent 04f06a4717
commit 924957ddee
10 changed files with 131 additions and 86 deletions

View File

@ -0,0 +1,28 @@
{
"blocks": [
"dirt",
"grass_block",
"lamp",
"glass",
"planks",
"wood",
"leaves",
"stone",
"water",
"sand",
"bazalt",
"grass",
"flower",
"brick",
"metal",
"rust",
"red_lamp",
"green_lamp",
"blue_lamp",
"pane",
"pipe",
"lightbulb",
"torch",
"wallpaper"
]
}

View File

@ -1,31 +1,6 @@
{ {
"id": "base", "id": "base",
"title": "Base",
"version": "0.15", "version": "0.15",
"description": "basic content package", "description": "basic content package"
"blocks": [
"dirt",
"grass_block",
"lamp",
"glass",
"planks",
"wood",
"leaves",
"stone",
"water",
"sand",
"bazalt",
"grass",
"flower",
"brick",
"metal",
"rust",
"red_lamp",
"green_lamp",
"blue_lamp",
"pane",
"pipe",
"lightbulb",
"torch",
"wallpaper"
]
} }

View File

@ -15,6 +15,7 @@ menu.missing-content=Отсутствует Контент!
menu.Controls=Управление menu.Controls=Управление
menu.Back to Main Menu=Вернуться в Меню menu.Back to Main Menu=Вернуться в Меню
menu.Settings=Настройки menu.Settings=Настройки
menu.Content=Контент
world.Seed=Зерно world.Seed=Зерно
world.Name=Название world.Name=Название
world.Create World=Создать Мир world.Create World=Создать Мир

View File

@ -3,6 +3,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <memory> #include <memory>
#include <glm/glm.hpp>
#include "Content.h" #include "Content.h"
#include "../voxels/Block.h" #include "../voxels/Block.h"
@ -10,27 +11,21 @@
#include "../coders/json.h" #include "../coders/json.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <glm/glm.hpp> #include "ContentPack.h"
// don't ask namespace fs = std::filesystem;
using glm::vec3;
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::unique_ptr;
using std::filesystem::path;
ContentLoader::ContentLoader(path folder) : folder(folder) {} ContentLoader::ContentLoader(const ContentPack* pack) : pack(pack) {
}
// TODO: add basic validation and logging // TODO: add basic validation and logging
Block* ContentLoader::loadBlock(string name, path file) { Block* ContentLoader::loadBlock(std::string name, fs::path file) {
unique_ptr<json::JObject> root(files::read_json(file)); std::unique_ptr<json::JObject> root(files::read_json(file));
unique_ptr<Block> def(new Block(name)); std::unique_ptr<Block> def(new Block(name));
// block texturing // block texturing
if (root->has("texture")) { if (root->has("texture")) {
string texture; std::string texture;
root->str("texture", texture); root->str("texture", texture);
for (uint i = 0; i < 6; i++) for (uint i = 0; i < 6; i++)
def->textureFaces[i] = texture; def->textureFaces[i] = texture;
@ -42,19 +37,19 @@ Block* ContentLoader::loadBlock(string name, path file) {
} }
// block model // block model
string model = "block"; std::string model = "block";
root->str("model", model); root->str("model", model);
if (model == "block") def->model = BlockModel::block; if (model == "block") def->model = BlockModel::block;
else if (model == "aabb") def->model = BlockModel::aabb; else if (model == "aabb") def->model = BlockModel::aabb;
else if (model == "X") def->model = BlockModel::xsprite; else if (model == "X") def->model = BlockModel::xsprite;
else if (model == "none") def->model = BlockModel::none; else if (model == "none") def->model = BlockModel::none;
else { else {
cerr << "unknown model " << model << endl; std::cerr << "unknown model " << model << std::endl;
def->model = BlockModel::none; def->model = BlockModel::none;
} }
// rotation profile // rotation profile
string profile = "none"; std::string profile = "none";
root->str("rotation", profile); root->str("rotation", profile);
def->rotatable = profile != "none"; def->rotatable = profile != "none";
if (profile == "pipe") { if (profile == "pipe") {
@ -62,16 +57,16 @@ Block* ContentLoader::loadBlock(string name, path file) {
} else if (profile == "pane") { } else if (profile == "pane") {
def->rotations = BlockRotProfile::PANE; def->rotations = BlockRotProfile::PANE;
} else if (profile != "none") { } else if (profile != "none") {
cerr << "unknown rotation profile " << profile << endl; std::cerr << "unknown rotation profile " << profile << std::endl;
def->rotatable = false; def->rotatable = false;
} }
// block hitbox AABB [x, y, z, width, height, depth] // block hitbox AABB [x, y, z, width, height, depth]
json::JArray* hitboxobj = root->arr("hitbox"); json::JArray* boxobj = root->arr("hitbox");
if (hitboxobj) { if (boxobj) {
AABB& aabb = def->hitbox; AABB& aabb = def->hitbox;
aabb.a = vec3(hitboxobj->num(0), hitboxobj->num(1), hitboxobj->num(2)); aabb.a = glm::vec3(boxobj->num(0), boxobj->num(1), boxobj->num(2));
aabb.b = vec3(hitboxobj->num(3), hitboxobj->num(4), hitboxobj->num(5)); aabb.b = glm::vec3(boxobj->num(3), boxobj->num(4), boxobj->num(5));
aabb.b += aabb.a; aabb.b += aabb.a;
} }
@ -96,35 +91,17 @@ Block* ContentLoader::loadBlock(string name, path file) {
} }
void ContentLoader::load(ContentBuilder* builder) { void ContentLoader::load(ContentBuilder* builder) {
cout << "-- loading content " << folder << endl; std::cout << "-- loading pack [" << pack->id << "]" << std::endl;
path file = folder / path("package.json"); auto folder = pack->folder;
string source = files::read_string(file); auto root = files::read_json(pack->getContentFile());
unique_ptr<json::JObject> root = nullptr;
try {
root.reset(json::parse(file.filename().string(), source));
} catch (const parsing_error& error) {
cerr << error.errorLog() << endl;
throw std::runtime_error("could not load content package");
}
string id;
string version;
root->str("id", id);
root->str("version", version);
cout << " id: " << id << endl;
cout << " version: " << version << endl;
json::JArray* blocksarr = root->arr("blocks"); json::JArray* blocksarr = root->arr("blocks");
if (blocksarr) { if (blocksarr) {
cout << " blocks: " << blocksarr->size() << endl;
for (uint i = 0; i < blocksarr->size(); i++) { for (uint i = 0; i < blocksarr->size(); i++) {
string name = blocksarr->str(i); std::string name = blocksarr->str(i);
cout << " loading block " << id << ":" << name << endl; fs::path blockfile = folder/fs::path("blocks/"+name+".json");
path blockfile = folder/path("blocks/"+name+".json"); builder->add(loadBlock(pack->id+":"+name, blockfile));
builder->add(loadBlock(id+":"+name, blockfile));
} }
} }
} }

View File

@ -5,12 +5,13 @@
#include <filesystem> #include <filesystem>
class Block; class Block;
class ContentPack;
class ContentBuilder; class ContentBuilder;
class ContentLoader { class ContentLoader {
std::filesystem::path folder; const ContentPack* pack;
public: public:
ContentLoader(std::filesystem::path folder); ContentLoader(const ContentPack* pack);
Block* loadBlock(std::string name, std::filesystem::path file); Block* loadBlock(std::string name, std::filesystem::path file);
void load(ContentBuilder* builder); void load(ContentBuilder* builder);

View File

@ -1 +1,46 @@
#include "ContentPack.h" #include "ContentPack.h"
#include <stdexcept>
#include "../files/files.h"
#include "../coders/json.h"
namespace fs = std::filesystem;
const std::string ContentPack::PACKAGE_FILENAME = "package.json";
const std::string ContentPack::CONTENT_FILENAME = "content.json";
std::filesystem::path ContentPack::getContentFile() const {
return folder/fs::path(CONTENT_FILENAME);
}
bool ContentPack::is_pack(std::filesystem::path folder) {
return fs::is_regular_file(folder/fs::path(PACKAGE_FILENAME));
}
ContentPack ContentPack::read(std::filesystem::path folder) {
auto root = files::read_json(folder/fs::path(PACKAGE_FILENAME));
ContentPack pack;
root->str("id", pack.id);
root->str("title", pack.title);
root->str("version", pack.version);
pack.folder = folder;
if (pack.id == "none")
throw std::runtime_error("content-pack id is none: "+folder.u8string());
return pack;
}
void ContentPack::scan(fs::path rootfolder,
std::vector<ContentPack>& packs) {
if (!fs::is_directory(rootfolder)) {
return;
}
for (auto entry : fs::directory_iterator(rootfolder)) {
fs::path folder = entry.path();
if (!fs::is_directory(folder))
continue;
if (!is_pack(folder))
continue;
packs.push_back(read(folder));
}
}

View File

@ -2,11 +2,23 @@
#define CONTENT_CONTENT_PACK_H_ #define CONTENT_CONTENT_PACK_H_
#include <string> #include <string>
#include <vector>
#include <filesystem> #include <filesystem>
struct ContentPack { struct ContentPack {
std::string id; std::string id = "none";
std::string title = "untitled";
std::string version = "0.0";
std::filesystem::path folder; std::filesystem::path folder;
std::filesystem::path getContentFile() const;
static const std::string PACKAGE_FILENAME;
static const std::string CONTENT_FILENAME;
static bool is_pack(std::filesystem::path folder);
static ContentPack read(std::filesystem::path folder);
static void scan(std::filesystem::path folder,
std::vector<ContentPack>& packs);
}; };
#endif // CONTENT_CONTENT_PACK_H_ #endif // CONTENT_CONTENT_PACK_H_

View File

@ -51,7 +51,7 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths)
} }
auto resdir = paths->getResources(); auto resdir = paths->getResources();
contentPacks.push_back({"base", resdir/path("content/base")}); contentPacks.push_back(ContentPack::read(resdir/path("content/base")));
loadContent(); loadContent();
Audio::initialize(); Audio::initialize();
@ -160,7 +160,7 @@ void Engine::loadContent() {
vector<path> resRoots; vector<path> resRoots;
for (auto& pack : contentPacks) { for (auto& pack : contentPacks) {
ContentLoader loader(pack.folder); ContentLoader loader(&pack);
loader.load(&contentBuilder); loader.load(&contentBuilder);
resRoots.push_back(pack.folder); resRoots.push_back(pack.folder);
} }

View File

@ -44,6 +44,7 @@ Panel* create_controls_panel(Engine* engine, PagesControl* menu);
Panel* create_settings_panel(Engine* engine, PagesControl* menu); Panel* create_settings_panel(Engine* engine, PagesControl* menu);
Panel* create_pause_panel(Engine* engine, PagesControl* menu); Panel* create_pause_panel(Engine* engine, PagesControl* menu);
Panel* create_languages_panel(Engine* engine, PagesControl* menu); Panel* create_languages_panel(Engine* engine, PagesControl* menu);
Panel* create_content_panel(Engine* engine, PagesControl* menu);
void menus::create_menus(Engine* engine, PagesControl* menu) { void menus::create_menus(Engine* engine, PagesControl* menu) {
menu->add("new-world", create_new_world_panel(engine, menu)); menu->add("new-world", create_new_world_panel(engine, menu));
@ -51,6 +52,7 @@ void menus::create_menus(Engine* engine, PagesControl* menu) {
menu->add("controls", create_controls_panel(engine, menu)); menu->add("controls", create_controls_panel(engine, menu));
menu->add("pause", create_pause_panel(engine, menu)); menu->add("pause", create_pause_panel(engine, menu));
menu->add("languages", create_languages_panel(engine, menu)); menu->add("languages", create_languages_panel(engine, menu));
menu->add("content", create_content_panel(engine, menu));
menu->add("main", create_main_menu_panel(engine, menu)); menu->add("main", create_main_menu_panel(engine, menu));
} }
@ -91,7 +93,6 @@ void show_content_missing(GUI* gui, const Content* content, ContentLUT* lut) {
panel->add((new Button(langs::get(L"Back to Main Menu", L"menu"), vec4(8.0f)))->listenAction([=](GUI*){ panel->add((new Button(langs::get(L"Back to Main Menu", L"menu"), vec4(8.0f)))->listenAction([=](GUI*){
menu->back(); menu->back();
})); }));
panel->refresh();
menu->add("missing-content", panel); menu->add("missing-content", panel);
menu->set("missing-content"); menu->set("missing-content");
} }
@ -132,7 +133,6 @@ Panel* create_languages_panel(Engine* engine, PagesControl* menu) {
panel->add(button); panel->add(button);
} }
panel->add(guiutil::backButton(menu)); panel->add(guiutil::backButton(menu));
panel->refresh();
return panel; return panel;
} }
@ -181,10 +181,20 @@ Panel* create_main_menu_panel(Engine* engine, PagesControl* menu) {
} }
panel->add(worldsPanel); panel->add(worldsPanel);
panel->add(guiutil::gotoButton(langs::get(L"Settings", L"menu"), "settings", menu)); panel->add(guiutil::gotoButton(langs::get(L"Settings", L"menu"), "settings", menu));
panel->add(guiutil::gotoButton(langs::get(L"Content", L"menu"), "content", menu));
panel->add((new Button(langs::get(L"Quit", L"menu"), vec4(10.f)))->listenAction([](GUI* gui) { panel->add((new Button(langs::get(L"Quit", L"menu"), vec4(10.f)))->listenAction([](GUI* gui) {
Window::setShouldClose(true); Window::setShouldClose(true);
})); }));
panel->refresh(); return panel;
}
Panel* create_content_panel(Engine* engine, PagesControl* menu) {
Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 5.0f);
panel->color(vec4(0.0f));
panel->add(new Label(L"work in progress"));
panel->add(guiutil::backButton(menu));
return panel; return panel;
} }
@ -271,7 +281,6 @@ Panel* create_new_world_panel(Engine* engine, PagesControl* menu) {
} }
panel->add(guiutil::backButton(menu)); panel->add(guiutil::backButton(menu));
panel->refresh();
return panel; return panel;
} }
@ -315,9 +324,7 @@ Panel* create_controls_panel(Engine* engine, PagesControl* menu) {
scrollPanel->add(subpanel); scrollPanel->add(subpanel);
} }
panel->add(scrollPanel); panel->add(scrollPanel);
panel->add(guiutil::backButton(menu)); panel->add(guiutil::backButton(menu));
panel->refresh();
return panel; return panel;
} }
@ -439,7 +446,6 @@ Panel* create_settings_panel(Engine* engine, PagesControl* menu) {
panel->add(guiutil::gotoButton(langs::get(L"Controls", L"menu"), "controls", menu)); panel->add(guiutil::gotoButton(langs::get(L"Controls", L"menu"), "controls", menu));
panel->add(guiutil::backButton(menu)); panel->add(guiutil::backButton(menu));
panel->refresh();
return panel; return panel;
} }

View File

@ -34,8 +34,8 @@ int main(int argc, char** argv) {
toml::Reader reader(wrapper.get(), settings_file.string(), text); toml::Reader reader(wrapper.get(), settings_file.string(), text);
reader.read(); reader.read();
} }
Engine engine(settings, &paths);
setup_bindings(); setup_bindings();
Engine engine(settings, &paths);
if (std::filesystem::is_regular_file(controls_file)) { if (std::filesystem::is_regular_file(controls_file)) {
std::cout << "-- loading controls" << std::endl; std::cout << "-- loading controls" << std::endl;
std::string text = files::read_string(controls_file); std::string text = files::read_string(controls_file);