refactor ContentBuilder and add entities support
This commit is contained in:
parent
1acced4475
commit
66a1240fbc
@ -7,15 +7,18 @@
|
||||
|
||||
#include "../voxels/Block.hpp"
|
||||
#include "../items/ItemDef.hpp"
|
||||
#include "../objects/EntityDef.hpp"
|
||||
|
||||
#include "ContentPack.hpp"
|
||||
#include "../logic/scripting/scripting.hpp"
|
||||
|
||||
ContentIndices::ContentIndices(
|
||||
std::vector<Block*> blocks,
|
||||
std::vector<ItemDef*> items
|
||||
ContentUnitIndices<Block> blocks,
|
||||
ContentUnitIndices<ItemDef> items,
|
||||
ContentUnitIndices<EntityDef> entities
|
||||
) : blocks(std::move(blocks)),
|
||||
items(std::move(items))
|
||||
items(std::move(items)),
|
||||
entities(std::move(entities))
|
||||
{}
|
||||
|
||||
Content::Content(
|
||||
@ -23,6 +26,7 @@ Content::Content(
|
||||
std::unique_ptr<DrawGroups> drawGroups,
|
||||
ContentUnitDefs<Block> blocks,
|
||||
ContentUnitDefs<ItemDef> items,
|
||||
ContentUnitDefs<EntityDef> entities,
|
||||
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
|
||||
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
|
||||
) : indices(std::move(indices)),
|
||||
@ -30,6 +34,7 @@ Content::Content(
|
||||
blockMaterials(std::move(blockMaterials)),
|
||||
blocks(std::move(blocks)),
|
||||
items(std::move(items)),
|
||||
entities(std::move(entities)),
|
||||
drawGroups(std::move(drawGroups))
|
||||
{}
|
||||
|
||||
|
||||
@ -14,12 +14,13 @@ using DrawGroups = std::set<ubyte>;
|
||||
|
||||
class Block;
|
||||
struct BlockMaterial;
|
||||
class ItemDef;
|
||||
struct ItemDef;
|
||||
struct EntityDef;
|
||||
class Content;
|
||||
class ContentPackRuntime;
|
||||
|
||||
enum class contenttype {
|
||||
none, block, item
|
||||
none, block, item, entity
|
||||
};
|
||||
|
||||
inline const char* contenttype_name(contenttype type) {
|
||||
@ -27,6 +28,7 @@ inline const char* contenttype_name(contenttype type) {
|
||||
case contenttype::none: return "none";
|
||||
case contenttype::block: return "block";
|
||||
case contenttype::item: return "item";
|
||||
case contenttype::entity: return "entity";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
@ -70,10 +72,12 @@ class ContentIndices {
|
||||
public:
|
||||
ContentUnitIndices<Block> blocks;
|
||||
ContentUnitIndices<ItemDef> items;
|
||||
ContentUnitIndices<EntityDef> entities;
|
||||
|
||||
ContentIndices(
|
||||
std::vector<Block*> blockDefs,
|
||||
std::vector<ItemDef*> itemDefs
|
||||
ContentUnitIndices<Block> blocks,
|
||||
ContentUnitIndices<ItemDef> items,
|
||||
ContentUnitIndices<EntityDef> entities
|
||||
);
|
||||
};
|
||||
|
||||
@ -109,6 +113,7 @@ class Content {
|
||||
public:
|
||||
ContentUnitDefs<Block> blocks;
|
||||
ContentUnitDefs<ItemDef> items;
|
||||
ContentUnitDefs<EntityDef> entities;
|
||||
std::unique_ptr<DrawGroups> const drawGroups;
|
||||
|
||||
Content(
|
||||
@ -116,6 +121,7 @@ public:
|
||||
std::unique_ptr<DrawGroups> drawGroups,
|
||||
ContentUnitDefs<Block> blocks,
|
||||
ContentUnitDefs<ItemDef> items,
|
||||
ContentUnitDefs<EntityDef> entities,
|
||||
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
|
||||
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
|
||||
);
|
||||
|
||||
@ -6,28 +6,6 @@ void ContentBuilder::add(std::unique_ptr<ContentPackRuntime> pack) {
|
||||
packs[pack->getId()] = std::move(pack);
|
||||
}
|
||||
|
||||
Block& ContentBuilder::createBlock(const std::string& id) {
|
||||
auto found = blockDefs.find(id);
|
||||
if (found != blockDefs.end()) {
|
||||
return *found->second;
|
||||
}
|
||||
checkIdentifier(id);
|
||||
blockIds.push_back(id);
|
||||
blockDefs[id] = std::make_unique<Block>(id);
|
||||
return *blockDefs[id];
|
||||
}
|
||||
|
||||
ItemDef& ContentBuilder::createItem(const std::string& id) {
|
||||
auto found = itemDefs.find(id);
|
||||
if (found != itemDefs.end()) {
|
||||
return *found->second;
|
||||
}
|
||||
checkIdentifier(id);
|
||||
itemIds.push_back(id);
|
||||
itemDefs[id] = std::make_unique<ItemDef>(id);
|
||||
return *itemDefs[id];
|
||||
}
|
||||
|
||||
BlockMaterial& ContentBuilder::createBlockMaterial(const std::string& id) {
|
||||
blockMaterials[id] = std::make_unique<BlockMaterial>();
|
||||
auto& material = *blockMaterials[id];
|
||||
@ -35,28 +13,11 @@ BlockMaterial& ContentBuilder::createBlockMaterial(const std::string& id) {
|
||||
return material;
|
||||
}
|
||||
|
||||
void ContentBuilder::checkIdentifier(const std::string& id) {
|
||||
contenttype result;
|
||||
if (((result = checkContentType(id)) != contenttype::none)) {
|
||||
throw namereuse_error("name "+id+" is already used", result);
|
||||
}
|
||||
}
|
||||
|
||||
contenttype ContentBuilder::checkContentType(const std::string& id) {
|
||||
if (blockDefs.find(id) != blockDefs.end()) {
|
||||
return contenttype::block;
|
||||
}
|
||||
if (itemDefs.find(id) != itemDefs.end()) {
|
||||
return contenttype::item;
|
||||
}
|
||||
return contenttype::none;
|
||||
}
|
||||
|
||||
std::unique_ptr<Content> ContentBuilder::build() {
|
||||
std::vector<Block*> blockDefsIndices;
|
||||
auto groups = std::make_unique<DrawGroups>();
|
||||
for (const std::string& name : blockIds) {
|
||||
Block& def = *blockDefs[name];
|
||||
for (const std::string& name : blocks.names) {
|
||||
Block& def = *blocks.defs[name];
|
||||
|
||||
// Generating runtime info
|
||||
def.rt.id = blockDefsIndices.size();
|
||||
@ -79,8 +40,8 @@ std::unique_ptr<Content> ContentBuilder::build() {
|
||||
}
|
||||
|
||||
std::vector<ItemDef*> itemDefsIndices;
|
||||
for (const std::string& name : itemIds) {
|
||||
ItemDef& def = *itemDefs[name];
|
||||
for (const std::string& name : items.names) {
|
||||
ItemDef& def = *items.defs[name];
|
||||
|
||||
// Generating runtime info
|
||||
def.rt.id = itemDefsIndices.size();
|
||||
@ -88,12 +49,24 @@ std::unique_ptr<Content> ContentBuilder::build() {
|
||||
itemDefsIndices.push_back(&def);
|
||||
}
|
||||
|
||||
std::vector<EntityDef*> entityDefsIndices;
|
||||
for (const std::string& name : entities.names) {
|
||||
EntityDef& def = *entities.defs[name];
|
||||
|
||||
// Generating runtime info
|
||||
entityDefsIndices.push_back(&def);
|
||||
}
|
||||
|
||||
auto content = std::make_unique<Content>(
|
||||
std::make_unique<ContentIndices>(blockDefsIndices, itemDefsIndices),
|
||||
std::move(groups),
|
||||
std::move(blockDefs),
|
||||
std::move(itemDefs),
|
||||
std::move(packs),
|
||||
std::make_unique<ContentIndices>(
|
||||
blockDefsIndices,
|
||||
itemDefsIndices,
|
||||
entityDefsIndices),
|
||||
std::move(groups),
|
||||
blocks.build(),
|
||||
items.build(),
|
||||
entities.build(),
|
||||
std::move(packs),
|
||||
std::move(blockMaterials)
|
||||
);
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include "../items/ItemDef.hpp"
|
||||
#include "../voxels/Block.hpp"
|
||||
#include "../objects/EntityDef.hpp"
|
||||
#include "../content/Content.hpp"
|
||||
#include "../content/ContentPack.hpp"
|
||||
|
||||
@ -10,27 +11,58 @@
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
template<class T>
|
||||
class ContentUnitBuilder {
|
||||
std::unordered_map<std::string, contenttype>& allNames;
|
||||
contenttype type;
|
||||
|
||||
void checkIdentifier(const std::string& id) {
|
||||
const auto& found = allNames.find(id);
|
||||
if (found != allNames.end()) {
|
||||
throw namereuse_error("name "+id+" is already used", found->second);
|
||||
}
|
||||
}
|
||||
public:
|
||||
std::unordered_map<std::string, std::unique_ptr<T>> defs;
|
||||
std::vector<std::string> names;
|
||||
|
||||
ContentUnitBuilder(
|
||||
std::unordered_map<std::string, contenttype>& allNames,
|
||||
contenttype type
|
||||
) : allNames(allNames), type(type) {}
|
||||
|
||||
T& create(const std::string& id) {
|
||||
auto found = defs.find(id);
|
||||
if (found != defs.end()) {
|
||||
return *found->second;
|
||||
}
|
||||
checkIdentifier(id);
|
||||
allNames[id] = type;
|
||||
names.push_back(id);
|
||||
defs[id] = std::make_unique<T>(id);
|
||||
return *defs[id];
|
||||
}
|
||||
|
||||
auto build() {
|
||||
return std::move(defs);
|
||||
}
|
||||
};
|
||||
|
||||
class ContentBuilder {
|
||||
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs;
|
||||
std::vector<std::string> blockIds;
|
||||
|
||||
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs;
|
||||
std::vector<std::string> itemIds;
|
||||
|
||||
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials;
|
||||
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs;
|
||||
std::unordered_map<std::string, contenttype> allNames;
|
||||
public:
|
||||
ContentUnitBuilder<Block> blocks {allNames, contenttype::block};
|
||||
ContentUnitBuilder<ItemDef> items {allNames, contenttype::item};
|
||||
ContentUnitBuilder<EntityDef> entities {allNames, contenttype::entity};
|
||||
|
||||
~ContentBuilder();
|
||||
|
||||
void add(std::unique_ptr<ContentPackRuntime> pack);
|
||||
|
||||
Block& createBlock(const std::string& id);
|
||||
ItemDef& createItem(const std::string& id);
|
||||
BlockMaterial& createBlockMaterial(const std::string& id);
|
||||
|
||||
void checkIdentifier(const std::string& id);
|
||||
contenttype checkContentType(const std::string& id);
|
||||
|
||||
std::unique_ptr<Content> build();
|
||||
};
|
||||
|
||||
|
||||
@ -363,14 +363,14 @@ void ContentLoader::load(ContentBuilder& builder) {
|
||||
auto colon = name.find(':');
|
||||
std::string full = colon == std::string::npos ? pack->id + ":" + name : name;
|
||||
if (colon != std::string::npos) name[colon] = '/';
|
||||
auto& def = builder.createBlock(full);
|
||||
auto& def = builder.blocks.create(full);
|
||||
if (colon != std::string::npos) {
|
||||
def.scriptName = name.substr(0, colon) + '/' + def.scriptName;
|
||||
}
|
||||
loadBlock(def, full, name);
|
||||
stats.totalBlocks++;
|
||||
if (!def.hidden) {
|
||||
auto& item = builder.createItem(full+BLOCK_ITEM_SUFFIX);
|
||||
auto& item = builder.items.create(full+BLOCK_ITEM_SUFFIX);
|
||||
item.generated = true;
|
||||
item.caption = def.caption;
|
||||
item.iconType = item_icon_type::block;
|
||||
@ -392,7 +392,7 @@ void ContentLoader::load(ContentBuilder& builder) {
|
||||
auto colon = name.find(':');
|
||||
std::string full = colon == std::string::npos ? pack->id + ":" + name : name;
|
||||
if (colon != std::string::npos) name[colon] = '/';
|
||||
auto& def = builder.createItem(full);
|
||||
auto& def = builder.items.create(full);
|
||||
if (colon != std::string::npos) def.scriptName = name.substr(0, colon) + '/' + def.scriptName;
|
||||
loadItem(def, full, name);
|
||||
stats.totalItems++;
|
||||
|
||||
@ -10,7 +10,7 @@ namespace fs = std::filesystem;
|
||||
|
||||
class Block;
|
||||
struct BlockMaterial;
|
||||
class ItemDef;
|
||||
struct ItemDef;
|
||||
struct ContentPack;
|
||||
class ContentBuilder;
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
// All in-game definitions (blocks, items, etc..)
|
||||
void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) {
|
||||
Block& block = builder->createBlock("core:air");
|
||||
Block& block = builder->blocks.create("core:air");
|
||||
block.replaceable = true;
|
||||
block.drawGroup = 1;
|
||||
block.lightPassing = true;
|
||||
@ -22,7 +22,7 @@ void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) {
|
||||
block.model = BlockModel::none;
|
||||
block.pickingItem = "core:empty";
|
||||
|
||||
ItemDef& item = builder->createItem("core:empty");
|
||||
ItemDef& item = builder->items.create("core:empty");
|
||||
item.iconType = item_icon_type::none;
|
||||
|
||||
auto bindsFile = paths->getResources()/fs::path("bindings.toml");
|
||||
|
||||
@ -19,8 +19,7 @@ enum class item_icon_type {
|
||||
block, // block preview: icon is string block id
|
||||
};
|
||||
|
||||
class ItemDef {
|
||||
public:
|
||||
struct ItemDef {
|
||||
/// @brief Item string id (with prefix included)
|
||||
std::string const name;
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ class ContentIndices;
|
||||
class Level;
|
||||
class Block;
|
||||
class Player;
|
||||
class ItemDef;
|
||||
struct ItemDef;
|
||||
class Inventory;
|
||||
class UiDocument;
|
||||
struct block_funcs_set;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user