fix and refactor ContentLUT
This commit is contained in:
parent
ee9f1639e9
commit
1acced4475
@ -6,43 +6,12 @@
|
||||
#include "../coders/json.hpp"
|
||||
#include "../voxels/Block.hpp"
|
||||
#include "../items/ItemDef.hpp"
|
||||
#include "../data/dynamic.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
template<typename I, class T>
|
||||
static void init(std::vector<I>& ids, std::vector<std::string>& names,
|
||||
const ContentUnitIndices<T>& 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<class T>
|
||||
static void setup_lut(ContentLUT* lut, const ContentUnitDefs<T>& 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<class T> static constexpr size_t get_entries_count(
|
||||
const ContentUnitIndices<T>& indices, dynamic::List* list) {
|
||||
@ -61,10 +30,10 @@ std::shared_ptr<ContentLUT> 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<ContentLUT>(content, blocks_c, items_c);
|
||||
auto lut = std::make_shared<ContentLUT>(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> ContentLUT::create(
|
||||
|
||||
std::vector<contententry> ContentLUT::getMissingContent() const {
|
||||
std::vector<contententry> 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;
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
#include "../typedefs.hpp"
|
||||
#include "../constants.hpp"
|
||||
#include "../data/dynamic.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@ -18,58 +19,82 @@ struct contententry {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
// TODO: make it unified for all types of content
|
||||
template<typename T, class U>
|
||||
class ContentUnitLUT {
|
||||
std::vector<T> indices;
|
||||
std::vector<std::string> names;
|
||||
bool missingContent = false;
|
||||
bool reorderContent = false;
|
||||
T missingValue;
|
||||
contenttype type;
|
||||
public:
|
||||
ContentUnitLUT(size_t count, const ContentUnitIndices<U>& 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<U>& 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<contententry>& 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<blockid_t> blocks;
|
||||
std::vector<std::string> blockNames;
|
||||
|
||||
std::vector<itemid_t> items;
|
||||
std::vector<std::string> itemNames;
|
||||
|
||||
bool reorderContent = false;
|
||||
bool missingContent = false;
|
||||
public:
|
||||
ContentLUT(const Content* content, size_t blocks, size_t items);
|
||||
ContentUnitLUT<blockid_t, Block> blocks;
|
||||
ContentUnitLUT<itemid_t, ItemDef> 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<ContentLUT> 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<contententry> getMissingContent() const;
|
||||
|
||||
@ -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");
|
||||
|
||||
16
src/objects/EntityDef.hpp
Normal file
16
src/objects/EntityDef.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef OBJECTS_ENTITY_DEF_HPP_
|
||||
#define OBJECTS_ENTITY_DEF_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
#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_
|
||||
@ -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<blockid_t>(data[i]) << 8) |
|
||||
static_cast<blockid_t>(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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user