Content packs structure update
This commit is contained in:
parent
04f06a4717
commit
924957ddee
28
res/content/base/content.json
Normal file
28
res/content/base/content.json
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -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"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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=Создать Мир
|
||||||
|
|||||||
@ -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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -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_
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user