inventory reindexing

This commit is contained in:
MihailRis 2024-01-26 15:35:23 +03:00
parent 1409df4b86
commit 51ffb93230
12 changed files with 174 additions and 51 deletions

View File

@ -24,6 +24,8 @@ constexpr int CHUNK_VOL = (CHUNK_W * CHUNK_H * CHUNK_D);
/* BLOCK_VOID is block id used to mark non-existing voxel (voxel of missing chunk) */
const blockid_t BLOCK_VOID = std::numeric_limits<blockid_t>::max();
const itemid_t ITEM_VOID = std::numeric_limits<itemid_t>::max();
const blockid_t MAX_BLOCKS = BLOCK_VOID;
inline uint vox_index(int x, int y, int z, int w=CHUNK_W, int d=CHUNK_D) {

View File

@ -7,10 +7,11 @@
#include "../files/files.h"
#include "../coders/json.h"
#include "../voxels/Block.h"
#include "../items/ItemDef.h"
#include "../data/dynamic.h"
ContentLUT::ContentLUT(size_t blocksCount, const Content* content) {
ContentLUT::ContentLUT(const Content* content, size_t blocksCount, size_t itemsCount) {
auto* indices = content->getIndices();
for (size_t i = 0; i < blocksCount; i++) {
blocks.push_back(i);
@ -18,23 +19,37 @@ ContentLUT::ContentLUT(size_t blocksCount, const Content* content) {
for (size_t i = 0; i < indices->countBlockDefs(); i++) {
blockNames.push_back(indices->getBlockDef(i)->name);
}
for (size_t i = indices->countBlockDefs(); i < blocksCount; i++) {
blockNames.push_back("");
}
for (size_t i = 0; i < itemsCount; i++) {
items.push_back(i);
}
for (size_t i = 0; i < indices->countItemDefs(); i++) {
itemNames.push_back(indices->getItemDef(i)->name);
}
for (size_t i = indices->countItemDefs(); i < itemsCount; i++) {
itemNames.push_back("");
}
}
ContentLUT* ContentLUT::create(const fs::path& filename,
const Content* content) {
auto root = files::read_json(filename);
auto blocklist = root->list("blocks");
auto itemlist = root->list("items");
auto* indices = content->getIndices();
size_t blocks_c = blocklist
? std::max(blocklist->size(), indices->countBlockDefs())
: indices->countBlockDefs();
auto lut = std::make_unique<ContentLUT>(blocks_c, content);
size_t items_c = itemlist
? std::max(itemlist->size(), indices->countItemDefs())
: indices->countItemDefs();
auto lut = std::make_unique<ContentLUT>(content, blocks_c, items_c);
if (blocklist) {
for (size_t i = 0; i < blocklist->size(); i++) {
std::string name = blocklist->str(i);
@ -46,6 +61,19 @@ ContentLUT* ContentLUT::create(const fs::path& filename,
}
}
}
if (itemlist) {
for (size_t i = 0; i < itemlist->size(); i++) {
std::string name = itemlist->str(i);
ItemDef* def = content->findItem(name);
if (def) {
lut->setItem(i, name, def->rt.id);
} else {
lut->setItem(i, name, ITEM_VOID);
}
}
}
if (lut->hasContentReorder() || lut->hasMissingContent()) {
return lut.release();
} else {

View File

@ -12,6 +12,8 @@ namespace fs = std::filesystem;
class Content;
// TODO: make it unified for all types of content
/* Content indices lookup table or report
used to convert world with different indices
Building with indices.json */
@ -19,10 +21,13 @@ 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(size_t blocks, const Content* content);
ContentLUT(const Content* content, size_t blocks, size_t items);
inline const std::string& getBlockName(blockid_t index) const {
return blockNames[index];
@ -42,8 +47,28 @@ public:
}
}
static ContentLUT* create(const fs::path& filename,
const Content* content);
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] = name;
if (id == ITEM_VOID) {
missingContent = true;
} else if (index != id) {
reorderContent = true;
}
}
static ContentLUT* create(
const fs::path& filename,
const Content* content
);
inline bool hasContentReorder() const {
return reorderContent;
@ -55,6 +80,10 @@ public:
inline size_t countBlocks() const {
return blocks.size();
}
inline size_t countItems() const {
return items.size();
}
};
#endif // CONTENT_CONTENT_LUT_H_

View File

@ -246,11 +246,9 @@ Map& Map::put(std::string key, int value) {
}
Map& Map::put(std::string key, int64_t value) {
auto found = values.find(key);
if (found != values.end()) found->second;
valvalue val;
val.integer = value;
values.insert(std::make_pair(key, new Value(valtype::integer, val)));
values[key] = std::make_unique<Value>(valtype::integer, val);
return *this;
}
@ -265,14 +263,14 @@ Map& Map::put(std::string key, float value) {
Map& Map::put(std::string key, double value) {
valvalue val;
val.decimal = value;
values.insert(std::make_pair(key, new Value(valtype::number, val)));
values[key] = std::make_unique<Value>(valtype::number, val);
return *this;
}
Map& Map::put(std::string key, std::string value){
valvalue val;
val.str = new std::string(value);
values.insert(std::make_pair(key, new Value(valtype::string, val)));
values[key] = std::make_unique<Value>(valtype::string, val);
return *this;
}
@ -283,21 +281,21 @@ Map& Map::put(std::string key, const char* value) {
Map& Map::put(std::string key, Map* value){
valvalue val;
val.map = value;
values.insert(std::make_pair(key, new Value(valtype::map, val)));
values[key] = std::make_unique<Value>(valtype::map, val);
return *this;
}
Map& Map::put(std::string key, List* value){
valvalue val;
val.list = value;
values.insert(std::make_pair(key, new Value(valtype::list, val)));
values[key] = std::make_unique<Value>(valtype::list, val);
return *this;
}
Map& Map::put(std::string key, bool value){
valvalue val;
val.boolean = value;
values.insert(std::make_pair(key, new Value(valtype::boolean, val)));
values[key] = std::make_unique<Value>(valtype::boolean, val);
return *this;
}

View File

@ -4,8 +4,12 @@
#include <iostream>
#include <stdexcept>
#include "WorldFiles.h"
#include "../data/dynamic.h"
#include "../files/files.h"
#include "../voxels/Chunk.h"
#include "../content/ContentLUT.h"
#include "../objects/Player.h"
namespace fs = std::filesystem;
@ -21,8 +25,9 @@ WorldConverter::WorldConverter(fs::path folder,
std::cerr << "nothing to convert" << std::endl;
return;
}
tasks.push(convert_task {convert_task_type::player, wfile->getPlayerFile()});
for (auto file : fs::directory_iterator(regionsFolder)) {
regions.push(file.path());
tasks.push(convert_task {convert_task_type::region, file.path()});
}
}
@ -31,19 +36,12 @@ WorldConverter::~WorldConverter() {
}
bool WorldConverter::hasNext() const {
return !regions.empty();
return !tasks.empty();
}
void WorldConverter::convertNext() {
if (!hasNext()) {
throw std::runtime_error("no more regions to convert");
}
fs::path regfile = regions.front();
regions.pop();
if (!fs::is_regular_file(regfile))
return;
void WorldConverter::convertRegion(fs::path file) {
int x, z;
std::string name = regfile.stem().string();
std::string name = file.stem().string();
if (!WorldFiles::parseRegionFilename(name, x, z)) {
std::cerr << "could not parse name " << name << std::endl;
return;
@ -64,6 +62,32 @@ void WorldConverter::convertNext() {
}
}
void WorldConverter::convertPlayer(fs::path file) {
std::cout << "converting player " << file.u8string() << std::endl;
auto map = files::read_json(file);
Player::convert(map.get(), lut.get());
files::write_json(file, map.get());
}
void WorldConverter::convertNext() {
if (!hasNext()) {
throw std::runtime_error("no more regions to convert");
}
convert_task task = tasks.front();
tasks.pop();
if (!fs::is_regular_file(task.file))
return;
switch (task.type) {
case convert_task_type::region:
convertRegion(task.file);
break;
case convert_task_type::player:
convertPlayer(task.file);
break;
}
}
void WorldConverter::write() {
std::cout << "writing world" << std::endl;
wfile->write(nullptr, content);

View File

@ -11,11 +11,23 @@ class Content;
class ContentLUT;
class WorldFiles;
enum class convert_task_type {
region, player
};
struct convert_task {
convert_task_type type;
fs::path file;
};
class WorldConverter {
WorldFiles* wfile;
std::shared_ptr<ContentLUT> const lut;
const Content* const content;
std::queue<fs::path> regions;
std::queue<convert_task> tasks;
void convertPlayer(fs::path file);
void convertRegion(fs::path file);
public:
WorldConverter(fs::path folder, const Content* content,
std::shared_ptr<ContentLUT> lut);

View File

@ -531,29 +531,7 @@ bool WorldFiles::readWorldInfo(World* world) {
}
void WorldFiles::writePlayer(Player* player) {
glm::vec3 position = player->hitbox->position;
dynamic::Map root;
auto& posarr = root.putList("position");
posarr.put(position.x);
posarr.put(position.y);
posarr.put(position.z);
auto& rotarr = root.putList("rotation");
rotarr.put(player->cam.x);
rotarr.put(player->cam.y);
auto& sparr = root.putList("spawnpoint");
glm::vec3 spawnpoint = player->getSpawnPoint();
sparr.put(spawnpoint.x);
sparr.put(spawnpoint.y);
sparr.put(spawnpoint.z);
root.put("flight", player->flight);
root.put("noclip", player->noclip);
root.put("chosen-slot", player->getChosenSlot());
root.put("inventory", player->getInventory()->write().release());
files::write_json(getPlayerFile(), &root);
files::write_json(getPlayerFile(), player->write().release());
}
bool WorldFiles::readPlayer(Player* player) {

View File

@ -76,7 +76,6 @@ class WorldFiles {
void writeWorldInfo(const World* world);
fs::path getLightsFolder() const;
fs::path getRegionFilename(int x, int y) const;
fs::path getPlayerFile() const;
fs::path getWorldFile() const;
fs::path getIndicesFile() const;
fs::path getPacksFile() const;
@ -114,6 +113,7 @@ class WorldFiles {
public:
static bool parseRegionFilename(const std::string& name, int& x, int& y);
fs::path getRegionsFolder() const;
fs::path getPlayerFile() const;
regionsmap regions;
regionsmap lights;

View File

@ -1,5 +1,7 @@
#include "Inventory.h"
#include "../content/ContentLUT.h"
Inventory::Inventory(size_t size) : slots(size) {
}
@ -71,4 +73,13 @@ std::unique_ptr<dynamic::Map> Inventory::write() const {
return map;
}
void Inventory::convert(dynamic::Map* data, const ContentLUT* lut) {
auto slotsarr = data->list("slots");
for (size_t i = 0; i < slotsarr->size(); i++) {
auto item = slotsarr->map(i);
itemid_t id = item->getInt("id", ITEM_EMPTY);
item->put("id", lut->getItemId(id));
}
}
const size_t Inventory::npos = -1;

View File

@ -9,6 +9,7 @@
#include "../typedefs.h"
#include "../data/dynamic.h"
class ContentLUT;
class ContentIndices;
// TODO: items indices fix
@ -36,6 +37,8 @@ public:
/* serializing inventory */
std::unique_ptr<dynamic::Map> write() const;
static void convert(dynamic::Map* data, const ContentLUT* lut);
static const size_t npos;
};

View File

@ -1,4 +1,5 @@
#include "Player.h"
#include "../content/ContentLUT.h"
#include "../physics/Hitbox.h"
#include "../physics/PhysicsSolver.h"
#include "../voxels/Chunks.h"
@ -167,3 +168,34 @@ void Player::setSpawnPoint(glm::vec3 spawnpoint) {
glm::vec3 Player::getSpawnPoint() const {
return spawnpoint;
}
std::unique_ptr<dynamic::Map> Player::write() const {
glm::vec3 position = hitbox->position;
auto root = std::make_unique<dynamic::Map>();
auto& posarr = root->putList("position");
posarr.put(position.x);
posarr.put(position.y);
posarr.put(position.z);
auto& rotarr = root->putList("rotation");
rotarr.put(cam.x);
rotarr.put(cam.y);
auto& sparr = root->putList("spawnpoint");
sparr.put(spawnpoint.x);
sparr.put(spawnpoint.y);
sparr.put(spawnpoint.z);
root->put("flight", flight);
root->put("noclip", noclip);
root->put("chosen-slot", chosenSlot);
root->put("inventory", inventory->write().release());
return root;
}
void Player::convert(dynamic::Map* data, const ContentLUT* lut) {
auto inventory = data->map("inventory");
if (inventory) {
Inventory::convert(inventory, lut);
}
}

View File

@ -4,12 +4,14 @@
#include <memory>
#include <glm/glm.hpp>
#include "../data/dynamic.h"
#include "../voxels/voxel.h"
#include "../settings.h"
class Camera;
class Hitbox;
class Inventory;
class ContentLUT;
class PhysicsSolver;
class Chunks;
class Level;
@ -62,6 +64,10 @@ public:
void setSpawnPoint(glm::vec3 point);
glm::vec3 getSpawnPoint() const;
std::unique_ptr<dynamic::Map> write() const;
static void convert(dynamic::Map* data, const ContentLUT* lut);
};
#endif /* SRC_OBJECTS_PLAYER_H_ */