refactor: change pointer parameters to references for Level and Content in various classes

This commit is contained in:
MihailRis 2024-12-25 18:53:53 +03:00
parent ef2c0b2370
commit c1b311f3c4
41 changed files with 258 additions and 251 deletions

View File

@ -159,9 +159,9 @@ std::optional<WorldInfo> WorldFiles::readWorldInfo() {
} }
static void read_resources_data( static void read_resources_data(
const Content* content, const dv::value& list, ResourceType type const Content& content, const dv::value& list, ResourceType type
) { ) {
const auto& indices = content->getIndices(type); const auto& indices = content.getIndices(type);
for (size_t i = 0; i < list.size(); i++) { for (size_t i = 0; i < list.size(); i++) {
auto& map = list[i]; auto& map = list[i];
const auto& name = map["name"].asString(); const auto& name = map["name"].asString();
@ -174,7 +174,7 @@ static void read_resources_data(
} }
} }
bool WorldFiles::readResourcesData(const Content* content) { bool WorldFiles::readResourcesData(const Content& content) {
fs::path file = getResourcesFile(); fs::path file = getResourcesFile();
if (!fs::is_regular_file(file)) { if (!fs::is_regular_file(file)) {
logger.warning() << "resources.json does not exists"; logger.warning() << "resources.json does not exists";

View File

@ -49,7 +49,7 @@ public:
void createDirectories(); void createDirectories();
std::optional<WorldInfo> readWorldInfo(); std::optional<WorldInfo> readWorldInfo();
bool readResourcesData(const Content* content); bool readResourcesData(const Content& content);
static void createContentIndicesCache( static void createContentIndicesCache(
const ContentIndices* indices, dv::value& root const ContentIndices* indices, dv::value& root

View File

@ -23,18 +23,18 @@ LevelFrontend::LevelFrontend(
controller(controller), controller(controller),
assets(assets), assets(assets),
contentCache(std::make_unique<ContentGfxCache>( contentCache(std::make_unique<ContentGfxCache>(
*level.content, assets, settings.graphics level.content, assets, settings.graphics
)) { )) {
assets.store( assets.store(
BlocksPreview::build( BlocksPreview::build(
*contentCache, assets, *level.content->getIndices() *contentCache, assets, *level.content.getIndices()
), ),
"block-previews" "block-previews"
); );
controller->getBlocksController()->listenBlockInteraction( controller->getBlocksController()->listenBlockInteraction(
[currentPlayer, controller, &assets](auto player, const auto& pos, const auto& def, BlockInteraction type) { [currentPlayer, controller, &assets](auto player, const auto& pos, const auto& def, BlockInteraction type) {
const auto& level = *controller->getLevel(); const auto& level = *controller->getLevel();
auto material = level.content->findBlockMaterial(def.material); auto material = level.content.findBlockMaterial(def.material);
if (material == nullptr) { if (material == nullptr) {
return; return;
} }

View File

@ -138,7 +138,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->blocks.get(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 {

View File

@ -107,8 +107,8 @@ std::shared_ptr<UINode> HudElement::getNode() const {
} }
std::shared_ptr<InventoryView> Hud::createContentAccess() { std::shared_ptr<InventoryView> Hud::createContentAccess() {
auto content = frontend.getLevel().content; auto& content = frontend.getLevel().content;
auto indices = content->getIndices(); auto indices = content.getIndices();
auto inventory = player.getInventory(); auto inventory = player.getInventory();
size_t itemsCount = indices->items.count(); size_t itemsCount = indices->items.count();
@ -129,14 +129,14 @@ std::shared_ptr<InventoryView> Hud::createContentAccess() {
InventoryBuilder builder; InventoryBuilder builder;
builder.addGrid(8, itemsCount-1, glm::vec2(), glm::vec4(8, 8, 12, 8), true, slotLayout); builder.addGrid(8, itemsCount-1, glm::vec2(), glm::vec4(8, 8, 12, 8), true, slotLayout);
auto view = builder.build(); auto view = builder.build();
view->bind(accessInventory, content); view->bind(accessInventory, &content);
view->setMargin(glm::vec4()); view->setMargin(glm::vec4());
return view; return view;
} }
std::shared_ptr<InventoryView> Hud::createHotbar() { std::shared_ptr<InventoryView> Hud::createHotbar() {
auto inventory = player.getInventory(); auto inventory = player.getInventory();
auto content = frontend.getLevel().content; auto& content = frontend.getLevel().content;
SlotLayout slotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr); SlotLayout slotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr);
InventoryBuilder builder; InventoryBuilder builder;
@ -144,7 +144,7 @@ std::shared_ptr<InventoryView> Hud::createHotbar() {
auto view = builder.build(); auto view = builder.build();
view->setId("hud.hotbar"); view->setId("hud.hotbar");
view->setOrigin(glm::vec2(view->getSize().x/2, 0)); view->setOrigin(glm::vec2(view->getSize().x/2, 0));
view->bind(inventory, content); view->bind(inventory, &content);
view->setInteractive(false); view->setInteractive(false);
return view; return view;
} }
@ -375,14 +375,14 @@ void Hud::update(bool visible) {
/// @brief Show inventory on the screen and turn on inventory mode blocking movement /// @brief Show inventory on the screen and turn on inventory mode blocking movement
void Hud::openInventory() { void Hud::openInventory() {
auto content = frontend.getLevel().content; auto& content = frontend.getLevel().content;
showExchangeSlot(); showExchangeSlot();
inventoryOpen = true; inventoryOpen = true;
auto inventory = player.getInventory(); auto inventory = player.getInventory();
auto inventoryDocument = assets.get<UiDocument>("core:inventory"); auto inventoryDocument = assets.get<UiDocument>("core:inventory");
inventoryView = std::dynamic_pointer_cast<InventoryView>(inventoryDocument->getRoot()); inventoryView = std::dynamic_pointer_cast<InventoryView>(inventoryDocument->getRoot());
inventoryView->bind(inventory, content); inventoryView->bind(inventory, &content);
add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false)); add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false));
add(HudElement(hud_element_mode::inventory_bound, nullptr, exchangeSlot, false)); add(HudElement(hud_element_mode::inventory_bound, nullptr, exchangeSlot, false));
} }
@ -396,7 +396,7 @@ std::shared_ptr<Inventory> Hud::openInventory(
closeInventory(); closeInventory();
} }
const auto& level = frontend.getLevel(); const auto& level = frontend.getLevel();
auto content = level.content; auto& content = level.content;
secondInvView = std::dynamic_pointer_cast<InventoryView>(doc->getRoot()); secondInvView = std::dynamic_pointer_cast<InventoryView>(doc->getRoot());
if (secondInvView == nullptr) { if (secondInvView == nullptr) {
throw std::runtime_error("secondary UI root element must be 'inventory'"); throw std::runtime_error("secondary UI root element must be 'inventory'");
@ -411,7 +411,7 @@ std::shared_ptr<Inventory> Hud::openInventory(
if (inv == nullptr) { if (inv == nullptr) {
inv = level.inventories->createVirtual(secondInvView->getSlotsCount()); inv = level.inventories->createVirtual(secondInvView->getSlotsCount());
} }
secondInvView->bind(inv, content); secondInvView->bind(inv, &content);
add(HudElement(hud_element_mode::inventory_bound, doc, secondUI, false)); add(HudElement(hud_element_mode::inventory_bound, doc, secondUI, false));
return inv; return inv;
} }
@ -427,7 +427,7 @@ void Hud::openInventory(
} }
auto& level = frontend.getLevel(); auto& level = frontend.getLevel();
const auto& chunks = *player.chunks; const auto& chunks = *player.chunks;
auto content = level.content; auto& content = level.content;
blockUI = std::dynamic_pointer_cast<InventoryView>(doc->getRoot()); blockUI = std::dynamic_pointer_cast<InventoryView>(doc->getRoot());
if (blockUI == nullptr) { if (blockUI == nullptr) {
@ -442,8 +442,8 @@ void Hud::openInventory(
if (blockinv == nullptr) { if (blockinv == nullptr) {
blockinv = level.inventories->createVirtual(blockUI->getSlotsCount()); blockinv = level.inventories->createVirtual(blockUI->getSlotsCount());
} }
chunks.getChunkByVoxel(block.x, block.y, block.z)->flags.unsaved = true; chunks.getChunkByVoxel(block)->flags.unsaved = true;
blockUI->bind(blockinv, content); blockUI->bind(blockinv, &content);
blockPos = block; blockPos = block;
currentblockid = chunks.require(block.x, block.y, block.z).id; currentblockid = chunks.require(block.x, block.y, block.z).id;
add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false)); add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false));
@ -451,12 +451,12 @@ void Hud::openInventory(
void Hud::showExchangeSlot() { void Hud::showExchangeSlot() {
auto& level = frontend.getLevel(); auto& level = frontend.getLevel();
auto content = level.content; auto& content = level.content;
exchangeSlotInv = level.inventories->createVirtual(1); exchangeSlotInv = level.inventories->createVirtual(1);
exchangeSlot = std::make_shared<SlotView>( exchangeSlot = std::make_shared<SlotView>(
SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr) SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr)
); );
exchangeSlot->bind(exchangeSlotInv->getId(), exchangeSlotInv->getSlot(0), content); exchangeSlot->bind(exchangeSlotInv->getId(), exchangeSlotInv->getSlot(0), &content);
exchangeSlot->setColor(glm::vec4()); exchangeSlot->setColor(glm::vec4());
exchangeSlot->setInteractive(false); exchangeSlot->setInteractive(false);
exchangeSlot->setZIndex(1); exchangeSlot->setZIndex(1);
@ -487,7 +487,7 @@ void Hud::openPermanent(UiDocument* doc) {
auto invview = std::dynamic_pointer_cast<InventoryView>(root); auto invview = std::dynamic_pointer_cast<InventoryView>(root);
if (invview) { if (invview) {
invview->bind(player.getInventory(), frontend.getLevel().content); invview->bind(player.getInventory(), &frontend.getLevel().content);
} }
add(HudElement(hud_element_mode::permanent, doc, doc->getRoot(), false)); add(HudElement(hud_element_mode::permanent, doc, doc->getRoot(), false));
} }
@ -501,7 +501,7 @@ void Hud::dropExchangeSlot() {
} }
ItemStack& stack = slotView->getStack(); ItemStack& stack = slotView->getStack();
auto indices = frontend.getLevel().content->getIndices(); auto indices = frontend.getLevel().content.getIndices();
if (auto invView = std::dynamic_pointer_cast<InventoryView>(blockUI)) { if (auto invView = std::dynamic_pointer_cast<InventoryView>(blockUI)) {
invView->getInventory()->move(stack, indices); invView->getInventory()->move(stack, indices);
} }

View File

@ -92,8 +92,8 @@ LevelScreen::LevelScreen(Engine& engine, std::unique_ptr<Level> levelPtr)
} }
void LevelScreen::initializeContent() { void LevelScreen::initializeContent() {
auto content = controller->getLevel()->content; auto& content = controller->getLevel()->content;
for (auto& entry : content->getPacks()) { for (auto& entry : content.getPacks()) {
initializePack(entry.second.get()); initializePack(entry.second.get());
} }
scripting::on_frontend_init(hud.get(), worldRenderer.get()); scripting::on_frontend_init(hud.get(), worldRenderer.get());

View File

@ -44,8 +44,7 @@ void BlockWrapsRenderer::draw(const BlockWrapper& wrapper) {
return; return;
} }
if (vox->id != BLOCK_VOID) { if (vox->id != BLOCK_VOID) {
const auto& def = const auto& def = level.content.getIndices()->blocks.require(vox->id);
level.content->getIndices()->blocks.require(vox->id);
switch (def.model) { switch (def.model) {
case BlockModel::block: case BlockModel::block:
batch->cube( batch->cube(

View File

@ -608,7 +608,7 @@ void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) {
voxelsBuffer->setPosition( voxelsBuffer->setPosition(
chunk->x * CHUNK_W - voxelBufferPadding, 0, chunk->x * CHUNK_W - voxelBufferPadding, 0,
chunk->z * CHUNK_D - voxelBufferPadding); chunk->z * CHUNK_D - voxelBufferPadding);
chunks->getVoxels(voxelsBuffer.get(), settings.graphics.backlight.get()); chunks->getVoxels(*voxelsBuffer, settings.graphics.backlight.get());
if (voxelsBuffer->pickBlockId( if (voxelsBuffer->pickBlockId(
chunk->x * CHUNK_W, 0, chunk->z * CHUNK_D chunk->x * CHUNK_W, 0, chunk->z * CHUNK_D

View File

@ -35,7 +35,7 @@ public:
settings.graphics.denseRender.get() settings.graphics.denseRender.get()
? settings.graphics.chunkMaxVerticesDense.get() ? settings.graphics.chunkMaxVerticesDense.get()
: settings.graphics.chunkMaxVertices.get(), : settings.graphics.chunkMaxVertices.get(),
*level.content, level.content,
cache, cache,
settings settings
) { ) {
@ -87,7 +87,7 @@ ChunksRenderer::ChunksRenderer(
threadPool.setStopOnFail(false); threadPool.setStopOnFail(false);
renderer = std::make_unique<BlocksRenderer>( renderer = std::make_unique<BlocksRenderer>(
settings.graphics.chunkMaxVertices.get(), settings.graphics.chunkMaxVertices.get(),
*level->content, cache, settings level->content, cache, settings
); );
logger.info() << "created " << threadPool.getWorkersCount() << " workers"; logger.info() << "created " << threadPool.getWorkersCount() << " workers";
} }

View File

@ -86,7 +86,7 @@ void Decorator::update(
currentIndex = (currentIndex + BIG_PRIME) % UPDATE_BLOCKS; currentIndex = (currentIndex + BIG_PRIME) % UPDATE_BLOCKS;
const auto& chunks = *player.chunks; const auto& chunks = *player.chunks;
const auto& indices = *level.content->getIndices(); const auto& indices = *level.content.getIndices();
int lx = index % UPDATE_AREA_DIAMETER; int lx = index % UPDATE_AREA_DIAMETER;
int lz = (index / UPDATE_AREA_DIAMETER) % UPDATE_AREA_DIAMETER; int lz = (index / UPDATE_AREA_DIAMETER) % UPDATE_AREA_DIAMETER;
@ -108,7 +108,7 @@ void Decorator::update(float delta, const Camera& camera) {
update(delta, pos - glm::ivec3(UPDATE_AREA_DIAMETER / 2), pos); update(delta, pos - glm::ivec3(UPDATE_AREA_DIAMETER / 2), pos);
} }
const auto& chunks = *player.chunks; const auto& chunks = *player.chunks;
const auto& indices = *level.content->getIndices(); const auto& indices = *level.content.getIndices();
auto iter = blockEmitters.begin(); auto iter = blockEmitters.begin();
while (iter != blockEmitters.end()) { while (iter != blockEmitters.end()) {
auto emitter = renderer.particles->getEmitter(iter->second); auto emitter = renderer.particles->getEmitter(iter->second);

View File

@ -120,7 +120,7 @@ void WorldRenderer::setupWorldShader(
shader.uniform3f("u_cameraPos", camera.position); shader.uniform3f("u_cameraPos", camera.position);
shader.uniform1i("u_cubemap", 1); shader.uniform1i("u_cubemap", 1);
auto indices = level.content->getIndices(); auto indices = level.content.getIndices();
// Light emission when an emissive item is chosen // Light emission when an emissive item is chosen
{ {
auto inventory = player.getInventory(); auto inventory = player.getInventory();
@ -193,7 +193,7 @@ void WorldRenderer::renderLevel(
void WorldRenderer::renderBlockSelection() { 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->blocks.require(id); auto& block = indices->blocks.require(id);
const glm::ivec3 pos = player.selection.position; const glm::ivec3 pos = player.selection.position;
@ -241,7 +241,7 @@ void WorldRenderer::renderHands(
const Camera& camera, float delta const Camera& camera, float delta
) { ) {
auto& entityShader = assets.require<Shader>("entity"); auto& entityShader = assets.require<Shader>("entity");
auto indices = level.content->getIndices(); auto indices = level.content.getIndices();
// get current chosen item // get current chosen item
const auto& inventory = player.getInventory(); const auto& inventory = player.getInventory();
@ -275,7 +275,7 @@ void WorldRenderer::renderHands(
); );
prevRotation = rotation; prevRotation = rotation;
auto offset = -(camera.position - player.getPosition()); auto offset = -(camera.position - player.getPosition());
float angle = glm::radians(player.cam.x - 90); float angle = glm::radians(player.rotation.x - 90);
float cos = glm::cos(angle); float cos = glm::cos(angle);
float sin = glm::sin(angle); float sin = glm::sin(angle);
@ -368,8 +368,7 @@ void WorldRenderer::renderBlockOverlay(const DrawContext& wctx) {
int z = std::floor(player.currentCamera->position.z); int z = std::floor(player.currentCamera->position.z);
auto block = player.chunks->get(x, y, z); auto block = player.chunks->get(x, y, z);
if (block && block->id) { if (block && block->id) {
const auto& def = const auto& def = level.content.getIndices()->blocks.require(block->id);
level.content->getIndices()->blocks.require(block->id);
if (def.overlayTexture.empty()) { if (def.overlayTexture.empty()) {
return; return;
} }

View File

@ -9,8 +9,8 @@
#include "voxels/voxel.hpp" #include "voxels/voxel.hpp"
#include "voxels/Block.hpp" #include "voxels/Block.hpp"
LightSolver::LightSolver(const ContentIndices* contentIds, Chunks* chunks, int channel) LightSolver::LightSolver(const ContentIndices& contentIds, Chunks& chunks, int channel)
: blockDefs(contentIds->blocks.getDefs()), : blockDefs(contentIds.blocks.getDefs()),
chunks(chunks), chunks(chunks),
channel(channel) { channel(channel) {
} }
@ -18,7 +18,7 @@ LightSolver::LightSolver(const ContentIndices* contentIds, Chunks* chunks, int c
void LightSolver::add(int x, int y, int z, int emission) { void LightSolver::add(int x, int y, int z, int emission) {
if (emission <= 1) if (emission <= 1)
return; return;
Chunk* chunk = chunks->getChunkByVoxel(x, y, z); Chunk* chunk = chunks.getChunkByVoxel(x, y, z);
if (chunk == nullptr) if (chunk == nullptr)
return; return;
ubyte light = chunk->lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel); ubyte light = chunk->lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
@ -32,11 +32,11 @@ void LightSolver::add(int x, int y, int z, int emission) {
void LightSolver::add(int x, int y, int z) { void LightSolver::add(int x, int y, int z) {
assert (chunks != nullptr); assert (chunks != nullptr);
add(x,y,z, chunks->getLight(x,y,z, channel)); add(x,y,z, chunks.getLight(x,y,z, channel));
} }
void LightSolver::remove(int x, int y, int z) { void LightSolver::remove(int x, int y, int z) {
Chunk* chunk = chunks->getChunkByVoxel(x, y, z); Chunk* chunk = chunks.getChunkByVoxel(x, y, z);
if (chunk == nullptr) if (chunk == nullptr)
return; return;
@ -68,7 +68,7 @@ void LightSolver::solve(){
int y = entry.y+coords[imul3+1]; int y = entry.y+coords[imul3+1];
int z = entry.z+coords[imul3+2]; int z = entry.z+coords[imul3+2];
Chunk* chunk = chunks->getChunkByVoxel(x,y,z); Chunk* chunk = chunks.getChunkByVoxel(x,y,z);
if (chunk) { if (chunk) {
int lx = x - chunk->x * CHUNK_W; int lx = x - chunk->x * CHUNK_W;
int lz = z - chunk->z * CHUNK_D; int lz = z - chunk->z * CHUNK_D;
@ -76,7 +76,7 @@ void LightSolver::solve(){
ubyte light = chunk->lightmap.get(lx,y,lz, channel); ubyte light = chunk->lightmap.get(lx,y,lz, channel);
if (light != 0 && light == entry.light-1){ if (light != 0 && light == entry.light-1){
voxel* vox = chunks->get(x, y, z); voxel* vox = chunks.get(x, y, z);
if (vox && vox->id != 0) { if (vox && vox->id != 0) {
const Block* block = blockDefs[vox->id]; const Block* block = blockDefs[vox->id];
if (uint8_t emission = block->emission[channel]) { if (uint8_t emission = block->emission[channel]) {
@ -105,7 +105,7 @@ void LightSolver::solve(){
int y = entry.y+coords[imul3+1]; int y = entry.y+coords[imul3+1];
int z = entry.z+coords[imul3+2]; int z = entry.z+coords[imul3+2];
Chunk* chunk = chunks->getChunkByVoxel(x,y,z); Chunk* chunk = chunks.getChunkByVoxel(x,y,z);
if (chunk) { if (chunk) {
int lx = x - chunk->x * CHUNK_W; int lx = x - chunk->x * CHUNK_W;
int lz = z - chunk->z * CHUNK_D; int lz = z - chunk->z * CHUNK_D;

View File

@ -17,10 +17,10 @@ class LightSolver {
std::queue<lightentry> addqueue; std::queue<lightentry> addqueue;
std::queue<lightentry> remqueue; std::queue<lightentry> remqueue;
const Block* const* blockDefs; const Block* const* blockDefs;
Chunks* chunks; Chunks& chunks;
int channel; int channel;
public: public:
LightSolver(const ContentIndices* contentIds, Chunks* chunks, int channel); LightSolver(const ContentIndices& contentIds, Chunks& chunks, int channel);
void add(int x, int y, int z); void add(int x, int y, int z);
void add(int x, int y, int z, int emission); void add(int x, int y, int z, int emission);

View File

@ -11,9 +11,9 @@
#include <memory> #include <memory>
Lighting::Lighting(const Content* content, Chunks* chunks) Lighting::Lighting(const Content& content, Chunks& chunks)
: content(content), chunks(chunks) { : content(content), chunks(chunks) {
auto indices = content->getIndices(); auto& indices = *content.getIndices();
solverR = std::make_unique<LightSolver>(indices, chunks, 0); solverR = std::make_unique<LightSolver>(indices, chunks, 0);
solverG = std::make_unique<LightSolver>(indices, chunks, 1); solverG = std::make_unique<LightSolver>(indices, chunks, 1);
solverB = std::make_unique<LightSolver>(indices, chunks, 2); solverB = std::make_unique<LightSolver>(indices, chunks, 2);
@ -23,7 +23,7 @@ Lighting::Lighting(const Content* content, Chunks* chunks)
Lighting::~Lighting() = default; Lighting::~Lighting() = default;
void Lighting::clear(){ void Lighting::clear(){
const auto& chunks = this->chunks->getChunks(); const auto& chunks = this->chunks.getChunks();
for (size_t index = 0; index < chunks.size(); index++){ for (size_t index = 0; index < chunks.size(); index++){
auto chunk = chunks[index]; auto chunk = chunks[index];
if (chunk == nullptr) if (chunk == nullptr)
@ -35,34 +35,34 @@ void Lighting::clear(){
} }
} }
void Lighting::prebuildSkyLight(Chunk* chunk, const ContentIndices* indices){ void Lighting::prebuildSkyLight(Chunk& chunk, const ContentIndices& indices){
const auto* blockDefs = indices->blocks.getDefs(); 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++){
for (int x = 0; x < CHUNK_W; x++){ for (int x = 0; x < CHUNK_W; x++){
for (int y = CHUNK_H-1; y >= 0; y--){ for (int y = CHUNK_H-1; y >= 0; y--){
int index = (y * CHUNK_D + z) * CHUNK_W + x; int index = (y * CHUNK_D + z) * CHUNK_W + x;
voxel& vox = chunk->voxels[index]; voxel& vox = chunk.voxels[index];
const Block* block = blockDefs[vox.id]; const Block* block = blockDefs[vox.id];
if (!block->skyLightPassing) { if (!block->skyLightPassing) {
if (highestPoint < y) if (highestPoint < y)
highestPoint = y; highestPoint = y;
break; break;
} }
chunk->lightmap.setS(x,y,z, 15); chunk.lightmap.setS(x,y,z, 15);
} }
} }
} }
if (highestPoint < CHUNK_H-1) if (highestPoint < CHUNK_H-1)
highestPoint++; highestPoint++;
chunk->lightmap.highestPoint = highestPoint; chunk.lightmap.highestPoint = highestPoint;
} }
void Lighting::buildSkyLight(int cx, int cz){ void Lighting::buildSkyLight(int cx, int cz){
const auto blockDefs = content->getIndices()->blocks.getDefs(); 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++){
for (int x = 0; x < CHUNK_W; x++){ for (int x = 0; x < CHUNK_W; x++){
int gx = x + cx * CHUNK_W; int gx = x + cx * CHUNK_W;
@ -93,8 +93,8 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand) {
auto& solverB = *this->solverB; auto& solverB = *this->solverB;
auto& solverS = *this->solverS; auto& solverS = *this->solverS;
auto blockDefs = content->getIndices()->blocks.getDefs(); auto blockDefs = content.getIndices()->blocks.getDefs();
auto 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++){
@ -151,7 +151,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){
const auto& block = content->getIndices()->blocks.require(id); const auto& block = content.getIndices()->blocks.require(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);
@ -160,9 +160,9 @@ void Lighting::onBlockSet(int x, int y, int z, blockid_t id){
solverR->solve(); solverR->solve();
solverG->solve(); solverG->solve();
solverB->solve(); solverB->solve();
if (chunks->getLight(x,y+1,z, 3) == 0xF){ if (chunks.getLight(x,y+1,z, 3) == 0xF){
for (int i = y; i >= 0; i--){ for (int i = y; i >= 0; i--){
voxel* vox = chunks->get(x,i,z); voxel* vox = chunks.get(x,i,z);
if ((vox == nullptr || vox->id != 0) && block.skyLightPassing) if ((vox == nullptr || vox->id != 0) && block.skyLightPassing)
break; break;
solverS->add(x,i,z, 0xF); solverS->add(x,i,z, 0xF);
@ -183,7 +183,7 @@ void Lighting::onBlockSet(int x, int y, int z, blockid_t id){
solverS->remove(x,y,z); solverS->remove(x,y,z);
for (int i = y-1; i >= 0; i--){ for (int i = y-1; i >= 0; i--){
solverS->remove(x,i,z); solverS->remove(x,i,z);
if (i == 0 || chunks->get(x,i-1,z)->id != 0){ if (i == 0 || chunks.get(x,i-1,z)->id != 0){
break; break;
} }
} }

View File

@ -9,14 +9,14 @@ class Chunks;
class LightSolver; class LightSolver;
class Lighting { class Lighting {
const Content* const content; const Content& content;
Chunks* chunks; Chunks& chunks;
std::unique_ptr<LightSolver> solverR; std::unique_ptr<LightSolver> solverR;
std::unique_ptr<LightSolver> solverG; std::unique_ptr<LightSolver> solverG;
std::unique_ptr<LightSolver> solverB; std::unique_ptr<LightSolver> solverB;
std::unique_ptr<LightSolver> solverS; std::unique_ptr<LightSolver> solverS;
public: public:
Lighting(const Content* content, Chunks* chunks); Lighting(const Content& content, Chunks& chunks);
~Lighting(); ~Lighting();
void clear(); void clear();
@ -24,5 +24,5 @@ public:
void onChunkLoaded(int cx, int cz, bool expand); void onChunkLoaded(int cx, int cz, bool expand);
void onBlockSet(int x, int y, int z, blockid_t id); void onBlockSet(int x, int y, int z, blockid_t id);
static void prebuildSkyLight(Chunk* chunk, const ContentIndices* indices); static void prebuildSkyLight(Chunk& chunk, const ContentIndices& indices);
}; };

View File

@ -39,7 +39,7 @@ void BlocksController::updateSides(int x, int y, int z) {
void BlocksController::updateSides(int x, int y, int z, int w, int h, int d) { void BlocksController::updateSides(int x, int y, int z, int w, int h, int d) {
voxel* vox = blocks_agent::get(chunks, x, y, z); voxel* vox = blocks_agent::get(chunks, x, y, z);
const auto& def = level.content->getIndices()->blocks.require(vox->id); const auto& def = level.content.getIndices()->blocks.require(vox->id);
const auto& rot = def.rotations.variants[vox->state.rotation]; const auto& rot = def.rotations.variants[vox->state.rotation];
const auto& xaxis = rot.axisX; const auto& xaxis = rot.axisX;
const auto& yaxis = rot.axisY; const auto& yaxis = rot.axisY;
@ -85,7 +85,7 @@ void BlocksController::placeBlock(
if (voxel == nullptr) { if (voxel == nullptr) {
return; return;
} }
const auto& prevDef = level.content->getIndices()->blocks.require(voxel->id); const auto& prevDef = level.content.getIndices()->blocks.require(voxel->id);
scripting::on_block_replaced(player, prevDef, {x, y, z}); scripting::on_block_replaced(player, prevDef, {x, y, z});
onBlockInteraction( onBlockInteraction(
@ -106,7 +106,7 @@ void BlocksController::placeBlock(
void BlocksController::updateBlock(int x, int y, int z) { void BlocksController::updateBlock(int x, int y, int z) {
voxel* vox = blocks_agent::get(chunks, x, y, z); voxel* vox = blocks_agent::get(chunks, x, y, z);
if (vox == nullptr) return; if (vox == nullptr) return;
const auto& def = level.content->getIndices()->blocks.require(vox->id); const auto& def = level.content.getIndices()->blocks.require(vox->id);
if (def.grounded) { if (def.grounded) {
const auto& vec = get_ground_direction(def, vox->state.rotation); const auto& vec = get_ground_direction(def, vox->state.rotation);
if (!blocks_agent::is_solid_at(chunks, x + vec.x, y + vec.y, z + vec.z)) { if (!blocks_agent::is_solid_at(chunks, x + vec.x, y + vec.y, z + vec.z)) {
@ -132,7 +132,7 @@ void BlocksController::update(float delta, uint padding) {
} }
void BlocksController::onBlocksTick(int tickid, int parts) { void BlocksController::onBlocksTick(int tickid, int parts) {
const auto& indices = level.content->getIndices()->blocks; const auto& indices = level.content.getIndices()->blocks;
int tickRate = blocksTickClock.getTickRate(); int tickRate = blocksTickClock.getTickRate();
for (size_t id = 0; id < indices.count(); id++) { for (size_t id = 0; id < indices.count(); id++) {
if ((id + tickid) % parts != 0) continue; if ((id + tickid) % parts != 0) continue;
@ -169,7 +169,7 @@ void BlocksController::randomTick(
} }
void BlocksController::randomTick(int tickid, int parts, uint padding) { void BlocksController::randomTick(int tickid, int parts, uint padding) {
auto indices = level.content->getIndices(); auto indices = level.content.getIndices();
std::set<uint64_t> chunksIterated; std::set<uint64_t> chunksIterated;
@ -218,7 +218,7 @@ int64_t BlocksController::createBlockInventory(int x, int y, int z) {
int lz = z - chunk->z * CHUNK_D; int lz = z - chunk->z * CHUNK_D;
auto inv = chunk->getBlockInventory(lx, y, lz); auto inv = chunk->getBlockInventory(lx, y, lz);
if (inv == nullptr) { if (inv == nullptr) {
const auto& indices = level.content->getIndices()->blocks; const auto& indices = level.content.getIndices()->blocks;
auto& def = indices.require(chunk->voxels[vox_index(lx, y, lz)].id); auto& def = indices.require(chunk->voxels[vox_index(lx, y, lz)].id);
int invsize = def.inventorySize; int invsize = def.inventorySize;
if (invsize == 0) { if (invsize == 0) {

View File

@ -24,7 +24,7 @@ const uint MIN_SURROUNDING = 9;
ChunksController::ChunksController(Level& level) ChunksController::ChunksController(Level& level)
: level(level), : level(level),
generator(std::make_unique<WorldGenerator>( generator(std::make_unique<WorldGenerator>(
level.content->generators.require(level.getWorld()->getGenerator()), level.content.generators.require(level.getWorld()->getGenerator()),
level.content, level.content,
level.getWorld()->getSeed() level.getWorld()->getSeed()
)) {} )) {}
@ -141,7 +141,7 @@ void ChunksController::createChunk(const Player& player, int x, int z) const {
chunk->updateHeights(); chunk->updateHeights();
if (!chunkFlags.loadedLights) { if (!chunkFlags.loadedLights) {
Lighting::prebuildSkyLight(chunk.get(), level.content->getIndices()); Lighting::prebuildSkyLight(*chunk, *level.content.getIndices());
} }
chunkFlags.loaded = true; chunkFlags.loaded = true;
chunkFlags.ready = true; chunkFlags.ready = true;

View File

@ -152,7 +152,7 @@ static void load_world(
auto& packs = engine.getContentPacks(); auto& packs = engine.getContentPacks();
auto& settings = engine.getSettings(); auto& settings = engine.getSettings();
auto level = World::load(worldFiles, settings, content, packs); auto level = World::load(worldFiles, settings, *content, packs);
engine.onWorldOpen(std::move(level)); engine.onWorldOpen(std::move(level));
} catch (const world_load_error& error) { } catch (const world_load_error& error) {
guiutil::alert( guiutil::alert(
@ -164,7 +164,7 @@ static void load_world(
} }
void EngineController::openWorld(const std::string& name, bool confirmConvert) { void EngineController::openWorld(const std::string& name, bool confirmConvert) {
auto& paths = engine.getPaths(); const auto& paths = engine.getPaths();
auto folder = paths.getWorldsFolder() / fs::u8path(name); auto folder = paths.getWorldsFolder() / fs::u8path(name);
auto worldFile = folder / fs::u8path("world.json"); auto worldFile = folder / fs::u8path("world.json");
if (!fs::exists(worldFile)) { if (!fs::exists(worldFile)) {
@ -245,7 +245,7 @@ void EngineController::createWorld(
folder, folder,
seed, seed,
engine.getSettings(), engine.getSettings(),
engine.getContent(), *engine.getContent(),
engine.getContentPacks() engine.getContentPacks()
); );
if (!engine.isHeadless()) { if (!engine.isHeadless()) {

View File

@ -28,7 +28,7 @@ LevelController::LevelController(
playerTickClock(20, 3) { playerTickClock(20, 3) {
if (clientPlayer) { if (clientPlayer) {
chunks->lighting = std::make_unique<Lighting>( chunks->lighting = std::make_unique<Lighting>(
level->content, clientPlayer->chunks.get() level->content, *clientPlayer->chunks
); );
} }
blocks = std::make_unique<BlocksController>( blocks = std::make_unique<BlocksController>(

View File

@ -54,30 +54,32 @@ void CameraControl::refresh() {
} }
void CameraControl::updateMouse(PlayerInput& input) { void CameraControl::updateMouse(PlayerInput& input) {
glm::vec3& cam = player.cam; glm::vec3& rotation = player.rotation;
float sensitivity = float sensitivity =
(input.zoom ? settings.sensitivity.get() / 4.f (input.zoom ? settings.sensitivity.get() / 4.f
: settings.sensitivity.get()); : settings.sensitivity.get());
auto d = glm::degrees(Events::delta / (float)Window::height * sensitivity); auto d = glm::degrees(Events::delta / (float)Window::height * sensitivity);
cam.x -= d.x; rotation.x -= d.x;
cam.y -= d.y; rotation.y -= d.y;
if (cam.y < -89.9f) { if (rotation.y < -89.9f) {
cam.y = -89.9f; rotation.y = -89.9f;
} else if (cam.y > 89.9f) { } else if (rotation.y > 89.9f) {
cam.y = 89.9f; rotation.y = 89.9f;
} }
if (cam.x > 180.f) { if (rotation.x > 180.f) {
cam.x -= 360.f; rotation.x -= 360.f;
} else if (cam.x < -180.f) { } else if (rotation.x < -180.f) {
cam.x += 360.f; rotation.x += 360.f;
} }
camera->rotation = glm::mat4(1.0f); camera->rotation = glm::mat4(1.0f);
camera->rotate( camera->rotate(
glm::radians(cam.y), glm::radians(cam.x), glm::radians(cam.z) glm::radians(rotation.y),
glm::radians(rotation.x),
glm::radians(rotation.z)
); );
} }
@ -219,7 +221,7 @@ void PlayerController::onFootstep(const Hitbox& hitbox) {
int z = std::floor(pos.z + half.z * offsetZ); int z = std::floor(pos.z + half.z * offsetZ);
auto vox = player.chunks->get(x, y, z); auto vox = player.chunks->get(x, y, z);
if (vox) { if (vox) {
auto& def = level.content->getIndices()->blocks.require(vox->id); auto& def = level.content.getIndices()->blocks.require(vox->id);
if (!def.obstacle) { if (!def.obstacle) {
continue; continue;
} }
@ -340,7 +342,7 @@ static int determine_rotation(
} }
voxel* PlayerController::updateSelection(float maxDistance) { voxel* PlayerController::updateSelection(float maxDistance) {
auto indices = level.content->getIndices(); auto indices = level.content.getIndices();
auto& chunks = *player.chunks; auto& chunks = *player.chunks;
auto camera = player.fpCamera.get(); auto camera = player.fpCamera.get();
auto& selection = player.selection; auto& selection = player.selection;
@ -476,7 +478,7 @@ void PlayerController::updateEntityInteraction(
} }
void PlayerController::updateInteraction(float delta) { void PlayerController::updateInteraction(float delta) {
auto indices = level.content->getIndices(); auto indices = level.content.getIndices();
auto chunks = player.chunks.get(); auto chunks = player.chunks.get();
const auto& selection = player.selection; const auto& selection = player.selection;

View File

@ -133,7 +133,7 @@ static int l_get_x(lua::State* L) {
if (vox == nullptr) { if (vox == nullptr) {
return lua::pushivec_stack(L, glm::ivec3(1, 0, 0)); return lua::pushivec_stack(L, glm::ivec3(1, 0, 0));
} }
const auto& def = level->content->getIndices()->blocks.require(vox->id); const auto& def = level->content.getIndices()->blocks.require(vox->id);
if (!def.rotatable) { if (!def.rotatable) {
return lua::pushivec_stack(L, glm::ivec3(1, 0, 0)); return lua::pushivec_stack(L, glm::ivec3(1, 0, 0));
} else { } else {
@ -150,7 +150,7 @@ static int l_get_y(lua::State* L) {
if (vox == nullptr) { if (vox == nullptr) {
return lua::pushivec_stack(L, glm::ivec3(0, 1, 0)); return lua::pushivec_stack(L, glm::ivec3(0, 1, 0));
} }
const auto& def = level->content->getIndices()->blocks.require(vox->id); const auto& def = level->content.getIndices()->blocks.require(vox->id);
if (!def.rotatable) { if (!def.rotatable) {
return lua::pushivec_stack(L, glm::ivec3(0, 1, 0)); return lua::pushivec_stack(L, glm::ivec3(0, 1, 0));
} else { } else {
@ -167,7 +167,7 @@ static int l_get_z(lua::State* L) {
if (vox == nullptr) { if (vox == nullptr) {
return lua::pushivec_stack(L, glm::ivec3(0, 0, 1)); return lua::pushivec_stack(L, glm::ivec3(0, 0, 1));
} }
const auto& def = level->content->getIndices()->blocks.require(vox->id); const auto& def = level->content.getIndices()->blocks.require(vox->id);
if (!def.rotatable) { if (!def.rotatable) {
return lua::pushivec_stack(L, glm::ivec3(0, 0, 1)); return lua::pushivec_stack(L, glm::ivec3(0, 0, 1));
} else { } else {
@ -367,7 +367,7 @@ static int l_place(lua::State* L) {
if (!blocks_agent::get(*level->chunks, x, y, z)) { if (!blocks_agent::get(*level->chunks, x, y, z)) {
return 0; return 0;
} }
const auto def = level->content->getIndices()->blocks.get(id); const auto def = level->content.getIndices()->blocks.get(id);
if (def == nullptr) { if (def == nullptr) {
throw std::runtime_error( throw std::runtime_error(
"there is no block with index " + std::to_string(id) "there is no block with index " + std::to_string(id)
@ -389,7 +389,7 @@ static int l_destruct(lua::State* L) {
if (vox == nullptr) { if (vox == nullptr) {
return 0; return 0;
} }
auto& def = level->content->getIndices()->blocks.require(vox->id); auto& def = level->content.getIndices()->blocks.require(vox->id);
auto player = level->players->get(playerid); auto player = level->players->get(playerid);
controller->getBlocksController()->breakBlock(player, def, x, y, z); controller->getBlocksController()->breakBlock(player, def, x, y, z);
return 0; return 0;

View File

@ -60,7 +60,7 @@ static int l_set_vel(lua::State* L) {
static int l_get_rot(lua::State* L) { static int l_get_rot(lua::State* L) {
if (auto player = get_player(L, 1)) { if (auto player = get_player(L, 1)) {
return lua::pushvec_stack(L, player->cam); return lua::pushvec_stack(L, player->rotation);
} }
return 0; return 0;
} }
@ -70,17 +70,17 @@ static int l_set_rot(lua::State* L) {
if (!player) { if (!player) {
return 0; return 0;
} }
glm::vec3& cam = player->cam; glm::vec3& rotation = player->rotation;
auto x = lua::tonumber(L, 2); auto x = lua::tonumber(L, 2);
auto y = lua::tonumber(L, 3); auto y = lua::tonumber(L, 3);
auto z = cam.z; auto z = rotation.z;
if (lua::isnumber(L, 4)) { if (lua::isnumber(L, 4)) {
z = lua::tonumber(L, 4); z = lua::tonumber(L, 4);
} }
cam.x = x; rotation.x = x;
cam.y = y; rotation.y = y;
cam.z = z; rotation.z = z;
return 0; return 0;
} }

View File

@ -59,7 +59,7 @@ void Entity::setRig(const rigging::SkeletonConfig* rigConfig) {
); );
} }
Entities::Entities(Level* level) Entities::Entities(Level& level)
: level(level), sensorsTickClock(20, 3), updateTickClock(20, 3) { : level(level), sensorsTickClock(20, 3), updateTickClock(20, 3) {
} }
@ -117,7 +117,7 @@ entityid_t Entities::spawn(
dv::value saved, dv::value saved,
entityid_t uid entityid_t uid
) { ) {
auto skeleton = level->content->getSkeleton(def.skeletonName); auto skeleton = level.content.getSkeleton(def.skeletonName);
if (skeleton == nullptr) { if (skeleton == nullptr) {
throw std::runtime_error("skeleton " + def.skeletonName + " not found"); throw std::runtime_error("skeleton " + def.skeletonName + " not found");
} }
@ -190,7 +190,7 @@ void Entities::despawn(entityid_t id) {
void Entities::loadEntity(const dv::value& map) { void Entities::loadEntity(const dv::value& map) {
entityid_t uid = map["uid"].asInteger(); entityid_t uid = map["uid"].asInteger();
std::string defname = map["def"].asString(); std::string defname = map["def"].asString();
auto& def = level->content->entities.require(defname); auto& def = level.content.entities.require(defname);
spawn(def, {}, nullptr, map, uid); spawn(def, {}, nullptr, map, uid);
} }
@ -219,7 +219,7 @@ void Entities::loadEntity(const dv::value& map, Entity entity) {
std::string skeletonName = skeleton.config->getName(); std::string skeletonName = skeleton.config->getName();
map.at("skeleton").get(skeletonName); map.at("skeleton").get(skeletonName);
if (skeletonName != skeleton.config->getName()) { if (skeletonName != skeleton.config->getName()) {
skeleton.config = level->content->getSkeleton(skeletonName); skeleton.config = level.content.getSkeleton(skeletonName);
} }
if (auto found = map.at(COMP_SKELETON)) { if (auto found = map.at(COMP_SKELETON)) {
auto& skeletonmap = *found; auto& skeletonmap = *found;
@ -361,8 +361,8 @@ dv::value Entities::serialize(const std::vector<Entity>& entities) {
if (!entity.getDef().save.enabled) { if (!entity.getDef().save.enabled) {
continue; continue;
} }
level->entities->onSave(entity); level.entities->onSave(entity);
list.add(level->entities->serialize(entity)); list.add(level.entities->serialize(entity));
} }
return list; return list;
} }
@ -380,7 +380,7 @@ void Entities::clean() {
} else { } else {
auto& rigidbody = registry.get<Rigidbody>(it->second); auto& rigidbody = registry.get<Rigidbody>(it->second);
// todo: refactor // todo: refactor
auto physics = level->physics.get(); auto physics = level.physics.get();
for (auto& sensor : rigidbody.sensors) { for (auto& sensor : rigidbody.sensors) {
physics->removeSensor(&sensor); physics->removeSensor(&sensor);
} }
@ -428,7 +428,7 @@ void Entities::preparePhysics(float delta) {
auto parts = sensorsTickClock.getParts(); auto parts = sensorsTickClock.getParts();
auto view = registry.view<EntityId, Transform, Rigidbody>(); auto view = registry.view<EntityId, Transform, Rigidbody>();
auto physics = level->physics.get(); auto physics = level.physics.get();
std::vector<Sensor*> sensors; std::vector<Sensor*> sensors;
for (auto [entity, eid, transform, rigidbody] : view.each()) { for (auto [entity, eid, transform, rigidbody] : view.each()) {
if (!rigidbody.enabled) { if (!rigidbody.enabled) {
@ -447,7 +447,7 @@ void Entities::updatePhysics(float delta) {
preparePhysics(delta); preparePhysics(delta);
auto view = registry.view<EntityId, Transform, Rigidbody>(); auto view = registry.view<EntityId, Transform, Rigidbody>();
auto physics = level->physics.get(); auto physics = level.physics.get();
for (auto [entity, eid, transform, rigidbody] : view.each()) { for (auto [entity, eid, transform, rigidbody] : view.each()) {
if (!rigidbody.enabled || rigidbody.hitbox.type == BodyType::STATIC) { if (!rigidbody.enabled || rigidbody.hitbox.type == BodyType::STATIC) {
continue; continue;
@ -459,7 +459,7 @@ void Entities::updatePhysics(float delta) {
float vel = glm::length(prevVel); float vel = glm::length(prevVel);
int substeps = static_cast<int>(delta * vel * 20); int substeps = static_cast<int>(delta * vel * 20);
substeps = std::min(100, std::max(2, substeps)); substeps = std::min(100, std::max(2, substeps));
physics->step(*level->chunks, &hitbox, delta, substeps, eid.uid); physics->step(*level.chunks, hitbox, delta, substeps, eid.uid);
hitbox.linearDamping = hitbox.grounded * 24; hitbox.linearDamping = hitbox.grounded * 24;
transform.setPos(hitbox.position); transform.setPos(hitbox.position);
if (hitbox.grounded && !grounded) { if (hitbox.grounded && !grounded) {

View File

@ -166,7 +166,7 @@ public:
class Entities { class Entities {
entt::registry registry; entt::registry registry;
Level* level; Level& level;
std::unordered_map<entityid_t, entt::entity> entities; std::unordered_map<entityid_t, entt::entity> entities;
std::unordered_map<entt::entity, entityid_t> uids; std::unordered_map<entt::entity, entityid_t> uids;
entityid_t nextID = 1; entityid_t nextID = 1;
@ -184,7 +184,7 @@ public:
float distance; float distance;
}; };
Entities(Level* level); Entities(Level& level);
void clean(); void clean();
void updatePhysics(float delta); void updatePhysics(float delta);

View File

@ -17,6 +17,9 @@
#include "window/Events.hpp" #include "window/Events.hpp"
#include "world/Level.hpp" #include "world/Level.hpp"
#include "data/dv_util.hpp" #include "data/dv_util.hpp"
#include "debug/Logger.hpp"
static debug::Logger logger("player");
constexpr float CROUCH_SPEED_MUL = 0.35f; constexpr float CROUCH_SPEED_MUL = 0.35f;
constexpr float RUN_SPEED_MUL = 1.5f; constexpr float RUN_SPEED_MUL = 1.5f;
@ -28,7 +31,7 @@ constexpr float JUMP_FORCE = 8.0f;
constexpr int SPAWN_ATTEMPTS_PER_UPDATE = 64; constexpr int SPAWN_ATTEMPTS_PER_UPDATE = 64;
Player::Player( Player::Player(
Level* level, Level& level,
int64_t id, int64_t id,
const std::string& name, const std::string& name,
glm::vec3 position, glm::vec3 position,
@ -45,11 +48,11 @@ Player::Player(
inventory(std::move(inv)), inventory(std::move(inv)),
eid(eid), eid(eid),
chunks(std::make_unique<Chunks>( chunks(std::make_unique<Chunks>(
3, 3, 0, 0, level->events.get(), level->content->getIndices() 3, 3, 0, 0, level.events.get(), *level.content.getIndices()
)), )),
fpCamera(level->getCamera("core:first-person")), fpCamera(level.getCamera("core:first-person")),
spCamera(level->getCamera("core:third-person-front")), spCamera(level.getCamera("core:third-person-front")),
tpCamera(level->getCamera("core:third-person-back")), tpCamera(level.getCamera("core:third-person-back")),
currentCamera(fpCamera) { currentCamera(fpCamera) {
fpCamera->setFov(glm::radians(90.0f)); fpCamera->setFov(glm::radians(90.0f));
spCamera->setFov(glm::radians(90.0f)); spCamera->setFov(glm::radians(90.0f));
@ -60,17 +63,19 @@ Player::~Player() = default;
void Player::updateEntity() { void Player::updateEntity() {
if (eid == 0) { if (eid == 0) {
auto& def = level->content->entities.require("base:player"); auto& def = level.content.entities.require("base:player");
eid = level->entities->spawn(def, getPosition()); eid = level.entities->spawn(def, getPosition());
} else if (auto entity = level->entities->get(eid)) { } else if (auto entity = level.entities->get(eid)) {
position = entity->getTransform().pos; position = entity->getTransform().pos;
} else { } else if (chunks->getChunkByVoxel(position)) {
// TODO: check if chunk loaded logger.error() << "player entity despawned or deleted; "
"will be respawned";
eid = 0;
} }
} }
Hitbox* Player::getHitbox() { Hitbox* Player::getHitbox() {
if (auto entity = level->entities->get(eid)) { if (auto entity = level.entities->get(eid)) {
return &entity->getRigidbody().hitbox; return &entity->getRigidbody().hitbox;
} }
return nullptr; return nullptr;
@ -143,7 +148,7 @@ void Player::updateSelectedEntity() {
} }
void Player::postUpdate() { void Player::postUpdate() {
auto entity = level->entities->get(eid); auto entity = level.entities->get(eid);
if (!entity.has_value()) { if (!entity.has_value()) {
return; return;
} }
@ -168,12 +173,12 @@ void Player::postUpdate() {
if (body) { if (body) {
skeleton.pose.matrices[body->getIndex()] = glm::rotate( skeleton.pose.matrices[body->getIndex()] = glm::rotate(
glm::mat4(1.0f), glm::radians(cam.x), glm::vec3(0, 1, 0) glm::mat4(1.0f), glm::radians(rotation.x), glm::vec3(0, 1, 0)
); );
} }
if (head) { if (head) {
skeleton.pose.matrices[head->getIndex()] = glm::rotate( skeleton.pose.matrices[head->getIndex()] = glm::rotate(
glm::mat4(1.0f), glm::radians(cam.y), glm::vec3(1, 0, 0) glm::mat4(1.0f), glm::radians(rotation.y), glm::vec3(1, 0, 0)
); );
} }
} }
@ -181,7 +186,7 @@ void Player::postUpdate() {
void Player::teleport(glm::vec3 position) { void Player::teleport(glm::vec3 position) {
this->position = position; this->position = position;
if (auto entity = level->entities->get(eid)) { if (auto entity = level.entities->get(eid)) {
entity->getRigidbody().hitbox.position = position; entity->getRigidbody().hitbox.position = position;
entity->getTransform().setPos(position); entity->getTransform().setPos(position);
} }
@ -298,7 +303,7 @@ dv::value Player::serialize() const {
root["name"] = name; root["name"] = name;
root["position"] = dv::to_value(position); root["position"] = dv::to_value(position);
root["rotation"] = dv::to_value(cam); root["rotation"] = dv::to_value(rotation);
root["spawnpoint"] = dv::to_value(spawnpoint); root["spawnpoint"] = dv::to_value(spawnpoint);
root["flight"] = flight; root["flight"] = flight;
@ -310,10 +315,10 @@ dv::value Player::serialize() const {
root["entity"] = eid; root["entity"] = eid;
root["inventory"] = inventory->serialize(); root["inventory"] = inventory->serialize();
auto found = auto found =
std::find(level->cameras.begin(), level->cameras.end(), currentCamera); std::find(level.cameras.begin(), level.cameras.end(), currentCamera);
if (found != level->cameras.end()) { if (found != level.cameras.end()) {
root["camera"] = level->content->getIndices(ResourceType::CAMERA) root["camera"] = level.content.getIndices(ResourceType::CAMERA)
.getName(found - level->cameras.begin()); .getName(found - level.cameras.begin());
} }
return root; return root;
} }
@ -328,7 +333,7 @@ void Player::deserialize(const dv::value& src) {
fpCamera->position = position; fpCamera->position = position;
const auto& rotarr = src["rotation"]; const auto& rotarr = src["rotation"];
dv::get_vec(rotarr, cam); dv::get_vec(rotarr, rotation);
const auto& sparr = src["spawnpoint"]; const auto& sparr = src["spawnpoint"];
setSpawnPoint(glm::vec3( setSpawnPoint(glm::vec3(
@ -349,7 +354,7 @@ void Player::deserialize(const dv::value& src) {
if (src.has("camera")) { if (src.has("camera")) {
std::string name = src["camera"].asString(); std::string name = src["camera"].asString();
if (auto camera = level->getCamera(name)) { if (auto camera = level.getCamera(name)) {
currentCamera = camera; currentCamera = camera;
} }
} }

View File

@ -39,7 +39,7 @@ struct CursorSelection {
}; };
class Player : public Serializable { class Player : public Serializable {
Level* level; Level& level;
int64_t id; int64_t id;
std::string name; std::string name;
float speed; float speed;
@ -57,12 +57,12 @@ class Player : public Serializable {
public: public:
std::unique_ptr<Chunks> chunks; std::unique_ptr<Chunks> chunks;
std::shared_ptr<Camera> fpCamera, spCamera, tpCamera; std::shared_ptr<Camera> fpCamera, spCamera, tpCamera;
std::shared_ptr<Camera> currentCamera;; std::shared_ptr<Camera> currentCamera;
glm::vec3 cam {}; glm::vec3 rotation {};
CursorSelection selection {}; CursorSelection selection {};
Player( Player(
Level* level, Level& level,
int64_t id, int64_t id,
const std::string& name, const std::string& name,
glm::vec3 position, glm::vec3 position,

View File

@ -5,7 +5,7 @@
#include "world/Level.hpp" #include "world/Level.hpp"
#include "world/World.hpp" #include "world/World.hpp"
Players::Players(Level* level) : level(level) {} Players::Players(Level& level) : level(level) {}
void Players::add(std::unique_ptr<Player> player) { void Players::add(std::unique_ptr<Player> player) {
players[player->getId()] = std::move(player); players[player->getId()] = std::move(player);
@ -22,17 +22,17 @@ Player* Players::get(int64_t id) const {
Player* Players::create() { Player* Players::create() {
auto playerPtr = std::make_unique<Player>( auto playerPtr = std::make_unique<Player>(
level, level,
level->getWorld()->getInfo().nextPlayerId++, level.getWorld()->getInfo().nextPlayerId++,
"", "",
glm::vec3(0, DEF_PLAYER_Y, 0), glm::vec3(0, DEF_PLAYER_Y, 0),
DEF_PLAYER_SPEED, DEF_PLAYER_SPEED,
level->inventories->create(DEF_PLAYER_INVENTORY_SIZE), level.inventories->create(DEF_PLAYER_INVENTORY_SIZE),
0 0
); );
auto player = playerPtr.get(); auto player = playerPtr.get();
add(std::move(playerPtr)); add(std::move(playerPtr));
level->inventories->store(player->getInventory()); level.inventories->store(player->getInventory());
return player; return player;
} }
@ -57,7 +57,7 @@ void Players::deserialize(const dv::value& src) {
"", "",
glm::vec3(0, DEF_PLAYER_Y, 0), glm::vec3(0, DEF_PLAYER_Y, 0),
DEF_PLAYER_SPEED, DEF_PLAYER_SPEED,
level->inventories->create(DEF_PLAYER_INVENTORY_SIZE), level.inventories->create(DEF_PLAYER_INVENTORY_SIZE),
0 0
); );
auto player = playerPtr.get(); auto player = playerPtr.get();
@ -66,8 +66,8 @@ void Players::deserialize(const dv::value& src) {
auto& inventory = player->getInventory(); auto& inventory = player->getInventory();
// invalid inventory id pre 0.25 // invalid inventory id pre 0.25
if (inventory->getId() == 0) { if (inventory->getId() == 0) {
inventory->setId(level->getWorld()->getNextInventoryId()); inventory->setId(level.getWorld()->getNextInventoryId());
} }
level->inventories->store(player->getInventory()); level.inventories->store(player->getInventory());
} }
} }

View File

@ -14,12 +14,12 @@ class Level;
class Player; class Player;
class Players : public Serializable { class Players : public Serializable {
Level* level; Level& level;
std::unordered_map<int64_t, std::unique_ptr<Player>> players; std::unordered_map<int64_t, std::unique_ptr<Player>> players;
void add(std::unique_ptr<Player> player); void add(std::unique_ptr<Player> player);
public: public:
Players(Level* level); Players(Level& level);
Player* get(int64_t id) const; Player* get(int64_t id) const;

View File

@ -19,79 +19,79 @@ PhysicsSolver::PhysicsSolver(glm::vec3 gravity) : gravity(gravity) {
void PhysicsSolver::step( void PhysicsSolver::step(
const GlobalChunks& chunks, const GlobalChunks& chunks,
Hitbox* hitbox, Hitbox& hitbox,
float delta, float delta,
uint substeps, uint substeps,
entityid_t entity entityid_t entity
) { ) {
float dt = delta / static_cast<float>(substeps); float dt = delta / static_cast<float>(substeps);
float linearDamping = hitbox->linearDamping; float linearDamping = hitbox.linearDamping;
float s = 2.0f/BLOCK_AABB_GRID; float s = 2.0f/BLOCK_AABB_GRID;
const glm::vec3& half = hitbox->halfsize; const glm::vec3& half = hitbox.halfsize;
glm::vec3& pos = hitbox->position; glm::vec3& pos = hitbox.position;
glm::vec3& vel = hitbox->velocity; glm::vec3& vel = hitbox.velocity;
float gravityScale = hitbox->gravityScale; float gravityScale = hitbox.gravityScale;
bool prevGrounded = hitbox->grounded; bool prevGrounded = hitbox.grounded;
hitbox->grounded = false; hitbox.grounded = false;
for (uint i = 0; i < substeps; i++) { for (uint i = 0; i < substeps; i++) {
float px = pos.x; float px = pos.x;
float py = pos.y; float py = pos.y;
float pz = pos.z; float pz = pos.z;
vel += gravity * dt * gravityScale; vel += gravity * dt * gravityScale;
if (hitbox->type == BodyType::DYNAMIC) { if (hitbox.type == BodyType::DYNAMIC) {
colisionCalc(chunks, hitbox, vel, pos, half, colisionCalc(chunks, hitbox, vel, pos, half,
(prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f); (prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f);
} }
vel.x *= glm::max(0.0f, 1.0f - dt * linearDamping); vel.x *= glm::max(0.0f, 1.0f - dt * linearDamping);
if (hitbox->verticalDamping) { if (hitbox.verticalDamping) {
vel.y *= glm::max(0.0f, 1.0f - dt * linearDamping); vel.y *= glm::max(0.0f, 1.0f - dt * linearDamping);
} }
vel.z *= glm::max(0.0f, 1.0f - dt * linearDamping); vel.z *= glm::max(0.0f, 1.0f - dt * linearDamping);
pos += vel * dt + gravity * gravityScale * dt * dt * 0.5f; pos += vel * dt + gravity * gravityScale * dt * dt * 0.5f;
if (hitbox->grounded && pos.y < py) { if (hitbox.grounded && pos.y < py) {
pos.y = py; pos.y = py;
} }
if (hitbox->crouching && hitbox->grounded){ if (hitbox.crouching && hitbox.grounded){
float y = (pos.y-half.y-E); float y = (pos.y-half.y-E);
hitbox->grounded = false; hitbox.grounded = false;
for (int ix = 0; ix <= (half.x-E)*2/s; ix++) { for (int ix = 0; ix <= (half.x-E)*2/s; ix++) {
float x = (px-half.x+E) + ix * s; float x = (px-half.x+E) + ix * s;
for (int iz = 0; iz <= (half.z-E)*2/s; iz++){ for (int iz = 0; iz <= (half.z-E)*2/s; iz++){
float z = (pos.z-half.z+E) + iz * s; float z = (pos.z-half.z+E) + iz * s;
if (chunks.isObstacleAt(x,y,z)){ if (chunks.isObstacleAt(x,y,z)){
hitbox->grounded = true; hitbox.grounded = true;
break; break;
} }
} }
} }
if (!hitbox->grounded) { if (!hitbox.grounded) {
pos.z = pz; pos.z = pz;
} }
hitbox->grounded = false; hitbox.grounded = false;
for (int ix = 0; ix <= (half.x-E)*2/s; ix++) { for (int ix = 0; ix <= (half.x-E)*2/s; ix++) {
float x = (pos.x-half.x+E) + ix * s; float x = (pos.x-half.x+E) + ix * s;
for (int iz = 0; iz <= (half.z-E)*2/s; iz++){ for (int iz = 0; iz <= (half.z-E)*2/s; iz++){
float z = (pz-half.z+E) + iz * s; float z = (pz-half.z+E) + iz * s;
if (chunks.isObstacleAt(x,y,z)){ if (chunks.isObstacleAt(x,y,z)){
hitbox->grounded = true; hitbox.grounded = true;
break; break;
} }
} }
} }
if (!hitbox->grounded) { if (!hitbox.grounded) {
pos.x = px; pos.x = px;
} }
hitbox->grounded = true; hitbox.grounded = true;
} }
} }
AABB aabb; AABB aabb;
aabb.a = hitbox->position - hitbox->halfsize; aabb.a = hitbox.position - hitbox.halfsize;
aabb.b = hitbox->position + hitbox->halfsize; aabb.b = hitbox.position + hitbox.halfsize;
for (size_t i = 0; i < sensors.size(); i++) { for (size_t i = 0; i < sensors.size(); i++) {
auto& sensor = *sensors[i]; auto& sensor = *sensors[i];
if (sensor.entity == entity) { if (sensor.entity == entity) {
@ -105,7 +105,7 @@ void PhysicsSolver::step(
break; break;
case SensorType::RADIUS: case SensorType::RADIUS:
triggered = glm::distance2( triggered = glm::distance2(
hitbox->position, glm::vec3(sensor.calculated.radial)) hitbox.position, glm::vec3(sensor.calculated.radial))
< sensor.calculated.radial.w; < sensor.calculated.radial.w;
break; break;
} }
@ -205,7 +205,7 @@ static void calc_collision_pos(
void PhysicsSolver::colisionCalc( void PhysicsSolver::colisionCalc(
const GlobalChunks& chunks, const GlobalChunks& chunks,
Hitbox* hitbox, Hitbox& hitbox,
glm::vec3& vel, glm::vec3& vel,
glm::vec3& pos, glm::vec3& pos,
const glm::vec3 half, const glm::vec3 half,
@ -225,7 +225,7 @@ void PhysicsSolver::colisionCalc(
calc_collision_pos<2, 1, 0>(chunks, pos, vel, half, stepHeight, s); calc_collision_pos<2, 1, 0>(chunks, pos, vel, half, stepHeight, s);
if (calc_collision_neg<1, 0, 2>(chunks, pos, vel, half, stepHeight, s)) { if (calc_collision_neg<1, 0, 2>(chunks, pos, vel, half, stepHeight, s)) {
hitbox->grounded = true; hitbox.grounded = true;
} }
if (stepHeight > 0.0 && vel.y <= 0.0f){ if (stepHeight > 0.0 && vel.y <= 0.0f){
@ -273,7 +273,7 @@ bool PhysicsSolver::isBlockInside(int x, int y, int z, Hitbox* hitbox) {
} }
bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate state, Hitbox* hitbox) { bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate state, Hitbox* hitbox) {
const float E = 0.001f; // inaccuracy const float e = 0.001f; // inaccuracy
const glm::vec3& pos = hitbox->position; const glm::vec3& pos = hitbox->position;
const glm::vec3& half = hitbox->halfsize; const glm::vec3& half = hitbox->halfsize;
const auto& boxes = def->rotatable const auto& boxes = def->rotatable
@ -282,9 +282,9 @@ bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate st
for (const auto& block_hitbox : boxes) { for (const auto& block_hitbox : boxes) {
glm::vec3 min = block_hitbox.min(); glm::vec3 min = block_hitbox.min();
glm::vec3 max = block_hitbox.max(); glm::vec3 max = block_hitbox.max();
if (min.x < pos.x+half.x-x-E && max.x > pos.x-half.x-x+E && if (min.x < pos.x+half.x-x-e && max.x > pos.x-half.x-x+e &&
min.z < pos.z+half.z-z-E && max.z > pos.z-half.z-z+E && min.z < pos.z+half.z-z-e && max.z > pos.z-half.z-z+e &&
min.y < pos.y+half.y-y-E && max.y > pos.y-half.y-y+E) min.y < pos.y+half.y-y-e && max.y > pos.y-half.y-y+e)
return true; return true;
} }
return false; return false;

View File

@ -19,14 +19,14 @@ public:
PhysicsSolver(glm::vec3 gravity); PhysicsSolver(glm::vec3 gravity);
void step( void step(
const GlobalChunks& chunks, const GlobalChunks& chunks,
Hitbox* hitbox, Hitbox& hitbox,
float delta, float delta,
uint substeps, uint substeps,
entityid_t entity entityid_t entity
); );
void colisionCalc( void colisionCalc(
const GlobalChunks& chunks, const GlobalChunks& chunks,
Hitbox* hitbox, Hitbox& hitbox,
glm::vec3& vel, glm::vec3& vel,
glm::vec3& pos, glm::vec3& pos,
const glm::vec3 half, const glm::vec3 half,

View File

@ -27,7 +27,7 @@ Chunks::Chunks(
int32_t ox, int32_t ox,
int32_t oz, int32_t oz,
LevelEvents* events, LevelEvents* events,
const ContentIndices* indices const ContentIndices& indices
) )
: events(events), : events(events),
indices(indices), indices(indices),
@ -67,7 +67,7 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z) const {
return &empty; return &empty;
} }
} }
const auto& def = indices->blocks.require(v->id); const auto& def = indices.blocks.require(v->id);
if (def.obstacle) { if (def.obstacle) {
glm::ivec3 offset {}; glm::ivec3 offset {};
if (v->state.segment) { if (v->state.segment) {
@ -98,7 +98,7 @@ bool Chunks::isReplaceableBlock(int32_t x, int32_t y, int32_t z) {
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) return false; if (v == nullptr) return false;
return indices->blocks.require(v->id).obstacle; return indices.blocks.require(v->id).obstacle;
} }
ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel) const { ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel) const {
@ -254,7 +254,7 @@ glm::vec3 Chunks::rayCastToObstacle(
while (t <= maxDist) { while (t <= maxDist) {
voxel* voxel = get(ix, iy, iz); voxel* voxel = get(ix, iy, iz);
if (voxel) { if (voxel) {
const auto& def = indices->blocks.require(voxel->id); const auto& def = indices.blocks.require(voxel->id);
if (def.obstacle) { if (def.obstacle) {
if (!def.rt.solid) { if (!def.rt.solid) {
const std::vector<AABB>& hitboxes = const std::vector<AABB>& hitboxes =
@ -333,16 +333,16 @@ bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) {
// reduce nesting on next modification // reduce nesting on next modification
// 25.06.2024: not now // 25.06.2024: not now
// 11.11.2024: not now // 11.11.2024: not now
void Chunks::getVoxels(VoxelsVolume* volume, bool backlight) const { void Chunks::getVoxels(VoxelsVolume& volume, bool backlight) const {
voxel* voxels = volume->getVoxels(); voxel* voxels = volume.getVoxels();
light_t* lights = volume->getLights(); light_t* lights = volume.getLights();
int x = volume->getX(); int x = volume.getX();
int y = volume->getY(); int y = volume.getY();
int z = volume->getZ(); int z = volume.getZ();
int w = volume->getW(); int w = volume.getW();
int h = volume->getH(); int h = volume.getH();
int d = volume->getD(); int d = volume.getD();
int scx = floordiv<CHUNK_W>(x); int scx = floordiv<CHUNK_W>(x);
int scz = floordiv<CHUNK_D>(z); int scz = floordiv<CHUNK_D>(z);
@ -394,7 +394,7 @@ void Chunks::getVoxels(VoxelsVolume* volume, bool backlight) const {
light_t light = clights[cidx]; light_t light = clights[cidx];
if (backlight) { if (backlight) {
const auto block = const auto block =
indices->blocks.get(voxels[vidx].id); indices.blocks.get(voxels[vidx].id);
if (block && block->lightPassing) { if (block && block->lightPassing) {
light = Lightmap::combine( light = Lightmap::combine(
std::min(15, std::min(15,

View File

@ -25,7 +25,7 @@ class VoxelsVolume;
/// Player-centred chunks matrix /// Player-centred chunks matrix
class Chunks { class Chunks {
LevelEvents* events; LevelEvents* events;
const ContentIndices* const indices; const ContentIndices& indices;
void eraseSegments(const Block& def, blockstate state, int x, int y, int z); void eraseSegments(const Block& def, blockstate state, int x, int y, int z);
void repairSegments( void repairSegments(
@ -46,7 +46,7 @@ public:
int32_t ox, int32_t ox,
int32_t oz, int32_t oz,
LevelEvents* events, LevelEvents* events,
const ContentIndices* indices const ContentIndices& indices
); );
~Chunks() = default; ~Chunks() = default;
@ -56,6 +56,14 @@ public:
Chunk* getChunk(int32_t x, int32_t z) const; Chunk* getChunk(int32_t x, int32_t z) const;
Chunk* getChunkByVoxel(int32_t x, int32_t y, int32_t z) const; Chunk* getChunkByVoxel(int32_t x, int32_t y, int32_t z) const;
template <typename T>
Chunk* getChunkByVoxel(const glm::vec<3, T>& pos) const {
return getChunkByVoxel(
glm::floor(pos.x), glm::floor(pos.y), glm::floor(pos.z)
);
}
voxel* get(int32_t x, int32_t y, int32_t z) const; voxel* get(int32_t x, int32_t y, int32_t z) const;
voxel& require(int32_t x, int32_t y, int32_t z) const; voxel& require(int32_t x, int32_t y, int32_t z) const;
@ -118,7 +126,7 @@ public:
bool isReplaceableBlock(int32_t x, int32_t y, int32_t z); bool isReplaceableBlock(int32_t x, int32_t y, int32_t z);
bool isObstacleBlock(int32_t x, int32_t y, int32_t z); bool isObstacleBlock(int32_t x, int32_t y, int32_t z);
void getVoxels(VoxelsVolume* volume, bool backlight = false) const; void getVoxels(VoxelsVolume& volume, bool backlight = false) const;
void setCenter(int32_t x, int32_t z); void setCenter(int32_t x, int32_t z);
void resize(uint32_t newW, uint32_t newD); void resize(uint32_t newW, uint32_t newD);
@ -154,7 +162,7 @@ public:
} }
const ContentIndices& getContentIndices() const { const ContentIndices& getContentIndices() const {
return *indices; return indices;
} }
static inline constexpr unsigned matrixSize(int loadDistance, int padding) { static inline constexpr unsigned matrixSize(int loadDistance, int padding) {

View File

@ -19,8 +19,8 @@
static debug::Logger logger("chunks-storage"); static debug::Logger logger("chunks-storage");
GlobalChunks::GlobalChunks(Level* level) GlobalChunks::GlobalChunks(Level& level)
: level(level), indices(level ? level->content->getIndices() : nullptr) { : level(level), indices(*level.content.getIndices()) {
chunksMap.max_load_factor(CHUNKS_MAP_MAX_LOAD_FACTOR); chunksMap.max_load_factor(CHUNKS_MAP_MAX_LOAD_FACTOR);
} }
@ -96,11 +96,11 @@ std::shared_ptr<Chunk> GlobalChunks::create(int x, int z) {
auto chunk = std::make_shared<Chunk>(x, z); auto chunk = std::make_shared<Chunk>(x, z);
chunksMap[keyfrom(x, z)] = chunk; chunksMap[keyfrom(x, z)] = chunk;
World* world = level->getWorld(); World& world = *level.getWorld();
auto& regions = world->wfile.get()->getRegions(); auto& regions = world.wfile.get()->getRegions();
if (auto data = regions.getVoxels(chunk->x, chunk->z)) { if (auto data = regions.getVoxels(chunk->x, chunk->z)) {
const auto& indices = *level->content->getIndices(); const auto& indices = *level.content.getIndices();
chunk->decode(data.get()); chunk->decode(data.get());
check_voxels(indices, *chunk); check_voxels(indices, *chunk);
@ -111,13 +111,13 @@ std::shared_ptr<Chunk> GlobalChunks::create(int x, int z) {
auto entitiesData = regions.fetchEntities(chunk->x, chunk->z); auto entitiesData = regions.fetchEntities(chunk->x, chunk->z);
if (entitiesData.getType() == dv::value_type::object) { if (entitiesData.getType() == dv::value_type::object) {
level->entities->loadEntities(std::move(entitiesData)); level.entities->loadEntities(std::move(entitiesData));
chunk->flags.entities = true; chunk->flags.entities = true;
} }
chunk->flags.loaded = true; chunk->flags.loaded = true;
for (auto& entry : chunk->inventories) { for (auto& entry : chunk->inventories) {
level->inventories->store(entry.second); level.inventories->store(entry.second);
} }
} }
if (auto lights = regions.getLights(chunk->x, chunk->z)) { if (auto lights = regions.getLights(chunk->x, chunk->z)) {
@ -178,13 +178,13 @@ void GlobalChunks::save(Chunk* chunk) {
return; return;
} }
AABB aabb = chunk->getAABB(); AABB aabb = chunk->getAABB();
auto entities = level->entities->getAllInside(aabb); auto entities = level.entities->getAllInside(aabb);
auto root = dv::object(); auto root = dv::object();
root["data"] = level->entities->serialize(entities); root["data"] = level.entities->serialize(entities);
if (!entities.empty()) { if (!entities.empty()) {
chunk->flags.entities = true; chunk->flags.entities = true;
} }
level->getWorld()->wfile->getRegions().put( level.getWorld()->wfile->getRegions().put(
chunk, chunk,
chunk->flags.entities ? json::to_binary(root, true) chunk->flags.entities ? json::to_binary(root, true)
: std::vector<ubyte>() : std::vector<ubyte>()

View File

@ -26,15 +26,15 @@ class GlobalChunks {
return ekey.key; return ekey.key;
} }
Level* level; Level& level;
const ContentIndices* indices; const ContentIndices& indices;
std::unordered_map<uint64_t, std::shared_ptr<Chunk>> chunksMap; std::unordered_map<uint64_t, std::shared_ptr<Chunk>> chunksMap;
std::unordered_map<glm::ivec2, std::shared_ptr<Chunk>> pinnedChunks; std::unordered_map<glm::ivec2, std::shared_ptr<Chunk>> pinnedChunks;
std::unordered_map<ptrdiff_t, int> refCounters; std::unordered_map<ptrdiff_t, int> refCounters;
consumer<Chunk&> onUnload; consumer<Chunk&> onUnload;
public: public:
GlobalChunks(Level* level); GlobalChunks(Level& level);
~GlobalChunks() = default; ~GlobalChunks() = default;
void setOnUnload(consumer<Chunk&> onUnload); void setOnUnload(consumer<Chunk&> onUnload);
@ -68,6 +68,6 @@ public:
} }
const ContentIndices& getContentIndices() const { const ContentIndices& getContentIndices() const {
return *indices; return indices;
} }
}; };

View File

@ -18,19 +18,19 @@
Level::Level( Level::Level(
std::unique_ptr<World> worldPtr, std::unique_ptr<World> worldPtr,
const Content* content, const Content& content,
EngineSettings& settings EngineSettings& settings
) )
: settings(settings), : settings(settings),
world(std::move(worldPtr)), world(std::move(worldPtr)),
content(content), content(content),
chunks(std::make_unique<GlobalChunks>(this)), chunks(std::make_unique<GlobalChunks>(*this)),
physics(std::make_unique<PhysicsSolver>(glm::vec3(0, -22.6f, 0))), physics(std::make_unique<PhysicsSolver>(glm::vec3(0, -22.6f, 0))),
events(std::make_unique<LevelEvents>()), events(std::make_unique<LevelEvents>()),
entities(std::make_unique<Entities>(this)), entities(std::make_unique<Entities>(*this)),
players(std::make_unique<Players>(this)) { players(std::make_unique<Players>(*this)) {
const auto& worldInfo = world->getInfo(); const auto& worldInfo = world->getInfo();
auto& cameraIndices = content->getIndices(ResourceType::CAMERA); auto& cameraIndices = content.getIndices(ResourceType::CAMERA);
for (size_t i = 0; i < cameraIndices.size(); i++) { for (size_t i = 0; i < cameraIndices.size(); i++) {
auto camera = std::make_shared<Camera>(); auto camera = std::make_shared<Camera>();
auto map = cameraIndices.getSavedData(i); auto map = cameraIndices.getSavedData(i);
@ -76,7 +76,7 @@ const World* Level::getWorld() const {
} }
void Level::onSave() { void Level::onSave() {
auto& cameraIndices = content->getIndices(ResourceType::CAMERA); auto& cameraIndices = content.getIndices(ResourceType::CAMERA);
for (size_t i = 0; i < cameraIndices.size(); i++) { for (size_t i = 0; i < cameraIndices.size(); i++) {
auto& camera = *cameras.at(i); auto& camera = *cameras.at(i);
auto map = dv::object(); auto map = dv::object();
@ -91,7 +91,7 @@ void Level::onSave() {
} }
std::shared_ptr<Camera> Level::getCamera(const std::string& name) { std::shared_ptr<Camera> Level::getCamera(const std::string& name) {
size_t index = content->getIndices(ResourceType::CAMERA).indexOf(name); size_t index = content.getIndices(ResourceType::CAMERA).indexOf(name);
if (index == ResourceIndices::MISSING) { if (index == ResourceIndices::MISSING) {
return nullptr; return nullptr;
} }

View File

@ -23,7 +23,7 @@ class Level {
const EngineSettings& settings; const EngineSettings& settings;
std::unique_ptr<World> world; std::unique_ptr<World> world;
public: public:
const Content* const content; const Content& content;
std::unique_ptr<GlobalChunks> chunks; std::unique_ptr<GlobalChunks> chunks;
std::unique_ptr<Inventories> inventories; std::unique_ptr<Inventories> inventories;
@ -35,7 +35,7 @@ public:
Level( Level(
std::unique_ptr<World> world, std::unique_ptr<World> world,
const Content* content, const Content& content,
EngineSettings& settings EngineSettings& settings
); );
~Level(); ~Level();

View File

@ -30,7 +30,7 @@ world_load_error::world_load_error(const std::string& message)
World::World( World::World(
WorldInfo info, WorldInfo info,
const std::shared_ptr<WorldFiles>& worldFiles, const std::shared_ptr<WorldFiles>& worldFiles,
const Content* content, const Content& content,
const std::vector<ContentPack>& packs const std::vector<ContentPack>& packs
) : info(std::move(info)), ) : info(std::move(info)),
content(content), content(content),
@ -46,12 +46,12 @@ void World::updateTimers(float delta) {
info.totalTime += delta; info.totalTime += delta;
} }
void World::writeResources(const Content* content) { void World::writeResources(const Content& content) {
auto root = dv::object(); auto root = dv::object();
for (size_t typeIndex = 0; typeIndex < RESOURCE_TYPES_COUNT; typeIndex++) { for (size_t typeIndex = 0; typeIndex < RESOURCE_TYPES_COUNT; typeIndex++) {
auto typeName = to_string(static_cast<ResourceType>(typeIndex)); auto typeName = to_string(static_cast<ResourceType>(typeIndex));
auto& list = root.list(typeName); auto& list = root.list(typeName);
auto& indices = content->resourceIndices[typeIndex]; auto& indices = content.resourceIndices[typeIndex];
for (size_t i = 0; i < indices.size(); i++) { for (size_t i = 0; i < indices.size(); i++) {
auto& map = list.object(); auto& map = list.object();
map["name"] = indices.getName(i); map["name"] = indices.getName(i);
@ -65,10 +65,9 @@ void World::writeResources(const Content* content) {
} }
void World::write(Level* level) { void World::write(Level* level) {
const Content* content = level->content;
level->chunks->saveAll(); level->chunks->saveAll();
info.nextEntityId = level->entities->peekNextID(); info.nextEntityId = level->entities->peekNextID();
wfile->write(this, content); wfile->write(this, &content);
auto playerFile = level->players->serialize(); auto playerFile = level->players->serialize();
files::write_json(wfile->getPlayerFile(), playerFile); files::write_json(wfile->getPlayerFile(), playerFile);
@ -82,7 +81,7 @@ std::unique_ptr<Level> World::create(
const fs::path& directory, const fs::path& directory,
uint64_t seed, uint64_t seed,
EngineSettings& settings, EngineSettings& settings,
const Content* content, const Content& content,
const std::vector<ContentPack>& packs const std::vector<ContentPack>& packs
) { ) {
WorldInfo info {}; WorldInfo info {};
@ -103,7 +102,7 @@ std::unique_ptr<Level> World::create(
std::unique_ptr<Level> World::load( std::unique_ptr<Level> World::load(
const std::shared_ptr<WorldFiles>& worldFilesPtr, const std::shared_ptr<WorldFiles>& worldFilesPtr,
EngineSettings& settings, EngineSettings& settings,
const Content* content, const Content& content,
const std::vector<ContentPack>& packs const std::vector<ContentPack>& packs
) { ) {
auto worldFiles = worldFilesPtr.get(); auto worldFiles = worldFilesPtr.get();

View File

@ -56,17 +56,17 @@ struct WorldInfo : public Serializable {
class World { class World {
WorldInfo info {}; WorldInfo info {};
const Content* const content; const Content& content;
std::vector<ContentPack> packs; std::vector<ContentPack> packs;
void writeResources(const Content* content); void writeResources(const Content& content);
public: public:
std::shared_ptr<WorldFiles> wfile; std::shared_ptr<WorldFiles> wfile;
World( World(
WorldInfo info, WorldInfo info,
const std::shared_ptr<WorldFiles>& worldFiles, const std::shared_ptr<WorldFiles>& worldFiles,
const Content* content, const Content& content,
const std::vector<ContentPack>& packs const std::vector<ContentPack>& packs
); );
@ -103,7 +103,7 @@ public:
const fs::path& directory, const fs::path& directory,
uint64_t seed, uint64_t seed,
EngineSettings& settings, EngineSettings& settings,
const Content* content, const Content& content,
const std::vector<ContentPack>& packs const std::vector<ContentPack>& packs
); );
@ -118,7 +118,7 @@ public:
static std::unique_ptr<Level> load( static std::unique_ptr<Level> load(
const std::shared_ptr<WorldFiles>& worldFiles, const std::shared_ptr<WorldFiles>& worldFiles,
EngineSettings& settings, EngineSettings& settings,
const Content* content, const Content& content,
const std::vector<ContentPack>& packs const std::vector<ContentPack>& packs
); );
@ -156,9 +156,4 @@ public:
int64_t getNextInventoryId() { int64_t getNextInventoryId() {
return info.nextInventoryId++; return info.nextInventoryId++;
} }
/// @brief Get current world Content instance
const Content* getContent() const {
return content;
}
}; };

View File

@ -59,7 +59,7 @@ std::unique_ptr<VoxelFragment> VoxelFragment::create(
std::vector<std::string> blockNames {CORE_AIR}; std::vector<std::string> blockNames {CORE_AIR};
std::unordered_map<blockid_t, blockid_t> blocksRegistered {{0, 0}}; std::unordered_map<blockid_t, blockid_t> blocksRegistered {{0, 0}};
auto contentIndices = level.content->getIndices(); auto contentIndices = level.content.getIndices();
for (size_t i = 0 ; i < voxels.size(); i++) { for (size_t i = 0 ; i < voxels.size(); i++) {
blockid_t id = volVoxels[i].id; blockid_t id = volVoxels[i].id;
blockid_t index; blockid_t index;

View File

@ -24,7 +24,7 @@ static inline constexpr uint MAX_PARAMETERS = 4;
static inline constexpr uint BASIC_PROTOTYPE_LAYERS = 5; static inline constexpr uint BASIC_PROTOTYPE_LAYERS = 5;
WorldGenerator::WorldGenerator( WorldGenerator::WorldGenerator(
const GeneratorDef& def, const Content* content, uint64_t seed const GeneratorDef& def, const Content& content, uint64_t seed
) )
: def(def), : def(def),
content(content), content(content),
@ -66,10 +66,10 @@ WorldGenerator::WorldGenerator(
}); });
for (int i = 0; i < def.structures.size(); i++) { for (int i = 0; i < def.structures.size(); i++) {
// pre-calculate rotated structure variants // pre-calculate rotated structure variants
def.structures[i]->fragments[0]->prepare(*content); def.structures[i]->fragments[0]->prepare(content);
for (int j = 1; j < 4; j++) { for (int j = 1; j < 4; j++) {
def.structures[i]->fragments[j] = def.structures[i]->fragments[j] =
def.structures[i]->fragments[j-1]->rotated(*content); def.structures[i]->fragments[j-1]->rotated(content);
} }
} }
} }
@ -367,7 +367,7 @@ void WorldGenerator::generatePlants(
int chunkZ, int chunkZ,
const Biome** biomes const Biome** biomes
) { ) {
const auto& indices = content->getIndices()->blocks; const auto& indices = content.getIndices()->blocks;
util::PseudoRandom plantsRand; util::PseudoRandom plantsRand;
plantsRand.setSeed(chunkX, chunkZ); plantsRand.setSeed(chunkX, chunkZ);
@ -431,7 +431,7 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) {
std::memset(voxels, 0, sizeof(voxel) * CHUNK_VOL); std::memset(voxels, 0, sizeof(voxel) * CHUNK_VOL);
const auto& indices = content->getIndices()->blocks; const auto& indices = content.getIndices()->blocks;
const auto& biomes = prototype.biomes.get(); const auto& biomes = prototype.biomes.get();
for (uint z = 0; z < CHUNK_D; z++) { for (uint z = 0; z < CHUNK_D; z++) {
for (uint x = 0; x < CHUNK_W; x++) { for (uint x = 0; x < CHUNK_W; x++) {
@ -531,7 +531,7 @@ void WorldGenerator::generateLine(
voxel* voxels, voxel* voxels,
int chunkX, int chunkZ int chunkX, int chunkZ
) { ) {
const auto& indices = content->getIndices()->blocks; const auto& indices = content.getIndices()->blocks;
int cgx = chunkX * CHUNK_W; int cgx = chunkX * CHUNK_W;
int cgz = chunkZ * CHUNK_D; int cgz = chunkZ * CHUNK_D;

View File

@ -50,7 +50,7 @@ class WorldGenerator {
/// @param def generator definition /// @param def generator definition
const GeneratorDef& def; const GeneratorDef& def;
/// @param content world content /// @param content world content
const Content* content; const Content& content;
/// @param seed world seed /// @param seed world seed
uint64_t seed; uint64_t seed;
/// @brief Chunk prototypes main storage /// @brief Chunk prototypes main storage
@ -120,7 +120,7 @@ class WorldGenerator {
public: public:
WorldGenerator( WorldGenerator(
const GeneratorDef& def, const GeneratorDef& def,
const Content* content, const Content& content,
uint64_t seed uint64_t seed
); );
~WorldGenerator(); ~WorldGenerator();