From dbc7cd56bdad2b200008e2834b27f4702b0840b3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 5 Mar 2026 20:52:45 +0300 Subject: [PATCH] feat: solid entity material support & minor refactor --- src/frontend/LevelFrontend.cpp | 102 ++++++++++++++++++--------- src/frontend/LevelFrontend.hpp | 14 ++-- src/frontend/hud.cpp | 4 +- src/frontend/screens/LevelScreen.cpp | 2 +- src/logic/PlayerController.cpp | 26 ++----- src/logic/PlayerController.hpp | 6 ++ 6 files changed, 91 insertions(+), 63 deletions(-) diff --git a/src/frontend/LevelFrontend.cpp b/src/frontend/LevelFrontend.cpp index 9a8553da6..d70f09ba2 100644 --- a/src/frontend/LevelFrontend.cpp +++ b/src/frontend/LevelFrontend.cpp @@ -10,17 +10,19 @@ #include "logic/LevelController.hpp" #include "logic/PlayerController.hpp" #include "objects/Player.hpp" +#include "physics/Hitbox.hpp" #include "voxels/Block.hpp" +#include "voxels/Chunks.hpp" #include "world/Level.hpp" #include "engine/Engine.hpp" LevelFrontend::LevelFrontend( Engine& engine, - Player* currentPlayer, - LevelController* controller, + PlayerController& playerController, + LevelController& controller, const EngineSettings& settings ) - : level(*controller->getLevel()), + : level(*controller.getLevel()), controller(controller), assets(*engine.getAssets()), contentCache(std::make_unique( @@ -36,45 +38,79 @@ LevelFrontend::LevelFrontend( "block-previews" ); - auto& rassets = assets; - controller->getBlocksController()->listenBlockInteraction( - [currentPlayer, controller, &rassets](auto player, const auto& pos, const auto& def, BlockInteraction type) { - const auto& level = *controller->getLevel(); + auto& currentPlayer = playerController.getPlayer(); + auto& assets = this->assets; + auto& level = this->level; + + playerController.setFootstepCallback( + [&level, ¤tPlayer, &assets](const Hitbox& hitbox) { + const BlockMaterial* material = nullptr; + if (hitbox.groundMaterial.empty()) { + const auto& pos = hitbox.position; + const auto& half = hitbox.getHalfSize(); + + auto& blockIndices = level.content.getIndices()->blocks; + for (int offsetZ = -1; offsetZ <= 1; offsetZ++) { + for (int offsetX = -1; offsetX <= 1; offsetX++) { + int x = std::floor(pos.x + half.x * offsetX); + int y = std::floor(pos.y - half.y * 1.1f); + int z = std::floor(pos.z + half.z * offsetZ); + auto vox = currentPlayer.chunks->get(x, y, z); + if (vox) { + auto& def = blockIndices.require(vox->id); + if (!def.obstacle) { + continue; + } + material = level.content.findBlockMaterial(def.material); + break; + } + } + } + } else { + material = level.content.findBlockMaterial(hitbox.groundMaterial); + } + if (material == nullptr) { + return; + } + + auto sound = assets.get(material->stepsSound); + glm::vec3 pos {}; + auto soundsCamera = currentPlayer.currentCamera.get(); + if (currentPlayer.isCurrentCameraBuiltin()) { + soundsCamera = currentPlayer.fpCamera.get(); + } + bool relative = soundsCamera == currentPlayer.fpCamera.get(); + if (!relative) { + pos = currentPlayer.getPosition(); + } + audio::play( + sound, + pos, + relative, + 0.333f, + 1.0f + (rand() % 6 - 3) * 0.05f, + false, + audio::PRIORITY_LOW, + audio::get_channel_index("regular") + ); + }); + + controller.getBlocksController()->listenBlockInteraction( + [&level, &assets] + (auto player, const auto& pos, const auto& def, BlockInteraction type) { auto material = level.content.findBlockMaterial(def.material); if (material == nullptr) { return; } - if (type == BlockInteraction::step) { - auto sound = rassets.get(material->stepsSound); - glm::vec3 pos {}; - auto soundsCamera = currentPlayer->currentCamera.get(); - if (currentPlayer->isCurrentCameraBuiltin()) { - soundsCamera = currentPlayer->fpCamera.get(); - } - bool relative = player == currentPlayer && - soundsCamera == currentPlayer->fpCamera.get(); - if (!relative) { - pos = player->getPosition(); - } - audio::play( - sound, - pos, - relative, - 0.333f, - 1.0f + (rand() % 6 - 3) * 0.05f, - false, - audio::PRIORITY_LOW, - audio::get_channel_index("regular") - ); - } else { + if (type != BlockInteraction::step) { audio::Sound* sound = nullptr; switch (type) { case BlockInteraction::placing: - sound = rassets.get(material->placeSound); + sound = assets.get(material->placeSound); break; case BlockInteraction::destruction: - sound = rassets.get(material->breakSound); + sound = assets.get(material->breakSound); break; default: break; @@ -108,6 +144,6 @@ const ContentGfxCache& LevelFrontend::getContentGfxCache() const { return *contentCache; } -LevelController* LevelFrontend::getController() const { +LevelController& LevelFrontend::getController() const { return controller; } diff --git a/src/frontend/LevelFrontend.hpp b/src/frontend/LevelFrontend.hpp index cc4f996b2..451f88675 100644 --- a/src/frontend/LevelFrontend.hpp +++ b/src/frontend/LevelFrontend.hpp @@ -2,24 +2,24 @@ #include -class Level; class Assets; -class Player; -class Engine; class ContentGfxCache; +class Engine; +class Level; class LevelController; +class PlayerController; struct EngineSettings; class LevelFrontend { Level& level; - LevelController* controller; + LevelController& controller; Assets& assets; std::unique_ptr contentCache; public: LevelFrontend( Engine& engine, - Player* currentPlayer, - LevelController* controller, + PlayerController& currentPlayer, + LevelController& controller, const EngineSettings& settings ); ~LevelFrontend(); @@ -27,5 +27,5 @@ public: Level& getLevel(); const ContentGfxCache& getContentGfxCache() const; ContentGfxCache& getContentGfxCache(); - LevelController* getController() const; + LevelController& getController() const; }; diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 6f3593610..6a4afbd89 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -272,7 +272,7 @@ void Hud::updateWorldGenDebug() { const auto& chunks = *player.chunks; uint padding = engine.getSettings().chunks.padding.get(); auto generator = - frontend.getController()->getChunksController()->getGenerator(); + frontend.getController().getChunksController()->getGenerator(); auto debugInfo = generator->createDebugInfo(); int width = debugImgWorldGen->getWidth(); @@ -294,7 +294,7 @@ void Hud::updateWorldGenDebug() { bool isInLoadingZone = frontend.getController() - ->getChunksController() + .getChunksController() ->isInLoadingZone(player, padding, ax + ox, az + oz); data[(flippedZ * width + x) * 4 + 1] = diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index 13618d33a..737742afd 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -68,7 +68,7 @@ LevelScreen::LevelScreen( ); frontend = std::make_unique( - engine, player, controller.get(), settings + engine, *playerController, *controller, settings ); renderer = std::make_unique( engine, *frontend, *player diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 35ea961ec..3d8c75872 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -229,26 +229,8 @@ PlayerController::PlayerController( } void PlayerController::onFootstep(const Hitbox& hitbox) { - const auto& pos = hitbox.position; - const auto& half = hitbox.getHalfSize(); - - for (int offsetZ = -1; offsetZ <= 1; offsetZ++) { - for (int offsetX = -1; offsetX <= 1; offsetX++) { - int x = std::floor(pos.x + half.x * offsetX); - int y = std::floor(pos.y - half.y * 1.1f); - 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); - if (!def.obstacle) { - continue; - } - blocksController.onBlockInteraction( - &player, glm::ivec3(x, y, z), def, BlockInteraction::step - ); - return; - } - } + if (footstepCallback) { + footstepCallback(hitbox); } } @@ -557,3 +539,7 @@ void PlayerController::updateInteraction(const Input& inputEvents, float delta) Player& PlayerController::getPlayer() { return player; } + +void PlayerController::setFootstepCallback(FootstepCallback&& callback) { + footstepCallback = std::move(callback); +} diff --git a/src/logic/PlayerController.hpp b/src/logic/PlayerController.hpp index e730ff37c..5ec8e4b50 100644 --- a/src/logic/PlayerController.hpp +++ b/src/logic/PlayerController.hpp @@ -18,6 +18,8 @@ struct Hitbox; struct CameraSettings; struct EngineSettings; +using FootstepCallback = std::function; + class CameraControl { Player& player; std::shared_ptr camera; @@ -57,6 +59,7 @@ class PlayerController { CameraControl camControl; BlocksController& blocksController; float interactionTimer = 0.0f; + FootstepCallback footstepCallback; void updateKeyboard(const Input& inputEvents); void resetKeyboard(); @@ -89,5 +92,8 @@ public: void postUpdate( float delta, int windowHeight, const Input* inputEvents, bool pause ); + Player& getPlayer(); + + void setFootstepCallback(FootstepCallback&& callback); };