diff --git a/src/content/ContentLUT.cpp b/src/content/ContentLUT.cpp index 3b0ad1f5..53245444 100644 --- a/src/content/ContentLUT.cpp +++ b/src/content/ContentLUT.cpp @@ -6,43 +6,12 @@ #include "../coders/json.hpp" #include "../voxels/Block.hpp" #include "../items/ItemDef.hpp" -#include "../data/dynamic.hpp" - #include -template -static void init(std::vector& ids, std::vector& names, - const ContentUnitIndices& indices, size_t count) { - for (size_t i = 0; i < count; i++) { - ids.push_back(i); - } - for (size_t i = 0; i < indices.count(); i++) { - names.push_back(indices.get(i)->name); - } - for (size_t i = indices.count(); i < count; i++) { - names.emplace_back(""); - } -} - -ContentLUT::ContentLUT(const Content* content, size_t blocksCount, size_t itemsCount) { - auto* indices = content->getIndices(); - init(blocks, blockNames, indices->blocks, blocksCount); - init(items, itemNames, indices->items, itemsCount); -} - -template -static void setup_lut(ContentLUT* lut, const ContentUnitDefs& defs, dynamic::List* list) { - if (list) { - for (size_t i = 0; i < list->size(); i++) { - std::string name = list->str(i); - if (auto def = defs.find(name)) { - lut->setBlock(i, name, def->rt.id); - } else { - lut->setBlock(i, name, BLOCK_VOID); - } - } - } -} +ContentLUT::ContentLUT(const ContentIndices* indices, size_t blocksCount, size_t itemsCount) + : blocks(blocksCount, indices->blocks, BLOCK_VOID, contenttype::block), + items(itemsCount, indices->items, ITEM_VOID, contenttype::item) +{} template static constexpr size_t get_entries_count( const ContentUnitIndices& indices, dynamic::List* list) { @@ -61,10 +30,10 @@ std::shared_ptr ContentLUT::create( size_t blocks_c = get_entries_count(indices->blocks, blocklist); size_t items_c = get_entries_count(indices->items, itemlist); - auto lut = std::make_shared(content, blocks_c, items_c); + auto lut = std::make_shared(indices, blocks_c, items_c); - setup_lut(lut.get(), content->blocks, blocklist); - setup_lut(lut.get(), content->items, itemlist); + lut->blocks.setup(blocklist, content->blocks); + lut->items.setup(itemlist, content->items); if (lut->hasContentReorder() || lut->hasMissingContent()) { return lut; @@ -75,17 +44,7 @@ std::shared_ptr ContentLUT::create( std::vector ContentLUT::getMissingContent() const { std::vector entries; - for (size_t i = 0; i < blocks.size(); i++) { - if (blocks[i] == BLOCK_VOID) { - auto& name = blockNames[i]; - entries.push_back(contententry {contenttype::block, name}); - } - } - for (size_t i = 0; i < items.size(); i++) { - if (items[i] == ITEM_VOID) { - auto& name = itemNames[i]; - entries.push_back(contententry {contenttype::item, name}); - } - } + blocks.getMissingContent(entries); + items.getMissingContent(entries); return entries; } diff --git a/src/content/ContentLUT.hpp b/src/content/ContentLUT.hpp index f7c8a799..baf347d7 100644 --- a/src/content/ContentLUT.hpp +++ b/src/content/ContentLUT.hpp @@ -5,6 +5,7 @@ #include "../typedefs.hpp" #include "../constants.hpp" +#include "../data/dynamic.hpp" #include #include @@ -18,58 +19,82 @@ struct contententry { std::string name; }; -// TODO: make it unified for all types of content +template +class ContentUnitLUT { + std::vector indices; + std::vector names; + bool missingContent = false; + bool reorderContent = false; + T missingValue; + contenttype type; +public: + ContentUnitLUT(size_t count, const ContentUnitIndices& unitIndices, T missingValue, contenttype type) + : missingValue(missingValue), type(type) { + for (size_t i = 0; i < count; i++) { + indices.push_back(i); + } + for (size_t i = 0; i < unitIndices.count(); i++) { + names.push_back(unitIndices.get(i)->name); + } + for (size_t i = unitIndices.count(); i < count; i++) { + names.emplace_back(""); + } + } + void setup(dynamic::List* list, const ContentUnitDefs& defs) { + if (list) { + for (size_t i = 0; i < list->size(); i++) { + std::string name = list->str(i); + if (auto def = defs.find(name)) { + set(i, name, def->rt.id); + } else { + set(i, name, missingValue); + } + } + } + } + void getMissingContent(std::vector& entries) const { + for (size_t i = 0; i < count(); i++) { + if (indices[i] == missingValue) { + auto& name = names[i]; + entries.push_back(contententry {type, name}); + } + } + } + inline const std::string& getName(T index) const { + return names[index]; + } + inline T getId(T index) const { + return indices[index]; + } + inline void set(T index, std::string name, T id) { + indices[index] = id; + names[index] = std::move(name); + if (id == missingValue) { + missingContent = true; + } else if (index != id) { + reorderContent = true; + } + } + inline size_t count() const { + return indices.size(); + } + inline bool hasContentReorder() const { + return reorderContent; + } + inline bool hasMissingContent() const { + return missingContent; + } +}; /// @brief Content indices lookup table or report /// used to convert world with different indices /// Building with indices.json class ContentLUT { - std::vector blocks; - std::vector blockNames; - - std::vector items; - std::vector itemNames; - - bool reorderContent = false; - bool missingContent = false; public: - ContentLUT(const Content* content, size_t blocks, size_t items); + ContentUnitLUT blocks; + ContentUnitLUT items; - inline const std::string& getBlockName(blockid_t index) const { - return blockNames[index]; - } - - inline blockid_t getBlockId(blockid_t index) const { - return blocks[index]; - } - - inline void setBlock(blockid_t index, std::string name, blockid_t id) { - blocks[index] = id; - blockNames[index] = std::move(name); - if (id == BLOCK_VOID) { - missingContent = true; - } else if (index != id) { - reorderContent = true; - } - } - - inline const std::string& getItemName(blockid_t index) const { - return itemNames[index]; - } - - inline itemid_t getItemId(itemid_t index) const { - return items[index]; - } - - inline void setItem(itemid_t index, std::string name, itemid_t id) { - items[index] = id; - itemNames[index] = std::move(name); - if (id == ITEM_VOID) { - missingContent = true; - } else if (index != id) { - reorderContent = true; - } - } + ContentLUT(const ContentIndices* indices, size_t blocks, size_t items); static std::shared_ptr create( const fs::path& filename, @@ -77,18 +102,10 @@ public: ); inline bool hasContentReorder() const { - return reorderContent; + return blocks.hasContentReorder() || items.hasContentReorder(); } inline bool hasMissingContent() const { - return missingContent; - } - - inline size_t countBlocks() const { - return blocks.size(); - } - - inline size_t countItems() const { - return items.size(); + return blocks.hasMissingContent() || items.hasMissingContent(); } std::vector getMissingContent() const; diff --git a/src/items/Inventory.cpp b/src/items/Inventory.cpp index e09dad45..8361f63d 100644 --- a/src/items/Inventory.cpp +++ b/src/items/Inventory.cpp @@ -89,7 +89,7 @@ void Inventory::convert(dynamic::Map* data, const ContentLUT* lut) { for (size_t i = 0; i < slotsarr->size(); i++) { auto item = slotsarr->map(i); itemid_t id = item->get("id", ITEM_EMPTY); - itemid_t replacement = lut->getItemId(id); + itemid_t replacement = lut->items.getId(id); item->put("id", replacement); if (replacement == 0 && item->has("count")) { item->remove("count"); diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp new file mode 100644 index 00000000..06510099 --- /dev/null +++ b/src/objects/EntityDef.hpp @@ -0,0 +1,16 @@ +#ifndef OBJECTS_ENTITY_DEF_HPP_ +#define OBJECTS_ENTITY_DEF_HPP_ + +#include + +#include "../typedefs.hpp" + +struct EntityDef { + /// @brief Entity string id (with prefix included) + std::string const name; + + EntityDef(const std::string& name); + EntityDef(const EntityDef&) = delete; +}; + +#endif // OBJECTS_ENTITY_DEF_HPP_ diff --git a/src/voxels/Chunk.cpp b/src/voxels/Chunk.cpp index be8238c6..bd6dc0bc 100644 --- a/src/voxels/Chunk.cpp +++ b/src/voxels/Chunk.cpp @@ -127,7 +127,7 @@ void Chunk::convert(ubyte* data, const ContentLUT* lut) { // see encode method to understand what the hell is going on here blockid_t id = ((static_cast(data[i]) << 8) | static_cast(data[CHUNK_VOL+i])); - blockid_t replacement = lut->getBlockId(id); + blockid_t replacement = lut->blocks.getId(id); data[i] = replacement >> 8; data[CHUNK_VOL+i] = replacement & 0xFF; }