ItemDef/EntityDef/Block: Add method cloneTo to definition to other definition

ContentBuilder: Add method `get` to get definition or nullptr
ContentLoader: Add functionality to clone from definition specified in `parent` field in json
This commit is contained in:
REDxEYE 2024-08-20 21:58:01 +03:00
parent 8ef288c189
commit 5f6ae5daba
9 changed files with 123 additions and 13 deletions

View File

@ -44,6 +44,14 @@ public:
defs[id] = std::make_unique<T>(id);
return *defs[id];
}
// Only fetch existing definition, return null otherwise.
T* get(const std::string& id) {
auto found = defs.find(id);
if (found != defs.end()) {
return &*found->second;
}
return nullptr;
}
auto build() {
return std::move(defs);

View File

@ -6,6 +6,9 @@
#include <memory>
#include <string>
#include "Content.hpp"
#include "ContentBuilder.hpp"
#include "ContentPack.hpp"
#include "coders/json.hpp"
#include "core_defs.hpp"
#include "data/dynamic.hpp"
@ -18,9 +21,6 @@
#include "util/listutil.hpp"
#include "util/stringutil.hpp"
#include "voxels/Block.hpp"
#include "Content.hpp"
#include "ContentBuilder.hpp"
#include "ContentPack.hpp"
namespace fs = std::filesystem;
@ -123,6 +123,18 @@ void ContentLoader::loadBlock(
) {
auto root = files::read_json(file);
if (root->has("parent")) {
std::string parentName;
root->str("parent", parentName);
auto parentDef = this->builder.blocks.get(parentName);
if (parentDef == nullptr) {
throw std::runtime_error(
"Failed to find parent(" + parentName + ") for " + name
);
}
parentDef->cloneTo(def);
}
root->str("caption", def.caption);
// block texturing
@ -289,6 +301,19 @@ void ContentLoader::loadItem(
ItemDef& def, const std::string& name, const fs::path& file
) {
auto root = files::read_json(file);
if (root->has("parent")) {
std::string parentName;
root->str("parent", parentName);
auto parentDef = this->builder.items.get(parentName);
if (parentDef == nullptr) {
throw std::runtime_error(
"Failed to find parent(" + parentName + ") for " + name
);
}
parentDef->cloneTo(def);
}
root->str("caption", def.caption);
std::string iconTypeStr = "";
@ -319,6 +344,19 @@ void ContentLoader::loadEntity(
EntityDef& def, const std::string& name, const fs::path& file
) {
auto root = files::read_json(file);
if (root->has("parent")) {
std::string parentName;
root->str("parent", parentName);
auto parentDef = this->builder.entities.get(parentName);
if (parentDef == nullptr) {
throw std::runtime_error(
"Failed to find parent(" + parentName + ") for " + name
);
}
parentDef->cloneTo(def);
}
if (auto componentsarr = root->list("components")) {
for (size_t i = 0; i < componentsarr->size(); i++) {
def.components.emplace_back(componentsarr->str(i));
@ -340,7 +378,8 @@ void ContentLoader::loadEntity(
sensorarr->num(3)},
{sensorarr->num(4),
sensorarr->num(5),
sensorarr->num(6)}}
sensorarr->num(6)}
}
);
} else if (sensorType == "radius") {
def.radialSensors.emplace_back(i, sensorarr->num(1));

View File

@ -42,13 +42,13 @@ class ContentLoader {
static void loadCustomBlockModel(Block& def, dynamic::Map* primitives);
static void loadBlockMaterial(BlockMaterial& def, const fs::path& file);
static void loadBlock(
void loadBlock(
Block& def, const std::string& name, const fs::path& file
);
static void loadItem(
void loadItem(
ItemDef& def, const std::string& name, const fs::path& file
);
static void loadEntity(
void loadEntity(
EntityDef& def, const std::string& name, const fs::path& file
);
void loadResources(ResourceType type, dynamic::List* list);

View File

@ -5,3 +5,13 @@
ItemDef::ItemDef(const std::string& name) : name(name) {
caption = util::id_to_caption(name);
}
void ItemDef::cloneTo(ItemDef& dst) {
dst.caption = caption;
dst.stackSize = stackSize;
dst.generated = generated;
std::copy(&emission[0], &emission[3], dst.emission);
dst.iconType = iconType;
dst.icon = icon;
dst.placingBlock = placingBlock;
dst.scriptName = scriptName;
}

View File

@ -44,4 +44,5 @@ struct ItemDef {
ItemDef(const std::string& name);
ItemDef(const ItemDef&) = delete;
void cloneTo(ItemDef& dst);
};

12
src/objects/EntityDef.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "EntityDef.hpp"
void EntityDef::cloneTo(EntityDef& dst) {
dst.components = components;
dst.bodyType = bodyType;
dst.hitbox = hitbox;
dst.boxSensors = boxSensors;
dst.radialSensors = radialSensors;
dst.skeletonName = skeletonName;
dst.blocking = blocking;
dst.save = save;
}

View File

@ -24,12 +24,12 @@ struct EntityDef {
/// @brief Hitbox size
glm::vec3 hitbox {0.25f};
/// @brief 'aabb' sensors
std::vector<std::pair<size_t, AABB>> boxSensors {};
/// @brief 'radius' sensors
std::vector<std::pair<size_t, float>> radialSensors {};
/// @brief Skeleton ID
std::string skeletonName = name;
@ -56,4 +56,6 @@ struct EntityDef {
EntityDef(const std::string& name) : name(name) {}
EntityDef(const EntityDef&) = delete;
void cloneTo(EntityDef& dst);
};

View File

@ -64,7 +64,8 @@ const BlockRotProfile BlockRotProfile::NONE {
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // West
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Up
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Down
}};
}
};
const BlockRotProfile BlockRotProfile::PIPE {
"pipe",
@ -75,7 +76,8 @@ const BlockRotProfile BlockRotProfile::PIPE {
{{0, 0, -1}, {1, 0, 0}, {0, -1, 0}}, // West
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Up
{{1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, // Down
}};
}
};
const BlockRotProfile BlockRotProfile::PANE {
"pane",
@ -84,7 +86,8 @@ const BlockRotProfile BlockRotProfile::PANE {
{{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}, // East
{{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}}, // South
{{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}}, // West
}};
}
};
Block::Block(const std::string& name)
: name(name),
@ -95,10 +98,43 @@ Block::Block(const std::string& name)
TEXTURE_NOTFOUND,
TEXTURE_NOTFOUND,
TEXTURE_NOTFOUND,
TEXTURE_NOTFOUND} {
TEXTURE_NOTFOUND
} {
}
Block::Block(std::string name, const std::string& texture)
: name(std::move(name)),
textureFaces {texture, texture, texture, texture, texture, texture} {
}
void Block::cloneTo(Block& dst) {
dst.caption = caption;
for (int i = 0; i < 6; i++) {
dst.textureFaces[i] = textureFaces[i];
}
dst.modelTextures = modelTextures;
dst.modelBoxes = modelBoxes;
dst.modelExtraPoints = modelExtraPoints;
dst.modelUVs = modelUVs;
dst.material = material;
std::copy(&emission[0], &emission[3], dst.emission);
dst.size = size;
dst.model = model;
dst.lightPassing = lightPassing;
dst.skyLightPassing = skyLightPassing;
dst.shadeless = shadeless;
dst.ambientOcclusion = ambientOcclusion;
dst.obstacle = obstacle;
dst.selectable = selectable;
dst.replaceable = replaceable;
dst.breakable = breakable;
dst.rotatable = rotatable;
dst.grounded = grounded;
dst.hidden = hidden;
dst.hitboxes = hitboxes;
dst.rotations = rotations;
dst.pickingItem = pickingItem;
dst.scriptName = scriptName;
dst.uiLayout = uiLayout;
dst.inventorySize = inventorySize;
dst.tickInterval = tickInterval;
}

View File

@ -211,6 +211,8 @@ public:
Block(const std::string& name);
Block(std::string name, const std::string& texture);
Block(const Block&) = delete;
void cloneTo(Block& dst);
};
inline glm::ivec3 get_ground_direction(const Block& def, int rotation) {