From 2e4a32fed7bc5db452bda479f4d51a6b3a599169 Mon Sep 17 00:00:00 2001 From: zhenyan121 <3367366583@qq.com> Date: Fri, 31 Jul 2026 20:51:14 +0800 Subject: [PATCH] feat(gameplay): add server-side entity movement and AI Refactor LocalPlayer::update_physical to operate on a passed position, and run speed, physical, and wander AI systems in ServerEntityManager. --- include/Cubed/gameplay/local_player.hpp | 2 +- .../Cubed/gameplay/server_entity_manager.hpp | 1 + src/gameplay/local_player.cpp | 17 +++++++++-------- src/gameplay/server_entity_manager.cpp | 10 ++++++++++ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/Cubed/gameplay/local_player.hpp b/include/Cubed/gameplay/local_player.hpp index fa76c31..b4a0cb6 100644 --- a/include/Cubed/gameplay/local_player.hpp +++ b/include/Cubed/gameplay/local_player.hpp @@ -156,7 +156,7 @@ private: Gait compute_gait() const; void update_speed(float dt); - std::tuple update_physical(float dt); + std::tuple update_physical(float dt, glm::vec3& pos); glm::vec3 get_move_distance(float dt); }; } // namespace Cubed diff --git a/include/Cubed/gameplay/server_entity_manager.hpp b/include/Cubed/gameplay/server_entity_manager.hpp index d4f6771..13a69d4 100644 --- a/include/Cubed/gameplay/server_entity_manager.hpp +++ b/include/Cubed/gameplay/server_entity_manager.hpp @@ -45,6 +45,7 @@ private: void handle_task(); void send_all_entities(std::shared_ptr& session); void update_ai(); + void update_move(); template EntityID create_entity_in_factory(Args&&... args) { auto entity = m_registry.create(); diff --git a/src/gameplay/local_player.cpp b/src/gameplay/local_player.cpp index 7208094..83522cc 100644 --- a/src/gameplay/local_player.cpp +++ b/src/gameplay/local_player.cpp @@ -473,7 +473,7 @@ void LocalPlayer::update_move(float dt) { if (m_game_mode == SPECTATOR) { player_pos += get_move_distance(dt); } else { - auto [x, y, z] = update_physical(dt); + auto [x, y, z] = update_physical(dt, player_pos); if (!x || !z) { m_sprinting = false; } @@ -736,22 +736,23 @@ void LocalPlayer::update_speed(float dt) { } } -std::tuple LocalPlayer::update_physical(float dt) { +std::tuple LocalPlayer::update_physical(float dt, + glm::vec3& pos) { auto distance = get_move_distance(dt); auto box = HitboxManager::hitbox(m_hitbox); bool x = false; bool y = false; bool z = false; - if (update_x(m_pos.value, distance, m_world, box.box)) { - m_pos.value.x += distance.x; + if (update_x(pos, distance, m_world, box.box)) { + pos.x += distance.x; x = true; } else { m_velocity.value.x = 0.0f; } - if (update_y(m_pos.value, distance, m_world, box.box)) { - m_pos.value.y += distance.y; + if (update_y(pos, distance, m_world, box.box)) { + pos.y += distance.y; y = true; } else { m_velocity.value.y = 0.0f; @@ -761,8 +762,8 @@ std::tuple LocalPlayer::update_physical(float dt) { } } - if (update_z(m_pos.value, distance, m_world, box.box)) { - m_pos.value.z += distance.z; + if (update_z(pos, distance, m_world, box.box)) { + pos.z += distance.z; z = true; } else { m_velocity.value.z = 0.0f; diff --git a/src/gameplay/server_entity_manager.cpp b/src/gameplay/server_entity_manager.cpp index 53a1297..222d792 100644 --- a/src/gameplay/server_entity_manager.cpp +++ b/src/gameplay/server_entity_manager.cpp @@ -6,6 +6,9 @@ #include "Cubed/gameplay/hitbox_manager.hpp" #include "Cubed/gameplay/server_world.hpp" #include "Cubed/gameplay/session.hpp" +#include "Cubed/gameplay/systems/physical_system.hpp" +#include "Cubed/gameplay/systems/speed_system.hpp" +#include "Cubed/gameplay/systems/wander_ai_system.hpp" #include "Cubed/tools/cubed_assert.hpp" #include "Cubed/tools/net_utils.hpp" using namespace google::protobuf; @@ -25,8 +28,15 @@ void ServerEntityManager::init() { void ServerEntityManager::update() { handle_task(); update_ai(); + update_move(); } +void ServerEntityManager::update_ai() { WanderAISystem::update(m_registry); } +void ServerEntityManager::update_move() { + SpeedSystem::update( + static_cast(m_world.get_per_tick_time()) / 1000.0f, m_registry); + PhysicalSystem::update(m_world, m_registry); +} void ServerEntityManager::handle_task() { TaskPair pair; while (m_tasks.try_pop(pair)) {