refactor Content
This commit is contained in:
parent
f3c5afa1ab
commit
ee9f1639e9
@ -12,62 +12,30 @@
|
||||
#include "../logic/scripting/scripting.hpp"
|
||||
|
||||
ContentIndices::ContentIndices(
|
||||
std::vector<Block*> blockDefs,
|
||||
std::vector<ItemDef*> itemDefs
|
||||
) : blockDefs(std::move(blockDefs)),
|
||||
itemDefs(std::move(itemDefs))
|
||||
std::vector<Block*> blocks,
|
||||
std::vector<ItemDef*> items
|
||||
) : blocks(std::move(blocks)),
|
||||
items(std::move(items))
|
||||
{}
|
||||
|
||||
Content::Content(
|
||||
std::unique_ptr<ContentIndices> indices,
|
||||
std::unique_ptr<DrawGroups> drawGroups,
|
||||
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs,
|
||||
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs,
|
||||
ContentUnitDefs<Block> blocks,
|
||||
ContentUnitDefs<ItemDef> items,
|
||||
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
|
||||
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
|
||||
) : blockDefs(std::move(blockDefs)),
|
||||
itemDefs(std::move(itemDefs)),
|
||||
indices(std::move(indices)),
|
||||
) : indices(std::move(indices)),
|
||||
packs(std::move(packs)),
|
||||
blockMaterials(std::move(blockMaterials)),
|
||||
blocks(std::move(blocks)),
|
||||
items(std::move(items)),
|
||||
drawGroups(std::move(drawGroups))
|
||||
{}
|
||||
|
||||
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 {
|
||||
auto found = blockMaterials.find(id);
|
||||
if (found == blockMaterials.end()) {
|
||||
|
||||
@ -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
|
||||
class ContentIndices {
|
||||
std::vector<Block*> blockDefs;
|
||||
std::vector<ItemDef*> itemDefs;
|
||||
public:
|
||||
ContentUnitIndices<Block> blocks;
|
||||
ContentUnitIndices<ItemDef> items;
|
||||
|
||||
ContentIndices(
|
||||
std::vector<Block*> blockDefs,
|
||||
std::vector<ItemDef*> itemDefs
|
||||
);
|
||||
};
|
||||
|
||||
inline Block* getBlockDef(blockid_t id) const {
|
||||
if (id >= blockDefs.size())
|
||||
template<class T>
|
||||
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 blockDefs[id];
|
||||
}
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
inline ItemDef* getItemDef(itemid_t id) const {
|
||||
if (id >= itemDefs.size())
|
||||
return nullptr;
|
||||
return itemDefs[id];
|
||||
}
|
||||
|
||||
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();
|
||||
T& require(const std::string& id) const {
|
||||
const auto& found = defs.find(id);
|
||||
if (found == defs.end()) {
|
||||
throw std::runtime_error("missing content unit "+id);
|
||||
}
|
||||
return *found->second;
|
||||
}
|
||||
};
|
||||
|
||||
/* Content is a definitions repository */
|
||||
/// @brief Content is a definitions repository
|
||||
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::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs;
|
||||
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials;
|
||||
public:
|
||||
ContentUnitDefs<Block> blocks;
|
||||
ContentUnitDefs<ItemDef> items;
|
||||
std::unique_ptr<DrawGroups> const drawGroups;
|
||||
|
||||
Content(
|
||||
std::unique_ptr<ContentIndices> indices,
|
||||
std::unique_ptr<DrawGroups> drawGroups,
|
||||
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs,
|
||||
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs,
|
||||
ContentUnitDefs<Block> blocks,
|
||||
ContentUnitDefs<ItemDef> items,
|
||||
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
|
||||
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
|
||||
);
|
||||
@ -106,15 +124,8 @@ public:
|
||||
inline ContentIndices* getIndices() const {
|
||||
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 ContentPackRuntime* getPackRuntime(const std::string& id) const;
|
||||
|
||||
const std::unordered_map<std::string, std::unique_ptr<BlockMaterial>>& getBlockMaterials() const;
|
||||
|
||||
@ -99,11 +99,11 @@ std::unique_ptr<Content> ContentBuilder::build() {
|
||||
|
||||
// Now, it's time to resolve foreign keys
|
||||
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) {
|
||||
def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id;
|
||||
def->rt.placingBlock = content->blocks.require(def->placingBlock).rt.id;
|
||||
}
|
||||
|
||||
return content;
|
||||
|
||||
@ -10,29 +10,45 @@
|
||||
|
||||
#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) {
|
||||
auto* indices = content->getIndices();
|
||||
for (size_t i = 0; i < blocksCount; i++) {
|
||||
blocks.push_back(i);
|
||||
}
|
||||
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("");
|
||||
}
|
||||
init(blocks, blockNames, indices->blocks, blocksCount);
|
||||
init(items, itemNames, indices->items, itemsCount);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < itemsCount; i++) {
|
||||
items.push_back(i);
|
||||
}
|
||||
for (size_t i = 0; i < indices->countItemDefs(); i++) {
|
||||
itemNames.push_back(indices->getItemDef(i)->name);
|
||||
}
|
||||
for (size_t i = indices->countItemDefs(); i < itemsCount; i++) {
|
||||
itemNames.emplace_back();
|
||||
template<class T>
|
||||
static void setup_lut(ContentLUT* lut, const ContentUnitDefs<T>& defs, dynamic::List* list) {
|
||||
if (list) {
|
||||
for (size_t i = 0; i < list->size(); i++) {
|
||||
std::string name = list->str(i);
|
||||
if (auto def = defs.find(name)) {
|
||||
lut->setBlock(i, name, def->rt.id);
|
||||
} 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(
|
||||
const fs::path& filename,
|
||||
const Content* content
|
||||
@ -42,38 +58,13 @@ std::shared_ptr<ContentLUT> ContentLUT::create(
|
||||
auto itemlist = root->list("items");
|
||||
|
||||
auto* indices = content->getIndices();
|
||||
size_t blocks_c = blocklist
|
||||
? std::max(blocklist->size(), indices->countBlockDefs())
|
||||
: indices->countBlockDefs();
|
||||
size_t items_c = itemlist
|
||||
? std::max(itemlist->size(), indices->countItemDefs())
|
||||
: indices->countItemDefs();
|
||||
size_t blocks_c = get_entries_count(indices->blocks, blocklist);
|
||||
size_t items_c = get_entries_count(indices->items, itemlist);
|
||||
|
||||
auto lut = std::make_shared<ContentLUT>(content, blocks_c, items_c);
|
||||
|
||||
if (blocklist) {
|
||||
for (size_t i = 0; i < blocklist->size(); i++) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
setup_lut(lut.get(), content->blocks, blocklist);
|
||||
setup_lut(lut.get(), content->items, itemlist);
|
||||
|
||||
if (lut->hasContentReorder() || lut->hasMissingContent()) {
|
||||
return lut;
|
||||
|
||||
@ -96,17 +96,16 @@ void WorldFiles::writeIndices(const ContentIndices* indices) {
|
||||
dynamic::Map root;
|
||||
uint count;
|
||||
auto& blocks = root.putList("blocks");
|
||||
count = indices->countBlockDefs();
|
||||
count = indices->blocks.count();
|
||||
for (uint i = 0; i < count; i++) {
|
||||
const Block* def = indices->getBlockDef(i);
|
||||
const Block* def = indices->blocks.get(i);
|
||||
blocks.put(def->name);
|
||||
}
|
||||
|
||||
auto& items = root.putList("items");
|
||||
count = indices->countItemDefs();
|
||||
count = indices->items.count();
|
||||
for (uint i = 0; i < count; i++) {
|
||||
const ItemDef* def = indices->getItemDef(i);
|
||||
items.put(def->name);
|
||||
items.put(indices->items.get(i)->name);
|
||||
}
|
||||
|
||||
files::write_json(getIndicesFile(), &root);
|
||||
|
||||
@ -14,11 +14,11 @@
|
||||
|
||||
ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) {
|
||||
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");
|
||||
|
||||
for (uint i = 0; i < indices->countBlockDefs(); i++) {
|
||||
Block* def = indices->getBlockDef(i);
|
||||
for (uint i = 0; i < indices->blocks.count(); i++) {
|
||||
Block* def = indices->blocks.get(i);
|
||||
for (uint side = 0; side < 6; side++) {
|
||||
const std::string& tex = def->textureFaces[side];
|
||||
if (atlas->has(tex)) {
|
||||
|
||||
@ -98,7 +98,7 @@ std::shared_ptr<UINode> create_debug_panel(
|
||||
}));
|
||||
panel->add(create_label([=](){
|
||||
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);
|
||||
} else {
|
||||
return std::wstring {L"name: void"};
|
||||
|
||||
@ -102,9 +102,9 @@ std::shared_ptr<InventoryView> Hud::createContentAccess() {
|
||||
auto indices = content->getIndices();
|
||||
auto inventory = player->getInventory();
|
||||
|
||||
int itemsCount = indices->countItemDefs();
|
||||
size_t itemsCount = indices->items.count();
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@ -123,7 +123,7 @@ std::unique_ptr<Atlas> BlocksPreview::build(
|
||||
const Content* content
|
||||
) {
|
||||
auto indices = content->getIndices();
|
||||
size_t count = indices->countBlockDefs();
|
||||
size_t count = indices->blocks.count();
|
||||
size_t iconSize = ITEM_ICON_SIZE;
|
||||
|
||||
auto shader = assets->get<Shader>("ui3d");
|
||||
@ -153,7 +153,7 @@ std::unique_ptr<Atlas> BlocksPreview::build(
|
||||
|
||||
fbo.bind();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
auto def = indices->getBlockDef(i);
|
||||
auto def = indices->blocks.get(i);
|
||||
atlas->getTexture()->bind();
|
||||
builder.add(def->name, draw(cache, shader, &fbo, &batch, def, iconSize));
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ BlocksRenderer::BlocksRenderer(
|
||||
CHUNK_W + voxelBufferPadding*2,
|
||||
CHUNK_H,
|
||||
CHUNK_D + voxelBufferPadding*2);
|
||||
blockDefsCache = content->getIndices()->getBlockDefs();
|
||||
blockDefsCache = content->getIndices()->blocks.getDefs();
|
||||
}
|
||||
|
||||
BlocksRenderer::~BlocksRenderer() {
|
||||
|
||||
@ -179,7 +179,7 @@ void WorldRenderer::renderLevel(
|
||||
{
|
||||
auto inventory = player->getInventory();
|
||||
ItemStack& stack = inventory->getSlot(player->getChosenSlot());
|
||||
auto item = indices->getItemDef(stack.getItemId());
|
||||
auto item = indices->items.get(stack.getItemId());
|
||||
float multiplier = 0.5f;
|
||||
shader->uniform3f("u_torchlightColor",
|
||||
item->emission[0] / 15.0f * multiplier,
|
||||
@ -202,11 +202,11 @@ void WorldRenderer::renderLevel(
|
||||
skybox->unbind();
|
||||
}
|
||||
|
||||
void WorldRenderer::renderBlockSelection(Camera* camera, Shader* linesShader) {
|
||||
void WorldRenderer::renderBlockSelection() {
|
||||
const auto& selection = player->selection;
|
||||
auto indices = level->content->getIndices();
|
||||
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::vec3 point = selection.hitPosition;
|
||||
const glm::vec3 norm = selection.normal;
|
||||
@ -230,7 +230,7 @@ void WorldRenderer::renderLines(Camera* camera, Shader* linesShader) {
|
||||
linesShader->use();
|
||||
linesShader->uniformMatrix("u_projview", camera->getProjView());
|
||||
if (player->selection.vox.id != BLOCK_VOID) {
|
||||
renderBlockSelection(camera, linesShader);
|
||||
renderBlockSelection();
|
||||
}
|
||||
if (player->debug) {
|
||||
level->entities->renderDebug(*lineBatch);
|
||||
|
||||
@ -45,10 +45,11 @@ class WorldRenderer {
|
||||
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader);
|
||||
|
||||
/// @brief Render block selection lines
|
||||
void renderBlockSelection();
|
||||
|
||||
/// @brief Render lines (selection and debug)
|
||||
/// @param camera active camera
|
||||
/// @param linesShader shader used
|
||||
void renderBlockSelection(Camera* camera, Shader* linesShader);
|
||||
|
||||
void renderLines(Camera* camera, Shader* linesShader);
|
||||
|
||||
/// @brief Render all debug lines (chunks borders, coord system guides)
|
||||
|
||||
@ -121,7 +121,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) {
|
||||
itemid_t itemid = bound->getItemId();
|
||||
if (itemid != prevItem) {
|
||||
if (itemid) {
|
||||
auto def = content->getIndices()->getItemDef(itemid);
|
||||
auto def = content->getIndices()->items.get(itemid);
|
||||
tooltip = util::pascal_case(
|
||||
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 indices = content->getIndices();
|
||||
|
||||
ItemDef* item = indices->getItemDef(stack.getItemId());
|
||||
ItemDef* item = indices->items.get(stack.getItemId());
|
||||
switch (item->iconType) {
|
||||
case item_icon_type::none:
|
||||
break;
|
||||
case item_icon_type::block: {
|
||||
const Block& cblock = content->requireBlock(item->icon);
|
||||
const Block& cblock = content->blocks.require(item->icon);
|
||||
batch->texture(previews->getTexture());
|
||||
|
||||
UVRegion region = previews->get(cblock.name);
|
||||
@ -268,7 +268,7 @@ void SlotView::clicked(gui::GUI* gui, mousecode button) {
|
||||
stack.setCount(halfremain);
|
||||
}
|
||||
} else {
|
||||
auto stackDef = content->getIndices()->getItemDef(stack.getItemId());
|
||||
auto stackDef = content->getIndices()->items.get(stack.getItemId());
|
||||
if (stack.isEmpty()) {
|
||||
stack.set(grabbed);
|
||||
stack.setCount(1);
|
||||
|
||||
@ -22,7 +22,7 @@ bool ItemStack::accepts(const ItemStack& other) const {
|
||||
}
|
||||
|
||||
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);
|
||||
if (isEmpty()) {
|
||||
set(ItemStack(item.getItemId(), count));
|
||||
|
||||
@ -81,7 +81,7 @@ void LightSolver::solve(){
|
||||
}
|
||||
}
|
||||
|
||||
const Block* const* blockDefs = contentIds->getBlockDefs();
|
||||
const Block* const* blockDefs = contentIds->blocks.getDefs();
|
||||
while (!addqueue.empty()){
|
||||
const lightentry entry = addqueue.front();
|
||||
addqueue.pop();
|
||||
|
||||
@ -36,7 +36,7 @@ void Lighting::clear(){
|
||||
}
|
||||
|
||||
void Lighting::prebuildSkyLight(Chunk* chunk, const ContentIndices* indices){
|
||||
auto* blockDefs = indices->getBlockDefs();
|
||||
const auto* blockDefs = indices->blocks.getDefs();
|
||||
|
||||
int highestPoint = 0;
|
||||
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){
|
||||
const Block* const* blockDefs = content->getIndices()->getBlockDefs();
|
||||
const auto blockDefs = content->getIndices()->blocks.getDefs();
|
||||
|
||||
Chunk* chunk = chunks->getChunk(cx, cz);
|
||||
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* solverS = this->solverS.get();
|
||||
|
||||
const Block* const* blockDefs = content->getIndices()->getBlockDefs();
|
||||
const Chunk* chunk = chunks->getChunk(cx, cz);
|
||||
auto blockDefs = content->getIndices()->blocks.getDefs();
|
||||
auto chunk = chunks->getChunk(cx, cz);
|
||||
|
||||
for (uint y = 0; y < CHUNK_H; y++){
|
||||
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){
|
||||
Block* block = content->getIndices()->getBlockDef(id);
|
||||
Block* block = content->getIndices()->blocks.get(id);
|
||||
solverR->remove(x,y,z);
|
||||
solverG->remove(x,y,z);
|
||||
solverB->remove(x,y,z);
|
||||
|
||||
@ -83,7 +83,7 @@ void BlocksController::updateBlock(int x, int y, int z) {
|
||||
voxel* vox = chunks->get(x, y, z);
|
||||
if (vox == nullptr)
|
||||
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)) {
|
||||
breakBlock(nullptr, def, x, y, z);
|
||||
return;
|
||||
@ -109,10 +109,10 @@ void BlocksController::onBlocksTick(int tickid, int parts) {
|
||||
auto content = level->content;
|
||||
auto indices = content->getIndices();
|
||||
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)
|
||||
continue;
|
||||
auto def = indices->getBlockDef(id);
|
||||
auto def = indices->blocks.get(id);
|
||||
auto interval = def->tickInterval;
|
||||
if (def->rt.funcsset.onblockstick && tickid / parts % interval == 0) {
|
||||
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 bz = random.rand() % CHUNK_D;
|
||||
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) {
|
||||
scripting::random_update_block(
|
||||
block,
|
||||
@ -167,7 +167,7 @@ int64_t BlocksController::createBlockInventory(int x, int y, int z) {
|
||||
auto inv = chunk->getBlockInventory(lx, y, lz);
|
||||
if (inv == nullptr) {
|
||||
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;
|
||||
if (invsize == 0) {
|
||||
return 0;
|
||||
|
||||
@ -203,7 +203,7 @@ void PlayerController::onFootstep() {
|
||||
int z = std::floor(pos.z+half.z*offsetZ);
|
||||
auto vox = level->chunks->get(x, y, z);
|
||||
if (vox) {
|
||||
auto def = level->content->getIndices()->getBlockDef(vox->id);
|
||||
auto def = level->content->getIndices()->blocks.get(vox->id);
|
||||
if (!def->obstacle)
|
||||
continue;
|
||||
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) {
|
||||
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;
|
||||
auto inventory = player->getInventory();
|
||||
size_t slotid = inventory->findSlotByItem(id, 0, 10);
|
||||
@ -356,7 +356,7 @@ voxel* PlayerController::updateSelection(float maxDistance) {
|
||||
selection.actualPosition = iend;
|
||||
if (selectedState.segment) {
|
||||
selection.position = chunks->seekOrigin(
|
||||
iend, indices->getBlockDef(selection.vox.id), selectedState
|
||||
iend, indices->blocks.get(selection.vox.id), selectedState
|
||||
);
|
||||
auto origin = chunks->get(iend);
|
||||
if (origin && origin->id != vox->id) {
|
||||
@ -430,7 +430,7 @@ void PlayerController::updateInteraction() {
|
||||
|
||||
auto inventory = player->getInventory();
|
||||
const ItemStack& stack = inventory->getSlot(player->getChosenSlot());
|
||||
ItemDef* item = indices->getItemDef(stack.getItemId());
|
||||
ItemDef* item = indices->items.get(stack.getItemId());
|
||||
|
||||
auto vox = updateSelection(maxDistance);
|
||||
if (vox == nullptr) {
|
||||
@ -446,7 +446,7 @@ void PlayerController::updateInteraction() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto target = indices->getBlockDef(vox->id);
|
||||
auto target = indices->blocks.get(vox->id);
|
||||
if (lclick && target->breakable){
|
||||
onBlockInteraction(
|
||||
iend, target,
|
||||
@ -467,7 +467,7 @@ void PlayerController::updateInteraction() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto def = indices->getBlockDef(item->rt.placingBlock);
|
||||
auto def = indices->blocks.get(item->rt.placingBlock);
|
||||
if (def && rclick) {
|
||||
processRightClick(def, target);
|
||||
}
|
||||
|
||||
@ -14,10 +14,10 @@ using namespace scripting;
|
||||
static Block* require_block(lua::State* L) {
|
||||
auto indices = content->getIndices();
|
||||
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 indices->getBlockDef(id);
|
||||
return indices->blocks.get(id);
|
||||
}
|
||||
|
||||
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) {
|
||||
return lua::pushinteger(L, indices->countBlockDefs());
|
||||
return lua::pushinteger(L, indices->blocks.count());
|
||||
}
|
||||
|
||||
static int l_index(lua::State* L) {
|
||||
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) {
|
||||
@ -78,7 +78,7 @@ static int l_seek_origin(lua::State* L) {
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
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));
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ static int l_set(lua::State* L) {
|
||||
auto id = lua::tointeger(L, 4);
|
||||
auto state = lua::tointeger(L, 5);
|
||||
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;
|
||||
}
|
||||
if (!level->chunks->get(x, y, z)) {
|
||||
@ -120,7 +120,7 @@ static int l_get_x(lua::State* L) {
|
||||
if (vox == nullptr) {
|
||||
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) {
|
||||
return lua::pushivec3(L, 1, 0, 0);
|
||||
} else {
|
||||
@ -137,7 +137,7 @@ static int l_get_y(lua::State* L) {
|
||||
if (vox == nullptr) {
|
||||
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) {
|
||||
return lua::pushivec3(L, 0, 1, 0);
|
||||
} else {
|
||||
@ -154,7 +154,7 @@ static int l_get_z(lua::State* L) {
|
||||
if (vox == nullptr) {
|
||||
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) {
|
||||
return lua::pushivec3(L, 0, 0, 1);
|
||||
} else {
|
||||
|
||||
@ -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)
|
||||
);
|
||||
}
|
||||
auto def = content->getIndices()->getBlockDef(vox->id);
|
||||
auto def = content->getIndices()->blocks.get(vox->id);
|
||||
auto assets = engine->getAssets();
|
||||
auto layout = assets->get<UiDocument>(def->uiLayout);
|
||||
if (layout == nullptr) {
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
using namespace scripting;
|
||||
|
||||
static void validate_itemid(itemid_t id) {
|
||||
if (id >= indices->countItemDefs()) {
|
||||
if (id >= indices->items.count()) {
|
||||
throw std::runtime_error("invalid item id");
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,30 +8,30 @@ using namespace scripting;
|
||||
static int l_item_name(lua::State* L) {
|
||||
auto indices = content->getIndices();
|
||||
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;
|
||||
}
|
||||
auto def = indices->getItemDef(id);
|
||||
auto def = indices->items.get(id);
|
||||
return lua::pushstring(L, def->name);
|
||||
}
|
||||
|
||||
static int l_item_index(lua::State* L) {
|
||||
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) {
|
||||
auto indices = content->getIndices();
|
||||
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;
|
||||
}
|
||||
auto def = indices->getItemDef(id);
|
||||
auto def = indices->items.get(id);
|
||||
return lua::pushinteger(L, def->stackSize);
|
||||
}
|
||||
|
||||
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 [] = {
|
||||
|
||||
@ -66,7 +66,7 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z){
|
||||
return ∅
|
||||
}
|
||||
}
|
||||
const Block* def = indices->getBlockDef(v->id);
|
||||
const auto def = indices->blocks.get(v->id);
|
||||
if (def->obstacle) {
|
||||
glm::ivec3 offset {};
|
||||
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);
|
||||
if (v == nullptr)
|
||||
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) {
|
||||
voxel* v = get(x, y, z);
|
||||
if (v == nullptr)
|
||||
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) {
|
||||
voxel* v = get(x, y, z);
|
||||
if (v == nullptr)
|
||||
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){
|
||||
@ -240,7 +240,7 @@ bool Chunks::checkReplaceability(const Block* def, blockstate state, glm::ivec3
|
||||
pos += rotation.axisY * sy;
|
||||
pos += rotation.axisZ * sz;
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
@ -316,7 +316,7 @@ void Chunks::setRotation(int32_t x, int32_t y, int32_t z, uint8_t index) {
|
||||
if (vox == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto def = indices->getBlockDef(vox->id);
|
||||
auto def = indices->blocks.get(vox->id);
|
||||
if (!def->rotatable || vox->state.rotation == index) {
|
||||
return;
|
||||
}
|
||||
@ -351,7 +351,7 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state)
|
||||
|
||||
// block finalization
|
||||
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) {
|
||||
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
|
||||
auto newdef = indices->getBlockDef(id);
|
||||
auto newdef = indices->blocks.get(id);
|
||||
vox.id = id;
|
||||
vox.state = state;
|
||||
chunk->setModifiedAndUnsaved();
|
||||
@ -429,7 +429,7 @@ voxel* Chunks::rayCast(
|
||||
if (voxel == nullptr){
|
||||
return nullptr;
|
||||
}
|
||||
const auto def = indices->getBlockDef(voxel->id);
|
||||
const auto def = indices->blocks.get(voxel->id);
|
||||
if (def->selectable){
|
||||
end.x = px + t * dx;
|
||||
end.y = py + t * dy;
|
||||
@ -553,7 +553,7 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis
|
||||
if (voxel == nullptr) {
|
||||
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->rt.solid) {
|
||||
const std::vector<AABB>& hitboxes = def->rotatable
|
||||
|
||||
@ -40,7 +40,7 @@ void ChunksStorage::remove(int x, int z) {
|
||||
static void verifyLoadedChunk(ContentIndices* indices, Chunk* chunk) {
|
||||
for (size_t i = 0; i < CHUNK_VOL; i++) {
|
||||
blockid_t id = chunk->voxels[i].id;
|
||||
if (indices->getBlockDef(id) == nullptr) {
|
||||
if (indices->blocks.get(id) == nullptr) {
|
||||
auto logline = logger.error();
|
||||
logline << "corruped block detected at " << i << " of chunk ";
|
||||
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
|
||||
// 25.06.2024: not now
|
||||
void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const {
|
||||
const Content* content = level->content;
|
||||
auto indices = content->getIndices();
|
||||
@ -137,7 +138,7 @@ void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const {
|
||||
voxels[vidx] = cvoxels[cidx];
|
||||
light_t light = clights[cidx];
|
||||
if (backlight) {
|
||||
const Block* block = indices->getBlockDef(voxels[vidx].id);
|
||||
auto block = indices->blocks.get(voxels[vidx].id);
|
||||
if (block->lightPassing) {
|
||||
light = Lightmap::combine(
|
||||
min(15, Lightmap::extract(light, 0)+1),
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
#include "../content/Content.hpp"
|
||||
|
||||
WorldGenerator::WorldGenerator(const Content* content)
|
||||
: idStone(content->requireBlock("base:stone").rt.id),
|
||||
idDirt(content->requireBlock("base:dirt").rt.id),
|
||||
idGrassBlock(content->requireBlock("base:grass_block").rt.id),
|
||||
idSand(content->requireBlock("base:sand").rt.id),
|
||||
idWater(content->requireBlock("base:water").rt.id),
|
||||
idWood(content->requireBlock("base:wood").rt.id),
|
||||
idLeaves(content->requireBlock("base:leaves").rt.id),
|
||||
idGrass(content->requireBlock("base:grass").rt.id),
|
||||
idFlower(content->requireBlock("base:flower").rt.id),
|
||||
idBazalt(content->requireBlock("base:bazalt").rt.id) {}
|
||||
: idStone(content->blocks.require("base:stone").rt.id),
|
||||
idDirt(content->blocks.require("base:dirt").rt.id),
|
||||
idGrassBlock(content->blocks.require("base:grass_block").rt.id),
|
||||
idSand(content->blocks.require("base:sand").rt.id),
|
||||
idWater(content->blocks.require("base:water").rt.id),
|
||||
idWood(content->blocks.require("base:wood").rt.id),
|
||||
idLeaves(content->blocks.require("base:leaves").rt.id),
|
||||
idGrass(content->blocks.require("base:grass").rt.id),
|
||||
idFlower(content->blocks.require("base:flower").rt.id),
|
||||
idBazalt(content->blocks.require("base:bazalt").rt.id) {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user