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(
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++) {
auto& map = list[i];
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();
if (!fs::is_regular_file(file)) {
logger.warning() << "resources.json does not exists";

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -86,7 +86,7 @@ void Decorator::update(
currentIndex = (currentIndex + BIG_PRIME) % UPDATE_BLOCKS;
const auto& chunks = *player.chunks;
const auto& indices = *level.content->getIndices();
const auto& indices = *level.content.getIndices();
int lx = index % 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);
}
const auto& chunks = *player.chunks;
const auto& indices = *level.content->getIndices();
const auto& indices = *level.content.getIndices();
auto iter = blockEmitters.begin();
while (iter != blockEmitters.end()) {
auto emitter = renderer.particles->getEmitter(iter->second);

View File

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

View File

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

View File

@ -17,10 +17,10 @@ class LightSolver {
std::queue<lightentry> addqueue;
std::queue<lightentry> remqueue;
const Block* const* blockDefs;
Chunks* chunks;
Chunks& chunks;
int channel;
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, int emission);

View File

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

View File

@ -9,14 +9,14 @@ class Chunks;
class LightSolver;
class Lighting {
const Content* const content;
Chunks* chunks;
const Content& content;
Chunks& chunks;
std::unique_ptr<LightSolver> solverR;
std::unique_ptr<LightSolver> solverG;
std::unique_ptr<LightSolver> solverB;
std::unique_ptr<LightSolver> solverS;
public:
Lighting(const Content* content, Chunks* chunks);
Lighting(const Content& content, Chunks& chunks);
~Lighting();
void clear();
@ -24,5 +24,5 @@ public:
void onChunkLoaded(int cx, int cz, bool expand);
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) {
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& xaxis = rot.axisX;
const auto& yaxis = rot.axisY;
@ -85,7 +85,7 @@ void BlocksController::placeBlock(
if (voxel == nullptr) {
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});
onBlockInteraction(
@ -106,7 +106,7 @@ void BlocksController::placeBlock(
void BlocksController::updateBlock(int x, int y, int z) {
voxel* vox = blocks_agent::get(chunks, x, y, z);
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) {
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)) {
@ -132,7 +132,7 @@ void BlocksController::update(float delta, uint padding) {
}
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();
for (size_t id = 0; id < indices.count(); id++) {
if ((id + tickid) % parts != 0) continue;
@ -169,7 +169,7 @@ void BlocksController::randomTick(
}
void BlocksController::randomTick(int tickid, int parts, uint padding) {
auto indices = level.content->getIndices();
auto indices = level.content.getIndices();
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;
auto inv = chunk->getBlockInventory(lx, y, lz);
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);
int invsize = def.inventorySize;
if (invsize == 0) {

View File

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

View File

@ -152,7 +152,7 @@ static void load_world(
auto& packs = engine.getContentPacks();
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));
} catch (const world_load_error& error) {
guiutil::alert(
@ -164,7 +164,7 @@ static void load_world(
}
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 worldFile = folder / fs::u8path("world.json");
if (!fs::exists(worldFile)) {
@ -245,7 +245,7 @@ void EngineController::createWorld(
folder,
seed,
engine.getSettings(),
engine.getContent(),
*engine.getContent(),
engine.getContentPacks()
);
if (!engine.isHeadless()) {

View File

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

View File

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

View File

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

View File

@ -60,7 +60,7 @@ static int l_set_vel(lua::State* L) {
static int l_get_rot(lua::State* L) {
if (auto player = get_player(L, 1)) {
return lua::pushvec_stack(L, player->cam);
return lua::pushvec_stack(L, player->rotation);
}
return 0;
}
@ -70,17 +70,17 @@ static int l_set_rot(lua::State* L) {
if (!player) {
return 0;
}
glm::vec3& cam = player->cam;
glm::vec3& rotation = player->rotation;
auto x = lua::tonumber(L, 2);
auto y = lua::tonumber(L, 3);
auto z = cam.z;
auto z = rotation.z;
if (lua::isnumber(L, 4)) {
z = lua::tonumber(L, 4);
}
cam.x = x;
cam.y = y;
cam.z = z;
rotation.x = x;
rotation.y = y;
rotation.z = z;
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) {
}
@ -117,7 +117,7 @@ entityid_t Entities::spawn(
dv::value saved,
entityid_t uid
) {
auto skeleton = level->content->getSkeleton(def.skeletonName);
auto skeleton = level.content.getSkeleton(def.skeletonName);
if (skeleton == nullptr) {
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) {
entityid_t uid = map["uid"].asInteger();
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);
}
@ -219,7 +219,7 @@ void Entities::loadEntity(const dv::value& map, Entity entity) {
std::string skeletonName = skeleton.config->getName();
map.at("skeleton").get(skeletonName);
if (skeletonName != skeleton.config->getName()) {
skeleton.config = level->content->getSkeleton(skeletonName);
skeleton.config = level.content.getSkeleton(skeletonName);
}
if (auto found = map.at(COMP_SKELETON)) {
auto& skeletonmap = *found;
@ -361,8 +361,8 @@ dv::value Entities::serialize(const std::vector<Entity>& entities) {
if (!entity.getDef().save.enabled) {
continue;
}
level->entities->onSave(entity);
list.add(level->entities->serialize(entity));
level.entities->onSave(entity);
list.add(level.entities->serialize(entity));
}
return list;
}
@ -380,7 +380,7 @@ void Entities::clean() {
} else {
auto& rigidbody = registry.get<Rigidbody>(it->second);
// todo: refactor
auto physics = level->physics.get();
auto physics = level.physics.get();
for (auto& sensor : rigidbody.sensors) {
physics->removeSensor(&sensor);
}
@ -428,7 +428,7 @@ void Entities::preparePhysics(float delta) {
auto parts = sensorsTickClock.getParts();
auto view = registry.view<EntityId, Transform, Rigidbody>();
auto physics = level->physics.get();
auto physics = level.physics.get();
std::vector<Sensor*> sensors;
for (auto [entity, eid, transform, rigidbody] : view.each()) {
if (!rigidbody.enabled) {
@ -447,7 +447,7 @@ void Entities::updatePhysics(float delta) {
preparePhysics(delta);
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()) {
if (!rigidbody.enabled || rigidbody.hitbox.type == BodyType::STATIC) {
continue;
@ -459,7 +459,7 @@ void Entities::updatePhysics(float delta) {
float vel = glm::length(prevVel);
int substeps = static_cast<int>(delta * vel * 20);
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;
transform.setPos(hitbox.position);
if (hitbox.grounded && !grounded) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,7 +25,7 @@ class VoxelsVolume;
/// Player-centred chunks matrix
class Chunks {
LevelEvents* events;
const ContentIndices* const indices;
const ContentIndices& indices;
void eraseSegments(const Block& def, blockstate state, int x, int y, int z);
void repairSegments(
@ -46,7 +46,7 @@ public:
int32_t ox,
int32_t oz,
LevelEvents* events,
const ContentIndices* indices
const ContentIndices& indices
);
~Chunks() = default;
@ -56,6 +56,14 @@ public:
Chunk* getChunk(int32_t x, 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& 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 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 resize(uint32_t newW, uint32_t newD);
@ -154,7 +162,7 @@ public:
}
const ContentIndices& getContentIndices() const {
return *indices;
return indices;
}
static inline constexpr unsigned matrixSize(int loadDistance, int padding) {

View File

@ -19,8 +19,8 @@
static debug::Logger logger("chunks-storage");
GlobalChunks::GlobalChunks(Level* level)
: level(level), indices(level ? level->content->getIndices() : nullptr) {
GlobalChunks::GlobalChunks(Level& level)
: level(level), indices(*level.content.getIndices()) {
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);
chunksMap[keyfrom(x, z)] = chunk;
World* world = level->getWorld();
auto& regions = world->wfile.get()->getRegions();
World& world = *level.getWorld();
auto& regions = world.wfile.get()->getRegions();
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());
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);
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.loaded = true;
for (auto& entry : chunk->inventories) {
level->inventories->store(entry.second);
level.inventories->store(entry.second);
}
}
if (auto lights = regions.getLights(chunk->x, chunk->z)) {
@ -178,13 +178,13 @@ void GlobalChunks::save(Chunk* chunk) {
return;
}
AABB aabb = chunk->getAABB();
auto entities = level->entities->getAllInside(aabb);
auto entities = level.entities->getAllInside(aabb);
auto root = dv::object();
root["data"] = level->entities->serialize(entities);
root["data"] = level.entities->serialize(entities);
if (!entities.empty()) {
chunk->flags.entities = true;
}
level->getWorld()->wfile->getRegions().put(
level.getWorld()->wfile->getRegions().put(
chunk,
chunk->flags.entities ? json::to_binary(root, true)
: std::vector<ubyte>()

View File

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

View File

@ -18,19 +18,19 @@
Level::Level(
std::unique_ptr<World> worldPtr,
const Content* content,
const Content& content,
EngineSettings& settings
)
: settings(settings),
world(std::move(worldPtr)),
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))),
events(std::make_unique<LevelEvents>()),
entities(std::make_unique<Entities>(this)),
players(std::make_unique<Players>(this)) {
entities(std::make_unique<Entities>(*this)),
players(std::make_unique<Players>(*this)) {
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++) {
auto camera = std::make_shared<Camera>();
auto map = cameraIndices.getSavedData(i);
@ -76,7 +76,7 @@ const World* Level::getWorld() const {
}
void Level::onSave() {
auto& cameraIndices = content->getIndices(ResourceType::CAMERA);
auto& cameraIndices = content.getIndices(ResourceType::CAMERA);
for (size_t i = 0; i < cameraIndices.size(); i++) {
auto& camera = *cameras.at(i);
auto map = dv::object();
@ -91,7 +91,7 @@ void Level::onSave() {
}
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) {
return nullptr;
}

View File

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

View File

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

View File

@ -56,17 +56,17 @@ struct WorldInfo : public Serializable {
class World {
WorldInfo info {};
const Content* const content;
const Content& content;
std::vector<ContentPack> packs;
void writeResources(const Content* content);
void writeResources(const Content& content);
public:
std::shared_ptr<WorldFiles> wfile;
World(
WorldInfo info,
const std::shared_ptr<WorldFiles>& worldFiles,
const Content* content,
const Content& content,
const std::vector<ContentPack>& packs
);
@ -103,7 +103,7 @@ public:
const fs::path& directory,
uint64_t seed,
EngineSettings& settings,
const Content* content,
const Content& content,
const std::vector<ContentPack>& packs
);
@ -118,7 +118,7 @@ public:
static std::unique_ptr<Level> load(
const std::shared_ptr<WorldFiles>& worldFiles,
EngineSettings& settings,
const Content* content,
const Content& content,
const std::vector<ContentPack>& packs
);
@ -156,9 +156,4 @@ public:
int64_t getNextInventoryId() {
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::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++) {
blockid_t id = volVoxels[i].id;
blockid_t index;

View File

@ -24,7 +24,7 @@ static inline constexpr uint MAX_PARAMETERS = 4;
static inline constexpr uint BASIC_PROTOTYPE_LAYERS = 5;
WorldGenerator::WorldGenerator(
const GeneratorDef& def, const Content* content, uint64_t seed
const GeneratorDef& def, const Content& content, uint64_t seed
)
: def(def),
content(content),
@ -66,10 +66,10 @@ WorldGenerator::WorldGenerator(
});
for (int i = 0; i < def.structures.size(); i++) {
// 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++) {
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,
const Biome** biomes
) {
const auto& indices = content->getIndices()->blocks;
const auto& indices = content.getIndices()->blocks;
util::PseudoRandom plantsRand;
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);
const auto& indices = content->getIndices()->blocks;
const auto& indices = content.getIndices()->blocks;
const auto& biomes = prototype.biomes.get();
for (uint z = 0; z < CHUNK_D; z++) {
for (uint x = 0; x < CHUNK_W; x++) {
@ -531,7 +531,7 @@ void WorldGenerator::generateLine(
voxel* voxels,
int chunkX, int chunkZ
) {
const auto& indices = content->getIndices()->blocks;
const auto& indices = content.getIndices()->blocks;
int cgx = chunkX * CHUNK_W;
int cgz = chunkZ * CHUNK_D;

View File

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