#include "ContentBuilder.hpp" ContentBuilder::~ContentBuilder() {} void ContentBuilder::add(std::unique_ptr pack) { packs[pack->getId()] = std::move(pack); } Block& ContentBuilder::createBlock(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(id); return *blockDefs[id]; } ItemDef& ContentBuilder::createItem(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(id); return *itemDefs[id]; } BlockMaterial& ContentBuilder::createBlockMaterial(std::string id) { blockMaterials[id] = std::make_unique(); auto& material = *blockMaterials[id]; material.name = id; return material; } void ContentBuilder::checkIdentifier(std::string id) { contenttype result; if (((result = checkContentType(id)) != contenttype::none)) { throw namereuse_error("name "+id+" is already used", result); } } contenttype ContentBuilder::checkContentType(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 ContentBuilder::build() { std::vector blockDefsIndices; auto groups = std::make_unique(); for (const std::string& name : blockIds) { Block& def = *blockDefs[name]; // Generating runtime info def.rt.id = blockDefsIndices.size(); def.rt.emissive = *reinterpret_cast(def.emission); def.rt.solid = def.model == BlockModel::block; if (def.rotatable) { for (uint i = 0; i < BlockRotProfile::MAX_COUNT; i++) { def.rt.hitboxes[i].reserve(def.hitboxes.size()); for (AABB aabb : def.hitboxes) { def.rotations.variants[i].transform(aabb); def.rt.hitboxes[i].push_back(aabb); } } } blockDefsIndices.push_back(&def); groups->insert(def.drawGroup); } std::vector itemDefsIndices; for (const std::string& name : itemIds) { ItemDef& def = *itemDefs[name]; // Generating runtime info def.rt.id = itemDefsIndices.size(); def.rt.emissive = *reinterpret_cast(def.emission); itemDefsIndices.push_back(&def); } auto content = std::make_unique( std::make_unique(blockDefsIndices, itemDefsIndices), std::move(groups), std::move(blockDefs), std::move(itemDefs), std::move(packs), std::move(blockMaterials) ); // Now, it's time to resolve foreign keys for (Block* def : blockDefsIndices) { def->rt.pickingItem = content->requireItem(def->pickingItem).rt.id; } for (ItemDef* def : itemDefsIndices) { def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id; } return content; }