Merge branch 'main' into heightmaps
This commit is contained in:
commit
f2395dede8
@ -45,6 +45,14 @@ public:
|
|||||||
defs[id] = std::make_unique<T>(id);
|
defs[id] = std::make_unique<T>(id);
|
||||||
return *defs[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() {
|
auto build() {
|
||||||
return std::move(defs);
|
return std::move(defs);
|
||||||
|
|||||||
@ -6,6 +6,9 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "Content.hpp"
|
||||||
|
#include "ContentBuilder.hpp"
|
||||||
|
#include "ContentPack.hpp"
|
||||||
#include "coders/json.hpp"
|
#include "coders/json.hpp"
|
||||||
#include "core_defs.hpp"
|
#include "core_defs.hpp"
|
||||||
#include "data/dynamic.hpp"
|
#include "data/dynamic.hpp"
|
||||||
@ -18,9 +21,6 @@
|
|||||||
#include "util/listutil.hpp"
|
#include "util/listutil.hpp"
|
||||||
#include "util/stringutil.hpp"
|
#include "util/stringutil.hpp"
|
||||||
#include "voxels/Block.hpp"
|
#include "voxels/Block.hpp"
|
||||||
#include "Content.hpp"
|
|
||||||
#include "ContentBuilder.hpp"
|
|
||||||
#include "ContentPack.hpp"
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
@ -123,6 +123,18 @@ void ContentLoader::loadBlock(
|
|||||||
) {
|
) {
|
||||||
auto root = files::read_json(file);
|
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);
|
root->str("caption", def.caption);
|
||||||
|
|
||||||
// block texturing
|
// block texturing
|
||||||
@ -289,6 +301,19 @@ void ContentLoader::loadItem(
|
|||||||
ItemDef& def, const std::string& name, const fs::path& file
|
ItemDef& def, const std::string& name, const fs::path& file
|
||||||
) {
|
) {
|
||||||
auto root = files::read_json(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);
|
root->str("caption", def.caption);
|
||||||
|
|
||||||
std::string iconTypeStr = "";
|
std::string iconTypeStr = "";
|
||||||
@ -319,6 +344,19 @@ void ContentLoader::loadEntity(
|
|||||||
EntityDef& def, const std::string& name, const fs::path& file
|
EntityDef& def, const std::string& name, const fs::path& file
|
||||||
) {
|
) {
|
||||||
auto root = files::read_json(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")) {
|
if (auto componentsarr = root->list("components")) {
|
||||||
for (size_t i = 0; i < componentsarr->size(); i++) {
|
for (size_t i = 0; i < componentsarr->size(); i++) {
|
||||||
def.components.emplace_back(componentsarr->str(i));
|
def.components.emplace_back(componentsarr->str(i));
|
||||||
@ -340,7 +378,8 @@ void ContentLoader::loadEntity(
|
|||||||
sensorarr->num(3)},
|
sensorarr->num(3)},
|
||||||
{sensorarr->num(4),
|
{sensorarr->num(4),
|
||||||
sensorarr->num(5),
|
sensorarr->num(5),
|
||||||
sensorarr->num(6)}}
|
sensorarr->num(6)}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
} else if (sensorType == "radius") {
|
} else if (sensorType == "radius") {
|
||||||
def.radialSensors.emplace_back(i, sensorarr->num(1));
|
def.radialSensors.emplace_back(i, sensorarr->num(1));
|
||||||
@ -484,45 +523,157 @@ void ContentLoader::load() {
|
|||||||
if (!fs::is_regular_file(pack->getContentFile())) return;
|
if (!fs::is_regular_file(pack->getContentFile())) return;
|
||||||
|
|
||||||
auto root = files::read_json(pack->getContentFile());
|
auto root = files::read_json(pack->getContentFile());
|
||||||
|
std::vector<std::pair<std::string, std::string>> pendingDefs;
|
||||||
|
auto getJsonParent = [this](const std::string& prefix, const std::string& name) {
|
||||||
|
auto configFile = pack->folder / fs::path(prefix + "/" + name + ".json");
|
||||||
|
std::string parent;
|
||||||
|
if (fs::exists(configFile)) {
|
||||||
|
auto root = files::read_json(configFile);
|
||||||
|
if (root->has("parent")) root->str("parent", parent);
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
};
|
||||||
|
auto processName = [this](const std::string& name) {
|
||||||
|
auto colon = name.find(':');
|
||||||
|
auto new_name = name;
|
||||||
|
std::string full =
|
||||||
|
colon == std::string::npos ? pack->id + ":" + name : name;
|
||||||
|
if (colon != std::string::npos) new_name[colon] = '/';
|
||||||
|
|
||||||
|
return std::make_pair(full, new_name);
|
||||||
|
};
|
||||||
|
|
||||||
if (auto blocksarr = root->list("blocks")) {
|
if (auto blocksarr = root->list("blocks")) {
|
||||||
for (size_t i = 0; i < blocksarr->size(); i++) {
|
for (size_t i = 0; i < blocksarr->size(); i++) {
|
||||||
std::string name = blocksarr->str(i);
|
auto [full, name] = processName(blocksarr->str(i));
|
||||||
auto [packid, full, filename] = create_unit_id(pack->id, name);
|
auto parent = getJsonParent("blocks", name);
|
||||||
|
if (parent.empty() || builder.blocks.get(parent)) {
|
||||||
auto& def = builder.blocks.create(full);
|
// No dependency or dependency already loaded/exists in another
|
||||||
if (filename != name) {
|
// content pack
|
||||||
def.scriptName = packid + "/" + def.scriptName;
|
auto& def = builder.blocks.create(full);
|
||||||
|
loadBlock(def, full, name);
|
||||||
|
stats->totalBlocks++;
|
||||||
|
} else {
|
||||||
|
// Dependency not loaded yet, add to pending items
|
||||||
|
pendingDefs.emplace_back(full, name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadBlock(def, full, filename);
|
// Resolve dependencies for pending items
|
||||||
stats->totalBlocks++;
|
bool progressMade = true;
|
||||||
|
while (!pendingDefs.empty() && progressMade) {
|
||||||
|
progressMade = false;
|
||||||
|
|
||||||
|
for (auto it = pendingDefs.begin(); it != pendingDefs.end();) {
|
||||||
|
auto parent = getJsonParent("blocks", it->second);
|
||||||
|
if (builder.blocks.get(parent)) {
|
||||||
|
// Dependency resolved or parent exists in another pack,
|
||||||
|
// load the item
|
||||||
|
auto& def = builder.blocks.create(it->first);
|
||||||
|
loadBlock(def, it->first, it->second);
|
||||||
|
stats->totalBlocks++;
|
||||||
|
it = pendingDefs.erase(it); // Remove resolved item
|
||||||
|
progressMade = true;
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pendingDefs.empty()) {
|
||||||
|
// Handle circular dependencies or missing dependencies
|
||||||
|
// You can log an error or throw an exception here if necessary
|
||||||
|
throw std::runtime_error("Unresolved block dependencies detected.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto itemsarr = root->list("items")) {
|
if (auto itemsarr = root->list("items")) {
|
||||||
for (size_t i = 0; i < itemsarr->size(); i++) {
|
for (size_t i = 0; i < itemsarr->size(); i++) {
|
||||||
std::string name = itemsarr->str(i);
|
auto [full, name] = processName(itemsarr->str(i));
|
||||||
auto [packid, full, filename] = create_unit_id(pack->id, name);
|
auto parent = getJsonParent("items", name);
|
||||||
|
if (parent.empty() || builder.items.get(parent)) {
|
||||||
auto& def = builder.items.create(full);
|
// No dependency or dependency already loaded/exists in another
|
||||||
if (filename != name) {
|
// content pack
|
||||||
def.scriptName = packid + "/" + def.scriptName;
|
auto& def = builder.items.create(full);
|
||||||
|
loadItem(def, full, name);
|
||||||
|
stats->totalItems++;
|
||||||
|
} else {
|
||||||
|
// Dependency not loaded yet, add to pending items
|
||||||
|
pendingDefs.emplace_back(full, name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadItem(def, full, filename);
|
// Resolve dependencies for pending items
|
||||||
stats->totalItems++;
|
bool progressMade = true;
|
||||||
|
while (!pendingDefs.empty() && progressMade) {
|
||||||
|
progressMade = false;
|
||||||
|
|
||||||
|
for (auto it = pendingDefs.begin(); it != pendingDefs.end();) {
|
||||||
|
auto parent = getJsonParent("items", it->second);
|
||||||
|
if (builder.items.get(parent)) {
|
||||||
|
// Dependency resolved or parent exists in another pack,
|
||||||
|
// load the item
|
||||||
|
auto& def = builder.items.create(it->first);
|
||||||
|
loadItem(def, it->first, it->second);
|
||||||
|
stats->totalItems++;
|
||||||
|
it = pendingDefs.erase(it); // Remove resolved item
|
||||||
|
progressMade = true;
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pendingDefs.empty()) {
|
||||||
|
// Handle circular dependencies or missing dependencies
|
||||||
|
// You can log an error or throw an exception here if necessary
|
||||||
|
throw std::runtime_error("Unresolved item dependencies detected.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto entitiesarr = root->list("entities")) {
|
if (auto entitiesarr = root->list("entities")) {
|
||||||
for (size_t i = 0; i < entitiesarr->size(); i++) {
|
for (size_t i = 0; i < entitiesarr->size(); i++) {
|
||||||
std::string name = entitiesarr->str(i);
|
auto [full, name] = processName(entitiesarr->str(i));
|
||||||
auto [packid, full, filename] = create_unit_id(pack->id, name);
|
auto parent = getJsonParent("entities", name);
|
||||||
|
if (parent.empty() || builder.entities.get(parent)) {
|
||||||
|
// No dependency or dependency already loaded/exists in another
|
||||||
|
// content pack
|
||||||
|
auto& def = builder.entities.create(full);
|
||||||
|
loadEntity(def, full, name);
|
||||||
|
stats->totalEntities++;
|
||||||
|
} else {
|
||||||
|
// Dependency not loaded yet, add to pending items
|
||||||
|
pendingDefs.emplace_back(full, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto& def = builder.entities.create(full);
|
// Resolve dependencies for pending items
|
||||||
|
bool progressMade = true;
|
||||||
|
while (!pendingDefs.empty() && progressMade) {
|
||||||
|
progressMade = false;
|
||||||
|
|
||||||
loadEntity(def, full, name);
|
for (auto it = pendingDefs.begin(); it != pendingDefs.end();) {
|
||||||
stats->totalEntities++;
|
auto parent = getJsonParent("entities", it->second);
|
||||||
|
if (builder.entities.get(parent)) {
|
||||||
|
// Dependency resolved or parent exists in another pack,
|
||||||
|
// load the item
|
||||||
|
auto& def = builder.entities.create(it->first);
|
||||||
|
loadEntity(def, it->first, it->second);
|
||||||
|
stats->totalEntities++;
|
||||||
|
it = pendingDefs.erase(it); // Remove resolved item
|
||||||
|
progressMade = true;
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pendingDefs.empty()) {
|
||||||
|
// Handle circular dependencies or missing dependencies
|
||||||
|
// You can log an error or throw an exception here if necessary
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Unresolved entities dependencies detected."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,13 +46,13 @@ class ContentLoader {
|
|||||||
|
|
||||||
static void loadCustomBlockModel(Block& def, dynamic::Map* primitives);
|
static void loadCustomBlockModel(Block& def, dynamic::Map* primitives);
|
||||||
static void loadBlockMaterial(BlockMaterial& def, const fs::path& file);
|
static void loadBlockMaterial(BlockMaterial& def, const fs::path& file);
|
||||||
static void loadBlock(
|
void loadBlock(
|
||||||
Block& def, const std::string& name, const fs::path& file
|
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
|
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
|
EntityDef& def, const std::string& name, const fs::path& file
|
||||||
);
|
);
|
||||||
void loadResources(ResourceType type, dynamic::List* list);
|
void loadResources(ResourceType type, dynamic::List* list);
|
||||||
|
|||||||
@ -5,3 +5,13 @@
|
|||||||
ItemDef::ItemDef(const std::string& name) : name(name) {
|
ItemDef::ItemDef(const std::string& name) : name(name) {
|
||||||
caption = util::id_to_caption(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;
|
||||||
|
}
|
||||||
|
|||||||
@ -44,4 +44,5 @@ struct ItemDef {
|
|||||||
|
|
||||||
ItemDef(const std::string& name);
|
ItemDef(const std::string& name);
|
||||||
ItemDef(const ItemDef&) = delete;
|
ItemDef(const ItemDef&) = delete;
|
||||||
|
void cloneTo(ItemDef& dst);
|
||||||
};
|
};
|
||||||
|
|||||||
12
src/objects/EntityDef.cpp
Normal file
12
src/objects/EntityDef.cpp
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
@ -24,12 +24,12 @@ struct EntityDef {
|
|||||||
|
|
||||||
/// @brief Hitbox size
|
/// @brief Hitbox size
|
||||||
glm::vec3 hitbox {0.25f};
|
glm::vec3 hitbox {0.25f};
|
||||||
|
|
||||||
/// @brief 'aabb' sensors
|
/// @brief 'aabb' sensors
|
||||||
std::vector<std::pair<size_t, AABB>> boxSensors {};
|
std::vector<std::pair<size_t, AABB>> boxSensors {};
|
||||||
/// @brief 'radius' sensors
|
/// @brief 'radius' sensors
|
||||||
std::vector<std::pair<size_t, float>> radialSensors {};
|
std::vector<std::pair<size_t, float>> radialSensors {};
|
||||||
|
|
||||||
/// @brief Skeleton ID
|
/// @brief Skeleton ID
|
||||||
std::string skeletonName = name;
|
std::string skeletonName = name;
|
||||||
|
|
||||||
@ -56,4 +56,6 @@ struct EntityDef {
|
|||||||
|
|
||||||
EntityDef(const std::string& name) : name(name) {}
|
EntityDef(const std::string& name) : name(name) {}
|
||||||
EntityDef(const EntityDef&) = delete;
|
EntityDef(const EntityDef&) = delete;
|
||||||
|
void cloneTo(EntityDef& dst);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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}}, // West
|
||||||
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Up
|
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Up
|
||||||
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Down
|
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Down
|
||||||
}};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const BlockRotProfile BlockRotProfile::PIPE {
|
const BlockRotProfile BlockRotProfile::PIPE {
|
||||||
"pipe",
|
"pipe",
|
||||||
@ -75,7 +76,8 @@ const BlockRotProfile BlockRotProfile::PIPE {
|
|||||||
{{0, 0, -1}, {1, 0, 0}, {0, -1, 0}}, // West
|
{{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}}, // Up
|
||||||
{{1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, // Down
|
{{1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, // Down
|
||||||
}};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const BlockRotProfile BlockRotProfile::PANE {
|
const BlockRotProfile BlockRotProfile::PANE {
|
||||||
"pane",
|
"pane",
|
||||||
@ -84,7 +86,8 @@ const BlockRotProfile BlockRotProfile::PANE {
|
|||||||
{{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}, // East
|
{{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}, // East
|
||||||
{{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}}, // South
|
{{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}}, // South
|
||||||
{{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}}, // West
|
{{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}}, // West
|
||||||
}};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Block::Block(const std::string& name)
|
Block::Block(const std::string& name)
|
||||||
: name(name),
|
: name(name),
|
||||||
@ -95,10 +98,43 @@ Block::Block(const std::string& name)
|
|||||||
TEXTURE_NOTFOUND,
|
TEXTURE_NOTFOUND,
|
||||||
TEXTURE_NOTFOUND,
|
TEXTURE_NOTFOUND,
|
||||||
TEXTURE_NOTFOUND,
|
TEXTURE_NOTFOUND,
|
||||||
TEXTURE_NOTFOUND} {
|
TEXTURE_NOTFOUND
|
||||||
|
} {
|
||||||
}
|
}
|
||||||
|
|
||||||
Block::Block(std::string name, const std::string& texture)
|
Block::Block(std::string name, const std::string& texture)
|
||||||
: name(std::move(name)),
|
: name(std::move(name)),
|
||||||
textureFaces {texture, texture, texture, texture, texture, texture} {
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -211,6 +211,8 @@ public:
|
|||||||
Block(const std::string& name);
|
Block(const std::string& name);
|
||||||
Block(std::string name, const std::string& texture);
|
Block(std::string name, const std::string& texture);
|
||||||
Block(const Block&) = delete;
|
Block(const Block&) = delete;
|
||||||
|
|
||||||
|
void cloneTo(Block& dst);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline glm::ivec3 get_ground_direction(const Block& def, int rotation) {
|
inline glm::ivec3 get_ground_direction(const Block& def, int rotation) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user