inventory reindexing
This commit is contained in:
parent
1409df4b86
commit
51ffb93230
@ -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) {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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_ */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user