refactor Content

This commit is contained in:
MihailRis 2024-06-25 22:37:53 +03:00
parent f3c5afa1ab
commit ee9f1639e9
25 changed files with 180 additions and 209 deletions

View File

@ -12,62 +12,30 @@
#include "../logic/scripting/scripting.hpp" #include "../logic/scripting/scripting.hpp"
ContentIndices::ContentIndices( ContentIndices::ContentIndices(
std::vector<Block*> blockDefs, std::vector<Block*> blocks,
std::vector<ItemDef*> itemDefs std::vector<ItemDef*> items
) : blockDefs(std::move(blockDefs)), ) : blocks(std::move(blocks)),
itemDefs(std::move(itemDefs)) items(std::move(items))
{} {}
Content::Content( Content::Content(
std::unique_ptr<ContentIndices> indices, std::unique_ptr<ContentIndices> indices,
std::unique_ptr<DrawGroups> drawGroups, std::unique_ptr<DrawGroups> drawGroups,
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs, ContentUnitDefs<Block> blocks,
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs, ContentUnitDefs<ItemDef> items,
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs, std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
) : blockDefs(std::move(blockDefs)), ) : indices(std::move(indices)),
itemDefs(std::move(itemDefs)),
indices(std::move(indices)),
packs(std::move(packs)), packs(std::move(packs)),
blockMaterials(std::move(blockMaterials)), blockMaterials(std::move(blockMaterials)),
blocks(std::move(blocks)),
items(std::move(items)),
drawGroups(std::move(drawGroups)) drawGroups(std::move(drawGroups))
{} {}
Content::~Content() { Content::~Content() {
} }
Block* Content::findBlock(const std::string& id) const {
auto found = blockDefs.find(id);
if (found == blockDefs.end()) {
return nullptr;
}
return found->second.get();
}
Block& Content::requireBlock(const std::string& id) const {
auto found = blockDefs.find(id);
if (found == blockDefs.end()) {
throw std::runtime_error("missing block "+id);
}
return *found->second;
}
ItemDef* Content::findItem(const std::string& id) const {
auto found = itemDefs.find(id);
if (found == itemDefs.end()) {
return nullptr;
}
return found->second.get();
}
ItemDef& Content::requireItem(const std::string& id) const {
auto found = itemDefs.find(id);
if (found == itemDefs.end()) {
throw std::runtime_error("missing item "+id);
}
return *found->second;
}
const BlockMaterial* Content::findBlockMaterial(const std::string& id) const { const BlockMaterial* Content::findBlockMaterial(const std::string& id) const {
auto found = blockMaterials.find(id); auto found = blockMaterials.find(id);
if (found == blockMaterials.end()) { if (found == blockMaterials.end()) {

View File

@ -43,61 +43,79 @@ public:
} }
}; };
template<class T>
class ContentUnitIndices {
std::vector<T*> defs;
public:
ContentUnitIndices(std::vector<T*> defs) : defs(std::move(defs)) {}
inline T* get(blockid_t id) const {
if (id >= defs.size()) {
return nullptr;
}
return defs[id];
}
inline size_t count() const {
return defs.size();
}
inline const T* const* getDefs() const {
return defs.data();
}
};
/// @brief Runtime defs cache: indices /// @brief Runtime defs cache: indices
class ContentIndices { class ContentIndices {
std::vector<Block*> blockDefs;
std::vector<ItemDef*> itemDefs;
public: public:
ContentUnitIndices<Block> blocks;
ContentUnitIndices<ItemDef> items;
ContentIndices( ContentIndices(
std::vector<Block*> blockDefs, std::vector<Block*> blockDefs,
std::vector<ItemDef*> itemDefs std::vector<ItemDef*> itemDefs
); );
};
inline Block* getBlockDef(blockid_t id) const { template<class T>
if (id >= blockDefs.size()) class ContentUnitDefs {
std::unordered_map<std::string, std::unique_ptr<T>> defs;
public:
ContentUnitDefs(std::unordered_map<std::string, std::unique_ptr<T>> defs)
: defs(std::move(defs)) {
}
T* find(const std::string& id) const {
const auto& found = defs.find(id);
if (found == defs.end()) {
return nullptr; return nullptr;
return blockDefs[id]; }
return found->second.get();
} }
T& require(const std::string& id) const {
inline ItemDef* getItemDef(itemid_t id) const { const auto& found = defs.find(id);
if (id >= itemDefs.size()) if (found == defs.end()) {
return nullptr; throw std::runtime_error("missing content unit "+id);
return itemDefs[id]; }
} return *found->second;
inline size_t countBlockDefs() const {
return blockDefs.size();
}
inline size_t countItemDefs() const {
return itemDefs.size();
}
// use this for critical spots to prevent range check overhead
const Block* const* getBlockDefs() const {
return blockDefs.data();
}
const ItemDef* const* getItemDefs() const {
return itemDefs.data();
} }
}; };
/* Content is a definitions repository */ /// @brief Content is a definitions repository
class Content { class Content {
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs;
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs;
std::unique_ptr<ContentIndices> indices; std::unique_ptr<ContentIndices> indices;
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs; std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs;
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials; std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials;
public: public:
ContentUnitDefs<Block> blocks;
ContentUnitDefs<ItemDef> items;
std::unique_ptr<DrawGroups> const drawGroups; std::unique_ptr<DrawGroups> const drawGroups;
Content( Content(
std::unique_ptr<ContentIndices> indices, std::unique_ptr<ContentIndices> indices,
std::unique_ptr<DrawGroups> drawGroups, std::unique_ptr<DrawGroups> drawGroups,
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs, ContentUnitDefs<Block> blocks,
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs, ContentUnitDefs<ItemDef> items,
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs, std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
); );
@ -107,14 +125,7 @@ public:
return indices.get(); return indices.get();
} }
Block* findBlock(const std::string& id) const;
Block& requireBlock(const std::string& id) const;
ItemDef* findItem(const std::string& id) const;
ItemDef& requireItem(const std::string& id) const;
const BlockMaterial* findBlockMaterial(const std::string& id) const; const BlockMaterial* findBlockMaterial(const std::string& id) const;
const ContentPackRuntime* getPackRuntime(const std::string& id) const; const ContentPackRuntime* getPackRuntime(const std::string& id) const;
const std::unordered_map<std::string, std::unique_ptr<BlockMaterial>>& getBlockMaterials() const; const std::unordered_map<std::string, std::unique_ptr<BlockMaterial>>& getBlockMaterials() const;

View File

@ -99,11 +99,11 @@ std::unique_ptr<Content> ContentBuilder::build() {
// Now, it's time to resolve foreign keys // Now, it's time to resolve foreign keys
for (Block* def : blockDefsIndices) { for (Block* def : blockDefsIndices) {
def->rt.pickingItem = content->requireItem(def->pickingItem).rt.id; def->rt.pickingItem = content->items.require(def->pickingItem).rt.id;
} }
for (ItemDef* def : itemDefsIndices) { for (ItemDef* def : itemDefsIndices) {
def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id; def->rt.placingBlock = content->blocks.require(def->placingBlock).rt.id;
} }
return content; return content;

View File

@ -10,29 +10,45 @@
#include <memory> #include <memory>
template<typename I, class T>
static void init(std::vector<I>& ids, std::vector<std::string>& names,
const ContentUnitIndices<T>& indices, size_t count) {
for (size_t i = 0; i < count; i++) {
ids.push_back(i);
}
for (size_t i = 0; i < indices.count(); i++) {
names.push_back(indices.get(i)->name);
}
for (size_t i = indices.count(); i < count; i++) {
names.emplace_back("");
}
}
ContentLUT::ContentLUT(const Content* content, size_t blocksCount, size_t itemsCount) { ContentLUT::ContentLUT(const Content* content, size_t blocksCount, size_t itemsCount) {
auto* indices = content->getIndices(); auto* indices = content->getIndices();
for (size_t i = 0; i < blocksCount; i++) { init(blocks, blockNames, indices->blocks, blocksCount);
blocks.push_back(i); init(items, itemNames, indices->items, itemsCount);
} }
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.emplace_back("");
}
for (size_t i = 0; i < itemsCount; i++) { template<class T>
items.push_back(i); static void setup_lut(ContentLUT* lut, const ContentUnitDefs<T>& defs, dynamic::List* list) {
} if (list) {
for (size_t i = 0; i < indices->countItemDefs(); i++) { for (size_t i = 0; i < list->size(); i++) {
itemNames.push_back(indices->getItemDef(i)->name); std::string name = list->str(i);
} if (auto def = defs.find(name)) {
for (size_t i = indices->countItemDefs(); i < itemsCount; i++) { lut->setBlock(i, name, def->rt.id);
itemNames.emplace_back(); } else {
lut->setBlock(i, name, BLOCK_VOID);
}
}
} }
} }
template<class T> static constexpr size_t get_entries_count(
const ContentUnitIndices<T>& indices, dynamic::List* list) {
return list ? std::max(list->size(), indices.count()) : indices.count();
}
std::shared_ptr<ContentLUT> ContentLUT::create( std::shared_ptr<ContentLUT> ContentLUT::create(
const fs::path& filename, const fs::path& filename,
const Content* content const Content* content
@ -42,38 +58,13 @@ std::shared_ptr<ContentLUT> ContentLUT::create(
auto itemlist = root->list("items"); auto itemlist = root->list("items");
auto* indices = content->getIndices(); auto* indices = content->getIndices();
size_t blocks_c = blocklist size_t blocks_c = get_entries_count(indices->blocks, blocklist);
? std::max(blocklist->size(), indices->countBlockDefs()) size_t items_c = get_entries_count(indices->items, itemlist);
: indices->countBlockDefs();
size_t items_c = itemlist
? std::max(itemlist->size(), indices->countItemDefs())
: indices->countItemDefs();
auto lut = std::make_shared<ContentLUT>(content, blocks_c, items_c); auto lut = std::make_shared<ContentLUT>(content, blocks_c, items_c);
if (blocklist) { setup_lut(lut.get(), content->blocks, blocklist);
for (size_t i = 0; i < blocklist->size(); i++) { setup_lut(lut.get(), content->items, itemlist);
std::string name = blocklist->str(i);
Block* def = content->findBlock(name);
if (def) {
lut->setBlock(i, name, def->rt.id);
} else {
lut->setBlock(i, name, BLOCK_VOID);
}
}
}
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()) { if (lut->hasContentReorder() || lut->hasMissingContent()) {
return lut; return lut;

View File

@ -96,17 +96,16 @@ void WorldFiles::writeIndices(const ContentIndices* indices) {
dynamic::Map root; dynamic::Map root;
uint count; uint count;
auto& blocks = root.putList("blocks"); auto& blocks = root.putList("blocks");
count = indices->countBlockDefs(); count = indices->blocks.count();
for (uint i = 0; i < count; i++) { for (uint i = 0; i < count; i++) {
const Block* def = indices->getBlockDef(i); const Block* def = indices->blocks.get(i);
blocks.put(def->name); blocks.put(def->name);
} }
auto& items = root.putList("items"); auto& items = root.putList("items");
count = indices->countItemDefs(); count = indices->items.count();
for (uint i = 0; i < count; i++) { for (uint i = 0; i < count; i++) {
const ItemDef* def = indices->getItemDef(i); items.put(indices->items.get(i)->name);
items.put(def->name);
} }
files::write_json(getIndicesFile(), &root); files::write_json(getIndicesFile(), &root);

View File

@ -14,11 +14,11 @@
ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) { ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) {
auto indices = content->getIndices(); auto indices = content->getIndices();
sideregions = std::make_unique<UVRegion[]>(indices->countBlockDefs() * 6); sideregions = std::make_unique<UVRegion[]>(indices->blocks.count() * 6);
auto atlas = assets->get<Atlas>("blocks"); auto atlas = assets->get<Atlas>("blocks");
for (uint i = 0; i < indices->countBlockDefs(); i++) { for (uint i = 0; i < indices->blocks.count(); i++) {
Block* def = indices->getBlockDef(i); Block* def = indices->blocks.get(i);
for (uint side = 0; side < 6; side++) { for (uint side = 0; side < 6; side++) {
const std::string& tex = def->textureFaces[side]; const std::string& tex = def->textureFaces[side];
if (atlas->has(tex)) { if (atlas->has(tex)) {

View File

@ -98,7 +98,7 @@ std::shared_ptr<UINode> create_debug_panel(
})); }));
panel->add(create_label([=](){ panel->add(create_label([=](){
auto* indices = level->content->getIndices(); auto* indices = level->content->getIndices();
if (auto def = indices->getBlockDef(player->selection.vox.id)) { if (auto def = indices->blocks.get(player->selection.vox.id)) {
return L"name: " + util::str2wstr_utf8(def->name); return L"name: " + util::str2wstr_utf8(def->name);
} else { } else {
return std::wstring {L"name: void"}; return std::wstring {L"name: void"};

View File

@ -102,9 +102,9 @@ std::shared_ptr<InventoryView> Hud::createContentAccess() {
auto indices = content->getIndices(); auto indices = content->getIndices();
auto inventory = player->getInventory(); auto inventory = player->getInventory();
int itemsCount = indices->countItemDefs(); size_t itemsCount = indices->items.count();
auto accessInventory = std::make_shared<Inventory>(0, itemsCount); auto accessInventory = std::make_shared<Inventory>(0, itemsCount);
for (int id = 1; id < itemsCount; id++) { for (size_t id = 1; id < itemsCount; id++) {
accessInventory->getSlot(id-1).set(ItemStack(id, 1)); accessInventory->getSlot(id-1).set(ItemStack(id, 1));
} }

View File

@ -123,7 +123,7 @@ std::unique_ptr<Atlas> BlocksPreview::build(
const Content* content const Content* content
) { ) {
auto indices = content->getIndices(); auto indices = content->getIndices();
size_t count = indices->countBlockDefs(); size_t count = indices->blocks.count();
size_t iconSize = ITEM_ICON_SIZE; size_t iconSize = ITEM_ICON_SIZE;
auto shader = assets->get<Shader>("ui3d"); auto shader = assets->get<Shader>("ui3d");
@ -153,7 +153,7 @@ std::unique_ptr<Atlas> BlocksPreview::build(
fbo.bind(); fbo.bind();
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
auto def = indices->getBlockDef(i); auto def = indices->blocks.get(i);
atlas->getTexture()->bind(); atlas->getTexture()->bind();
builder.add(def->name, draw(cache, shader, &fbo, &batch, def, iconSize)); builder.add(def->name, draw(cache, shader, &fbo, &batch, def, iconSize));
} }

View File

@ -40,7 +40,7 @@ BlocksRenderer::BlocksRenderer(
CHUNK_W + voxelBufferPadding*2, CHUNK_W + voxelBufferPadding*2,
CHUNK_H, CHUNK_H,
CHUNK_D + voxelBufferPadding*2); CHUNK_D + voxelBufferPadding*2);
blockDefsCache = content->getIndices()->getBlockDefs(); blockDefsCache = content->getIndices()->blocks.getDefs();
} }
BlocksRenderer::~BlocksRenderer() { BlocksRenderer::~BlocksRenderer() {

View File

@ -179,7 +179,7 @@ void WorldRenderer::renderLevel(
{ {
auto inventory = player->getInventory(); auto inventory = player->getInventory();
ItemStack& stack = inventory->getSlot(player->getChosenSlot()); ItemStack& stack = inventory->getSlot(player->getChosenSlot());
auto item = indices->getItemDef(stack.getItemId()); auto item = indices->items.get(stack.getItemId());
float multiplier = 0.5f; float multiplier = 0.5f;
shader->uniform3f("u_torchlightColor", shader->uniform3f("u_torchlightColor",
item->emission[0] / 15.0f * multiplier, item->emission[0] / 15.0f * multiplier,
@ -202,11 +202,11 @@ void WorldRenderer::renderLevel(
skybox->unbind(); skybox->unbind();
} }
void WorldRenderer::renderBlockSelection(Camera* camera, Shader* linesShader) { void WorldRenderer::renderBlockSelection() {
const auto& selection = player->selection; const auto& selection = player->selection;
auto indices = level->content->getIndices(); auto indices = level->content->getIndices();
blockid_t id = selection.vox.id; blockid_t id = selection.vox.id;
auto block = indices->getBlockDef(id); auto block = indices->blocks.get(id);
const glm::ivec3 pos = player->selection.position; const glm::ivec3 pos = player->selection.position;
const glm::vec3 point = selection.hitPosition; const glm::vec3 point = selection.hitPosition;
const glm::vec3 norm = selection.normal; const glm::vec3 norm = selection.normal;
@ -230,7 +230,7 @@ void WorldRenderer::renderLines(Camera* camera, Shader* linesShader) {
linesShader->use(); linesShader->use();
linesShader->uniformMatrix("u_projview", camera->getProjView()); linesShader->uniformMatrix("u_projview", camera->getProjView());
if (player->selection.vox.id != BLOCK_VOID) { if (player->selection.vox.id != BLOCK_VOID) {
renderBlockSelection(camera, linesShader); renderBlockSelection();
} }
if (player->debug) { if (player->debug) {
level->entities->renderDebug(*lineBatch); level->entities->renderDebug(*lineBatch);

View File

@ -45,10 +45,11 @@ class WorldRenderer {
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); void drawChunks(Chunks* chunks, Camera* camera, Shader* shader);
/// @brief Render block selection lines /// @brief Render block selection lines
void renderBlockSelection();
/// @brief Render lines (selection and debug)
/// @param camera active camera /// @param camera active camera
/// @param linesShader shader used /// @param linesShader shader used
void renderBlockSelection(Camera* camera, Shader* linesShader);
void renderLines(Camera* camera, Shader* linesShader); void renderLines(Camera* camera, Shader* linesShader);
/// @brief Render all debug lines (chunks borders, coord system guides) /// @brief Render all debug lines (chunks borders, coord system guides)

View File

@ -121,7 +121,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) {
itemid_t itemid = bound->getItemId(); itemid_t itemid = bound->getItemId();
if (itemid != prevItem) { if (itemid != prevItem) {
if (itemid) { if (itemid) {
auto def = content->getIndices()->getItemDef(itemid); auto def = content->getIndices()->items.get(itemid);
tooltip = util::pascal_case( tooltip = util::pascal_case(
langs::get(util::str2wstr_utf8(def->caption)) langs::get(util::str2wstr_utf8(def->caption))
); );
@ -159,12 +159,12 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) {
auto previews = assets->get<Atlas>("block-previews"); auto previews = assets->get<Atlas>("block-previews");
auto indices = content->getIndices(); auto indices = content->getIndices();
ItemDef* item = indices->getItemDef(stack.getItemId()); ItemDef* item = indices->items.get(stack.getItemId());
switch (item->iconType) { switch (item->iconType) {
case item_icon_type::none: case item_icon_type::none:
break; break;
case item_icon_type::block: { case item_icon_type::block: {
const Block& cblock = content->requireBlock(item->icon); const Block& cblock = content->blocks.require(item->icon);
batch->texture(previews->getTexture()); batch->texture(previews->getTexture());
UVRegion region = previews->get(cblock.name); UVRegion region = previews->get(cblock.name);
@ -268,7 +268,7 @@ void SlotView::clicked(gui::GUI* gui, mousecode button) {
stack.setCount(halfremain); stack.setCount(halfremain);
} }
} else { } else {
auto stackDef = content->getIndices()->getItemDef(stack.getItemId()); auto stackDef = content->getIndices()->items.get(stack.getItemId());
if (stack.isEmpty()) { if (stack.isEmpty()) {
stack.set(grabbed); stack.set(grabbed);
stack.setCount(1); stack.setCount(1);

View File

@ -22,7 +22,7 @@ bool ItemStack::accepts(const ItemStack& other) const {
} }
void ItemStack::move(ItemStack& item, const ContentIndices* indices) { void ItemStack::move(ItemStack& item, const ContentIndices* indices) {
auto def = indices->getItemDef(item.getItemId()); auto def = indices->items.get(item.getItemId());
int count = std::min(item.count, def->stackSize-this->count); int count = std::min(item.count, def->stackSize-this->count);
if (isEmpty()) { if (isEmpty()) {
set(ItemStack(item.getItemId(), count)); set(ItemStack(item.getItemId(), count));

View File

@ -81,7 +81,7 @@ void LightSolver::solve(){
} }
} }
const Block* const* blockDefs = contentIds->getBlockDefs(); const Block* const* blockDefs = contentIds->blocks.getDefs();
while (!addqueue.empty()){ while (!addqueue.empty()){
const lightentry entry = addqueue.front(); const lightentry entry = addqueue.front();
addqueue.pop(); addqueue.pop();

View File

@ -36,7 +36,7 @@ void Lighting::clear(){
} }
void Lighting::prebuildSkyLight(Chunk* chunk, const ContentIndices* indices){ void Lighting::prebuildSkyLight(Chunk* chunk, const ContentIndices* indices){
auto* blockDefs = indices->getBlockDefs(); const auto* blockDefs = indices->blocks.getDefs();
int highestPoint = 0; int highestPoint = 0;
for (int z = 0; z < CHUNK_D; z++){ for (int z = 0; z < CHUNK_D; z++){
@ -60,7 +60,7 @@ void Lighting::prebuildSkyLight(Chunk* chunk, const ContentIndices* indices){
} }
void Lighting::buildSkyLight(int cx, int cz){ void Lighting::buildSkyLight(int cx, int cz){
const Block* const* blockDefs = content->getIndices()->getBlockDefs(); const auto blockDefs = content->getIndices()->blocks.getDefs();
Chunk* chunk = chunks->getChunk(cx, cz); Chunk* chunk = chunks->getChunk(cx, cz);
for (int z = 0; z < CHUNK_D; z++){ for (int z = 0; z < CHUNK_D; z++){
@ -92,8 +92,8 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand){
LightSolver* solverB = this->solverB.get(); LightSolver* solverB = this->solverB.get();
LightSolver* solverS = this->solverS.get(); LightSolver* solverS = this->solverS.get();
const Block* const* blockDefs = content->getIndices()->getBlockDefs(); auto blockDefs = content->getIndices()->blocks.getDefs();
const Chunk* chunk = chunks->getChunk(cx, cz); auto chunk = chunks->getChunk(cx, cz);
for (uint y = 0; y < CHUNK_H; y++){ for (uint y = 0; y < CHUNK_H; y++){
for (uint z = 0; z < CHUNK_D; z++){ for (uint z = 0; z < CHUNK_D; z++){
@ -150,7 +150,7 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand){
} }
void Lighting::onBlockSet(int x, int y, int z, blockid_t id){ void Lighting::onBlockSet(int x, int y, int z, blockid_t id){
Block* block = content->getIndices()->getBlockDef(id); Block* block = content->getIndices()->blocks.get(id);
solverR->remove(x,y,z); solverR->remove(x,y,z);
solverG->remove(x,y,z); solverG->remove(x,y,z);
solverB->remove(x,y,z); solverB->remove(x,y,z);

View File

@ -83,7 +83,7 @@ void BlocksController::updateBlock(int x, int y, int z) {
voxel* vox = chunks->get(x, y, z); voxel* vox = chunks->get(x, y, z);
if (vox == nullptr) if (vox == nullptr)
return; return;
const Block* def = level->content->getIndices()->getBlockDef(vox->id); auto def = level->content->getIndices()->blocks.get(vox->id);
if (def->grounded && !chunks->isSolidBlock(x, y-1, z)) { if (def->grounded && !chunks->isSolidBlock(x, y-1, z)) {
breakBlock(nullptr, def, x, y, z); breakBlock(nullptr, def, x, y, z);
return; return;
@ -109,10 +109,10 @@ void BlocksController::onBlocksTick(int tickid, int parts) {
auto content = level->content; auto content = level->content;
auto indices = content->getIndices(); auto indices = content->getIndices();
int tickRate = blocksTickClock.getTickRate(); int tickRate = blocksTickClock.getTickRate();
for (size_t id = 0; id < indices->countBlockDefs(); id++) { for (size_t id = 0; id < indices->blocks.count(); id++) {
if ((id + tickid) % parts != 0) if ((id + tickid) % parts != 0)
continue; continue;
auto def = indices->getBlockDef(id); auto def = indices->blocks.get(id);
auto interval = def->tickInterval; auto interval = def->tickInterval;
if (def->rt.funcsset.onblockstick && tickid / parts % interval == 0) { if (def->rt.funcsset.onblockstick && tickid / parts % interval == 0) {
scripting::on_blocks_tick(def, tickRate / interval); scripting::on_blocks_tick(def, tickRate / interval);
@ -143,7 +143,7 @@ void BlocksController::randomTick(int tickid, int parts) {
int by = random.rand() % segheight + s * segheight; int by = random.rand() % segheight + s * segheight;
int bz = random.rand() % CHUNK_D; int bz = random.rand() % CHUNK_D;
const voxel& vox = chunk->voxels[(by * CHUNK_D + bz) * CHUNK_W + bx]; const voxel& vox = chunk->voxels[(by * CHUNK_D + bz) * CHUNK_W + bx];
Block* block = indices->getBlockDef(vox.id); Block* block = indices->blocks.get(vox.id);
if (block->rt.funcsset.randupdate) { if (block->rt.funcsset.randupdate) {
scripting::random_update_block( scripting::random_update_block(
block, block,
@ -167,7 +167,7 @@ int64_t BlocksController::createBlockInventory(int x, int y, int z) {
auto inv = chunk->getBlockInventory(lx, y, lz); auto inv = chunk->getBlockInventory(lx, y, lz);
if (inv == nullptr) { if (inv == nullptr) {
auto indices = level->content->getIndices(); auto indices = level->content->getIndices();
auto def = indices->getBlockDef(chunk->voxels[vox_index(lx, y, lz)].id); auto def = indices->blocks.get(chunk->voxels[vox_index(lx, y, lz)].id);
int invsize = def->inventorySize; int invsize = def->inventorySize;
if (invsize == 0) { if (invsize == 0) {
return 0; return 0;

View File

@ -203,7 +203,7 @@ void PlayerController::onFootstep() {
int z = std::floor(pos.z+half.z*offsetZ); int z = std::floor(pos.z+half.z*offsetZ);
auto vox = level->chunks->get(x, y, z); auto vox = level->chunks->get(x, y, z);
if (vox) { if (vox) {
auto def = level->content->getIndices()->getBlockDef(vox->id); auto def = level->content->getIndices()->blocks.get(vox->id);
if (!def->obstacle) if (!def->obstacle)
continue; continue;
onBlockInteraction( onBlockInteraction(
@ -317,7 +317,7 @@ static int determine_rotation(Block* def, const glm::ivec3& norm, glm::vec3& cam
} }
static void pick_block(ContentIndices* indices, Chunks* chunks, Player* player, int x, int y, int z) { static void pick_block(ContentIndices* indices, Chunks* chunks, Player* player, int x, int y, int z) {
Block* block = indices->getBlockDef(chunks->get(x,y,z)->id); auto block = indices->blocks.get(chunks->get(x,y,z)->id);
itemid_t id = block->rt.pickingItem; itemid_t id = block->rt.pickingItem;
auto inventory = player->getInventory(); auto inventory = player->getInventory();
size_t slotid = inventory->findSlotByItem(id, 0, 10); size_t slotid = inventory->findSlotByItem(id, 0, 10);
@ -356,7 +356,7 @@ voxel* PlayerController::updateSelection(float maxDistance) {
selection.actualPosition = iend; selection.actualPosition = iend;
if (selectedState.segment) { if (selectedState.segment) {
selection.position = chunks->seekOrigin( selection.position = chunks->seekOrigin(
iend, indices->getBlockDef(selection.vox.id), selectedState iend, indices->blocks.get(selection.vox.id), selectedState
); );
auto origin = chunks->get(iend); auto origin = chunks->get(iend);
if (origin && origin->id != vox->id) { if (origin && origin->id != vox->id) {
@ -430,7 +430,7 @@ void PlayerController::updateInteraction() {
auto inventory = player->getInventory(); auto inventory = player->getInventory();
const ItemStack& stack = inventory->getSlot(player->getChosenSlot()); const ItemStack& stack = inventory->getSlot(player->getChosenSlot());
ItemDef* item = indices->getItemDef(stack.getItemId()); ItemDef* item = indices->items.get(stack.getItemId());
auto vox = updateSelection(maxDistance); auto vox = updateSelection(maxDistance);
if (vox == nullptr) { if (vox == nullptr) {
@ -446,7 +446,7 @@ void PlayerController::updateInteraction() {
return; return;
} }
} }
auto target = indices->getBlockDef(vox->id); auto target = indices->blocks.get(vox->id);
if (lclick && target->breakable){ if (lclick && target->breakable){
onBlockInteraction( onBlockInteraction(
iend, target, iend, target,
@ -467,7 +467,7 @@ void PlayerController::updateInteraction() {
return; return;
} }
} }
auto def = indices->getBlockDef(item->rt.placingBlock); auto def = indices->blocks.get(item->rt.placingBlock);
if (def && rclick) { if (def && rclick) {
processRightClick(def, target); processRightClick(def, target);
} }

View File

@ -14,10 +14,10 @@ using namespace scripting;
static Block* require_block(lua::State* L) { static Block* require_block(lua::State* L) {
auto indices = content->getIndices(); auto indices = content->getIndices();
auto id = lua::tointeger(L, 1); auto id = lua::tointeger(L, 1);
if (static_cast<size_t>(id) >= indices->countBlockDefs()) { if (static_cast<size_t>(id) >= indices->blocks.count()) {
return nullptr; return nullptr;
} }
return indices->getBlockDef(id); return indices->blocks.get(id);
} }
static int l_name(lua::State* L) { static int l_name(lua::State* L) {
@ -43,12 +43,12 @@ static int l_is_solid_at(lua::State* L) {
} }
static int l_count(lua::State* L) { static int l_count(lua::State* L) {
return lua::pushinteger(L, indices->countBlockDefs()); return lua::pushinteger(L, indices->blocks.count());
} }
static int l_index(lua::State* L) { static int l_index(lua::State* L) {
auto name = lua::require_string(L, 1); auto name = lua::require_string(L, 1);
return lua::pushinteger(L, content->requireBlock(name).rt.id); return lua::pushinteger(L, content->blocks.require(name).rt.id);
} }
static int l_is_extended(lua::State* L) { static int l_is_extended(lua::State* L) {
@ -78,7 +78,7 @@ static int l_seek_origin(lua::State* L) {
auto y = lua::tointeger(L, 2); auto y = lua::tointeger(L, 2);
auto z = lua::tointeger(L, 3); auto z = lua::tointeger(L, 3);
auto vox = level->chunks->get(x, y, z); auto vox = level->chunks->get(x, y, z);
auto def = indices->getBlockDef(vox->id); auto def = indices->blocks.get(vox->id);
return lua::pushivec3(L, level->chunks->seekOrigin({x, y, z}, def, vox->state)); return lua::pushivec3(L, level->chunks->seekOrigin({x, y, z}, def, vox->state));
} }
@ -89,7 +89,7 @@ static int l_set(lua::State* L) {
auto id = lua::tointeger(L, 4); auto id = lua::tointeger(L, 4);
auto state = lua::tointeger(L, 5); auto state = lua::tointeger(L, 5);
bool noupdate = lua::toboolean(L, 6); bool noupdate = lua::toboolean(L, 6);
if (static_cast<size_t>(id) >= indices->countBlockDefs()) { if (static_cast<size_t>(id) >= indices->blocks.count()) {
return 0; return 0;
} }
if (!level->chunks->get(x, y, z)) { if (!level->chunks->get(x, y, z)) {
@ -120,7 +120,7 @@ static int l_get_x(lua::State* L) {
if (vox == nullptr) { if (vox == nullptr) {
return lua::pushivec3(L, 1, 0, 0); return lua::pushivec3(L, 1, 0, 0);
} }
auto def = level->content->getIndices()->getBlockDef(vox->id); auto def = level->content->getIndices()->blocks.get(vox->id);
if (!def->rotatable) { if (!def->rotatable) {
return lua::pushivec3(L, 1, 0, 0); return lua::pushivec3(L, 1, 0, 0);
} else { } else {
@ -137,7 +137,7 @@ static int l_get_y(lua::State* L) {
if (vox == nullptr) { if (vox == nullptr) {
return lua::pushivec3(L, 0, 1, 0); return lua::pushivec3(L, 0, 1, 0);
} }
auto def = level->content->getIndices()->getBlockDef(vox->id); auto def = level->content->getIndices()->blocks.get(vox->id);
if (!def->rotatable) { if (!def->rotatable) {
return lua::pushivec3(L, 0, 1, 0); return lua::pushivec3(L, 0, 1, 0);
} else { } else {
@ -154,7 +154,7 @@ static int l_get_z(lua::State* L) {
if (vox == nullptr) { if (vox == nullptr) {
return lua::pushivec3(L, 0, 0, 1); return lua::pushivec3(L, 0, 0, 1);
} }
auto def = level->content->getIndices()->getBlockDef(vox->id); auto def = level->content->getIndices()->blocks.get(vox->id);
if (!def->rotatable) { if (!def->rotatable) {
return lua::pushivec3(L, 0, 0, 1); return lua::pushivec3(L, 0, 0, 1);
} else { } else {

View File

@ -49,7 +49,7 @@ static int l_hud_open_block(lua::State* L) {
std::to_string(x) + " " + std::to_string(y) + " " + std::to_string(z) std::to_string(x) + " " + std::to_string(y) + " " + std::to_string(z)
); );
} }
auto def = content->getIndices()->getBlockDef(vox->id); auto def = content->getIndices()->blocks.get(vox->id);
auto assets = engine->getAssets(); auto assets = engine->getAssets();
auto layout = assets->get<UiDocument>(def->uiLayout); auto layout = assets->get<UiDocument>(def->uiLayout);
if (layout == nullptr) { if (layout == nullptr) {

View File

@ -9,7 +9,7 @@
using namespace scripting; using namespace scripting;
static void validate_itemid(itemid_t id) { static void validate_itemid(itemid_t id) {
if (id >= indices->countItemDefs()) { if (id >= indices->items.count()) {
throw std::runtime_error("invalid item id"); throw std::runtime_error("invalid item id");
} }
} }

View File

@ -8,30 +8,30 @@ using namespace scripting;
static int l_item_name(lua::State* L) { static int l_item_name(lua::State* L) {
auto indices = content->getIndices(); auto indices = content->getIndices();
auto id = lua::tointeger(L, 1); auto id = lua::tointeger(L, 1);
if (static_cast<size_t>(id) >= indices->countItemDefs()) { if (static_cast<size_t>(id) >= indices->items.count()) {
return 0; return 0;
} }
auto def = indices->getItemDef(id); auto def = indices->items.get(id);
return lua::pushstring(L, def->name); return lua::pushstring(L, def->name);
} }
static int l_item_index(lua::State* L) { static int l_item_index(lua::State* L) {
auto name = lua::require_string(L, 1); auto name = lua::require_string(L, 1);
return lua::pushinteger(L, content->requireItem(name).rt.id); return lua::pushinteger(L, content->items.require(name).rt.id);
} }
static int l_item_stack_size(lua::State* L) { static int l_item_stack_size(lua::State* L) {
auto indices = content->getIndices(); auto indices = content->getIndices();
auto id = lua::tointeger(L, 1); auto id = lua::tointeger(L, 1);
if (static_cast<size_t>(id) >= indices->countItemDefs()) { if (static_cast<size_t>(id) >= indices->items.count()) {
return 0; return 0;
} }
auto def = indices->getItemDef(id); auto def = indices->items.get(id);
return lua::pushinteger(L, def->stackSize); return lua::pushinteger(L, def->stackSize);
} }
static int l_item_defs_count(lua::State* L) { static int l_item_defs_count(lua::State* L) {
return lua::pushinteger(L, indices->countItemDefs()); return lua::pushinteger(L, indices->items.count());
} }
const luaL_Reg itemlib [] = { const luaL_Reg itemlib [] = {

View File

@ -66,7 +66,7 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z){
return &empty; return &empty;
} }
} }
const Block* def = indices->getBlockDef(v->id); const auto def = indices->blocks.get(v->id);
if (def->obstacle) { if (def->obstacle) {
glm::ivec3 offset {}; glm::ivec3 offset {};
if (v->state.segment) { if (v->state.segment) {
@ -89,21 +89,21 @@ bool Chunks::isSolidBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z); voxel* v = get(x, y, z);
if (v == nullptr) if (v == nullptr)
return false; return false;
return indices->getBlockDef(v->id)->rt.solid; return indices->blocks.get(v->id)->rt.solid;
} }
bool Chunks::isReplaceableBlock(int32_t x, int32_t y, int32_t z) { bool Chunks::isReplaceableBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z); voxel* v = get(x, y, z);
if (v == nullptr) if (v == nullptr)
return false; return false;
return indices->getBlockDef(v->id)->replaceable; return indices->blocks.get(v->id)->replaceable;
} }
bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) { bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z); voxel* v = get(x, y, z);
if (v == nullptr) if (v == nullptr)
return false; return false;
return indices->getBlockDef(v->id)->obstacle; return indices->blocks.get(v->id)->obstacle;
} }
ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel){ ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel){
@ -240,7 +240,7 @@ bool Chunks::checkReplaceability(const Block* def, blockstate state, glm::ivec3
pos += rotation.axisY * sy; pos += rotation.axisY * sy;
pos += rotation.axisZ * sz; pos += rotation.axisZ * sz;
if (auto vox = get(pos.x, pos.y, pos.z)) { if (auto vox = get(pos.x, pos.y, pos.z)) {
auto target = indices->getBlockDef(vox->id); auto target = indices->blocks.get(vox->id);
if (!target->replaceable && vox->id != ignore) { if (!target->replaceable && vox->id != ignore) {
return false; return false;
} }
@ -316,7 +316,7 @@ void Chunks::setRotation(int32_t x, int32_t y, int32_t z, uint8_t index) {
if (vox == nullptr) { if (vox == nullptr) {
return; return;
} }
auto def = indices->getBlockDef(vox->id); auto def = indices->blocks.get(vox->id);
if (!def->rotatable || vox->state.rotation == index) { if (!def->rotatable || vox->state.rotation == index) {
return; return;
} }
@ -351,7 +351,7 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state)
// block finalization // block finalization
voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx]; voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx];
auto prevdef = indices->getBlockDef(vox.id); auto prevdef = indices->blocks.get(vox.id);
if (prevdef->inventorySize == 0) { if (prevdef->inventorySize == 0) {
chunk->removeBlockInventory(lx, y, lz); chunk->removeBlockInventory(lx, y, lz);
} }
@ -360,7 +360,7 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state)
} }
// block initialization // block initialization
auto newdef = indices->getBlockDef(id); auto newdef = indices->blocks.get(id);
vox.id = id; vox.id = id;
vox.state = state; vox.state = state;
chunk->setModifiedAndUnsaved(); chunk->setModifiedAndUnsaved();
@ -429,7 +429,7 @@ voxel* Chunks::rayCast(
if (voxel == nullptr){ if (voxel == nullptr){
return nullptr; return nullptr;
} }
const auto def = indices->getBlockDef(voxel->id); const auto def = indices->blocks.get(voxel->id);
if (def->selectable){ if (def->selectable){
end.x = px + t * dx; end.x = px + t * dx;
end.y = py + t * dy; end.y = py + t * dy;
@ -553,7 +553,7 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis
if (voxel == nullptr) { if (voxel == nullptr) {
return glm::vec3(px + t * dx, py + t * dy, pz + t * dz); return glm::vec3(px + t * dx, py + t * dy, pz + t * dz);
} }
const auto def = indices->getBlockDef(voxel->id); const auto def = indices->blocks.get(voxel->id);
if (def->obstacle) { if (def->obstacle) {
if (!def->rt.solid) { if (!def->rt.solid) {
const std::vector<AABB>& hitboxes = def->rotatable const std::vector<AABB>& hitboxes = def->rotatable

View File

@ -40,7 +40,7 @@ void ChunksStorage::remove(int x, int z) {
static void verifyLoadedChunk(ContentIndices* indices, Chunk* chunk) { static void verifyLoadedChunk(ContentIndices* indices, Chunk* chunk) {
for (size_t i = 0; i < CHUNK_VOL; i++) { for (size_t i = 0; i < CHUNK_VOL; i++) {
blockid_t id = chunk->voxels[i].id; blockid_t id = chunk->voxels[i].id;
if (indices->getBlockDef(id) == nullptr) { if (indices->blocks.get(id) == nullptr) {
auto logline = logger.error(); auto logline = logger.error();
logline << "corruped block detected at " << i << " of chunk "; logline << "corruped block detected at " << i << " of chunk ";
logline << chunk->x << "x" << chunk->z; logline << chunk->x << "x" << chunk->z;
@ -79,6 +79,7 @@ std::shared_ptr<Chunk> ChunksStorage::create(int x, int z) {
} }
// reduce nesting on next modification // reduce nesting on next modification
// 25.06.2024: not now
void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const { void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const {
const Content* content = level->content; const Content* content = level->content;
auto indices = content->getIndices(); auto indices = content->getIndices();
@ -137,7 +138,7 @@ void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const {
voxels[vidx] = cvoxels[cidx]; voxels[vidx] = cvoxels[cidx];
light_t light = clights[cidx]; light_t light = clights[cidx];
if (backlight) { if (backlight) {
const Block* block = indices->getBlockDef(voxels[vidx].id); auto block = indices->blocks.get(voxels[vidx].id);
if (block->lightPassing) { if (block->lightPassing) {
light = Lightmap::combine( light = Lightmap::combine(
min(15, Lightmap::extract(light, 0)+1), min(15, Lightmap::extract(light, 0)+1),

View File

@ -6,13 +6,13 @@
#include "../content/Content.hpp" #include "../content/Content.hpp"
WorldGenerator::WorldGenerator(const Content* content) WorldGenerator::WorldGenerator(const Content* content)
: idStone(content->requireBlock("base:stone").rt.id), : idStone(content->blocks.require("base:stone").rt.id),
idDirt(content->requireBlock("base:dirt").rt.id), idDirt(content->blocks.require("base:dirt").rt.id),
idGrassBlock(content->requireBlock("base:grass_block").rt.id), idGrassBlock(content->blocks.require("base:grass_block").rt.id),
idSand(content->requireBlock("base:sand").rt.id), idSand(content->blocks.require("base:sand").rt.id),
idWater(content->requireBlock("base:water").rt.id), idWater(content->blocks.require("base:water").rt.id),
idWood(content->requireBlock("base:wood").rt.id), idWood(content->blocks.require("base:wood").rt.id),
idLeaves(content->requireBlock("base:leaves").rt.id), idLeaves(content->blocks.require("base:leaves").rt.id),
idGrass(content->requireBlock("base:grass").rt.id), idGrass(content->blocks.require("base:grass").rt.id),
idFlower(content->requireBlock("base:flower").rt.id), idFlower(content->blocks.require("base:flower").rt.id),
idBazalt(content->requireBlock("base:bazalt").rt.id) {} idBazalt(content->blocks.require("base:bazalt").rt.id) {}