From dd5cd55aeb8d70ff43d39b7592669a05798187ad Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 8 Jan 2024 14:16:25 +0300 Subject: [PATCH] Generated items --- src/content/Content.cpp | 29 +++++++++++++++++++++++- src/content/Content.h | 9 ++++++-- src/content/ContentLoader.cpp | 42 ++++++++++++++++++----------------- src/content/ContentLoader.h | 8 +++---- src/content/ItemDef.h | 15 ++++++++++++- 5 files changed, 75 insertions(+), 28 deletions(-) diff --git a/src/content/Content.cpp b/src/content/Content.cpp index 773a0bda..50a74cb0 100644 --- a/src/content/Content.cpp +++ b/src/content/Content.cpp @@ -10,6 +10,9 @@ using glm::vec3; using std::string; using std::unordered_map; +ContentBuilder::~ContentBuilder() { +} + void ContentBuilder::add(Block* def) { checkIdentifier(def->name); blockDefs[def->name] = def; @@ -22,10 +25,34 @@ void ContentBuilder::add(ItemDef* def) { itemIds.push_back(def->name); } +Block* ContentBuilder::createBlock(std::string id) { + auto found = blockDefs.find(id); + if (found != blockDefs.end()) { + //return found->second; + throw namereuse_error("name "+id+" is already used", contenttype::item); + } + Block* block = new Block(id); + add(block); + return block; +} + +ItemDef* ContentBuilder::createItem(std::string id) { + auto found = itemDefs.find(id); + if (found != itemDefs.end()) { + if (found->second->generated) { + return found->second; + } + throw namereuse_error("name "+id+" is already used", contenttype::item); + } + ItemDef* item = new ItemDef(id); + add(item); + return item; +} + void ContentBuilder::checkIdentifier(std::string id) { contenttype result; if ((checkContentType(id) != contenttype::none)) { - throw contentindexreuse_error("identifier "+id+" is already used", result); + throw namereuse_error("name "+id+" is already used", result); } } diff --git a/src/content/Content.h b/src/content/Content.h index 3c661582..6748dc19 100644 --- a/src/content/Content.h +++ b/src/content/Content.h @@ -18,10 +18,10 @@ enum class contenttype { none, block, item }; -class contentindexreuse_error: public std::runtime_error { +class namereuse_error: public std::runtime_error { contenttype type; public: - contentindexreuse_error(const std::string& msg, contenttype type) + namereuse_error(const std::string& msg, contenttype type) : std::runtime_error(msg), type(type) {} inline contenttype getType() const { @@ -36,9 +36,14 @@ class ContentBuilder { std::unordered_map itemDefs; std::vector itemIds; public: + ~ContentBuilder(); + void add(Block* def); void add(ItemDef* def); + Block* createBlock(std::string id); + ItemDef* createItem(std::string id); + void checkIdentifier(std::string id); contenttype checkContentType(std::string id); diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 271f2e52..ad2cd0f3 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -92,9 +92,8 @@ void ContentLoader::fixPackIndices() { } // TODO: add basic validation and logging -Block* ContentLoader::loadBlock(std::string name, fs::path file) { +void ContentLoader::loadBlock(Block* def, std::string name, fs::path file) { std::unique_ptr root(files::read_json(file)); - std::unique_ptr def(new Block(name)); // block texturing if (root->has("texture")) { @@ -176,41 +175,32 @@ Block* ContentLoader::loadBlock(std::string name, fs::path file) { root->flag("hidden", def->hidden); root->flag("sky-light-passing", def->skyLightPassing); root->num("draw-group", def->drawGroup); - - return def.release(); } -ItemDef* ContentLoader::loadItem(std::string name, std::filesystem::path file) { +void ContentLoader::loadItem(ItemDef* def, std::string name, std::filesystem::path file) { std::unique_ptr root(files::read_json(file)); - std::unique_ptr def(new ItemDef(name)); - - return def.release(); } -Block* ContentLoader::loadBlock(std::string name) { +void ContentLoader::loadBlock(Block* def, std::string full, std::string name) { auto folder = pack->folder; - std::string prefix = pack->id+":"+name; fs::path configFile = folder/fs::path("blocks/"+name+".json"); fs::path scriptfile = folder/fs::path("scripts/"+name+".lua"); - Block* def = loadBlock(prefix, configFile); + loadBlock(def, full, configFile); if (fs::is_regular_file(scriptfile)) { - scripting::load_block_script(prefix, scriptfile, &def->rt.funcsset); + scripting::load_block_script(full, scriptfile, &def->rt.funcsset); } - return def; } -ItemDef* ContentLoader::loadItem(std::string name) { +void ContentLoader::loadItem(ItemDef* def, std::string full, std::string name) { auto folder = pack->folder; - std::string prefix = pack->id+":"+name; fs::path configFile = folder/fs::path("items/"+name+".json"); fs::path scriptfile = folder/fs::path("scripts/"+name+".lua"); - ItemDef* def = loadItem(prefix, configFile); + loadItem(def, full, configFile); if (fs::is_regular_file(scriptfile)) { - scripting::load_item_script(prefix, scriptfile, &def->rt.funcsset); + scripting::load_item_script(full, scriptfile, &def->rt.funcsset); } - return def; } void ContentLoader::load(ContentBuilder* builder) { @@ -226,14 +216,26 @@ void ContentLoader::load(ContentBuilder* builder) { json::JArray* blocksarr = root->arr("blocks"); if (blocksarr) { for (uint i = 0; i < blocksarr->size(); i++) { - builder->add(loadBlock(blocksarr->str(i))); + std::string name = blocksarr->str(i); + std::string full = pack->id+":"+name; + auto def = builder->createBlock(full); + loadBlock(def, full, name); + if (!def->hidden) { + auto item = builder->createItem(full+BLOCK_ITEM_SUFFIX); + item->generated = true; + item->iconType = item_icon_type::block; + item->icon = full; + item->placingBlock = full; + } } } json::JArray* itemsarr = root->arr("items"); if (itemsarr) { for (uint i = 0; i < itemsarr->size(); i++) { - builder->add(loadItem(itemsarr->str(i))); + std::string name = itemsarr->str(i); + std::string full = pack->id+":"+name; + loadItem(builder->createItem(full), full, name); } } } diff --git a/src/content/ContentLoader.h b/src/content/ContentLoader.h index 983ce581..25b5104a 100644 --- a/src/content/ContentLoader.h +++ b/src/content/ContentLoader.h @@ -16,8 +16,8 @@ namespace json { class ContentLoader { const ContentPack* pack; - Block* loadBlock(std::string name); - ItemDef* loadItem(std::string name); + void loadBlock(Block* def, std::string full, std::string name); + void loadItem(ItemDef* def, std::string full, std::string name); public: ContentLoader(ContentPack* pack); @@ -25,8 +25,8 @@ public: json::JObject* indicesRoot, std::string contentSection); void fixPackIndices(); - Block* loadBlock(std::string name, std::filesystem::path file); - ItemDef* loadItem(std::string name, std::filesystem::path file); + void loadBlock(Block* def, std::string name, std::filesystem::path file); + void loadItem(ItemDef* def, std::string name, std::filesystem::path file); void load(ContentBuilder* builder); }; diff --git a/src/content/ItemDef.h b/src/content/ItemDef.h index 2223c1e0..75be27d6 100644 --- a/src/content/ItemDef.h +++ b/src/content/ItemDef.h @@ -6,13 +6,26 @@ #include "../typedefs.h" +#define BLOCK_ITEM_SUFFIX ".item" + struct item_funcs_set { bool init: 1; }; +enum class item_icon_type { + sprite, block, +}; + class ItemDef { public: - std::string name; + std::string const name; + + bool generated = false; + + item_icon_type iconType = item_icon_type::sprite; + std::string icon = "block:notfound"; + + std::string placingBlock = "none"; struct { itemid_t id;