diff --git a/include/Cubed/gameplay/player_data.hpp b/include/Cubed/gameplay/client_player.hpp similarity index 63% rename from include/Cubed/gameplay/player_data.hpp rename to include/Cubed/gameplay/client_player.hpp index 3e38030..7388688 100644 --- a/include/Cubed/gameplay/player_data.hpp +++ b/include/Cubed/gameplay/client_player.hpp @@ -1,7 +1,12 @@ #pragma once -#include "Cubed/gameplay/entity.hpp" + +#include "Cubed/gameplay/ecs/animation.hpp" +#include "Cubed/gameplay/ecs/identity.hpp" +#include "Cubed/gameplay/ecs/transform.hpp" +#include "Cubed/gameplay/player.hpp" namespace Cubed { -struct PlayerData { + +struct ClientPlayer { Position pos{}; Position render_pos{}; EntityInfo entity{}; diff --git a/include/Cubed/gameplay/client_player_manager.hpp b/include/Cubed/gameplay/client_player_manager.hpp new file mode 100644 index 0000000..a5888b8 --- /dev/null +++ b/include/Cubed/gameplay/client_player_manager.hpp @@ -0,0 +1,45 @@ +#pragma once +#include "Cubed/gameplay/client_player.hpp" +#include "Cubed/gameplay/local_player.hpp" +#include "Cubed/gameplay/network_client.hpp" +#include "Cubed/tools/sparse_vector.hpp" +namespace Cubed { +class ClientWorld; +class ClientPlayerManager { +public: + ClientPlayerManager(const ClientPlayerManager&) = delete; + ClientPlayerManager(ClientPlayerManager&&) = delete; + ClientPlayerManager& operator=(const ClientPlayerManager&) = delete; + ClientPlayerManager& operator=(ClientPlayerManager&&) = delete; + ClientPlayerManager(ClientWorld& world); + ~ClientPlayerManager(); + + void init(std::string_view local_name); + void update(float dt); + + std::span render_player_data(); + + bool has_player(const Hitbox& hitbox) const; + + LocalPlayer& get_local(); + const LocalPlayer& get_local() const; + + void receive_remote_player(const PlayerInfoRsp& rsp); + void receive_player_logout(const LogoutRsp& rsp); + + void reload_config(); + + void report_player_info(NetworkClient* client); + +private: + ClientWorld& m_world; + mutable std::shared_mutex m_players_mutex; + using PlayerHandle = SparseVector::Handle; + SparseVector m_players; + std::vector m_render_data; + std::unordered_map m_players_handle; + LocalPlayer m_local; + + void update_players_data(float dt); +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/client_world.hpp b/include/Cubed/gameplay/client_world.hpp index 77ffe67..a1a777c 100644 --- a/include/Cubed/gameplay/client_world.hpp +++ b/include/Cubed/gameplay/client_world.hpp @@ -5,15 +5,14 @@ #include "Cubed/gameplay/chat_message.hpp" #include "Cubed/gameplay/chunk_pos.hpp" #include "Cubed/gameplay/client_chunk.hpp" +#include "Cubed/gameplay/client_player_manager.hpp" #include "Cubed/gameplay/game_time.hpp" #include "Cubed/gameplay/local_player.hpp" #include "Cubed/gameplay/network_client.hpp" -#include "Cubed/gameplay/player_data.hpp" #include "Cubed/gameplay/world.hpp" #include "Cubed/input/event.hpp" #include "Cubed/tools/cubed_random.hpp" #include "Cubed/tools/priority_thread_pool.hpp" -#include "Cubed/tools/sparse_vector.hpp" #include #include @@ -34,7 +33,6 @@ public: void init(std::string_view player_name, std::shared_ptr client); void update(float dt); - void update_players(float dt); bool handle_event(const Event& e); const std::optional& get_look_block_pos() const; LocalPlayer& get_player(); @@ -55,7 +53,6 @@ public: void receive_block_change(const BlockChangeRsp& rsp); void receive_time(const UpdateTime& rsp); - void receive_remote_player(const PlayerInfoRsp& rsp); void receive_player_logout(const LogoutRsp& rsp); void receive_player_water_sound(const PlayerWaterSound& rsp); void send_player_water_sound(bool underwater, const glm::vec3& pos); @@ -74,8 +71,6 @@ public: void reset_key_status(); std::vector& planes(); const std::vector& render_snapshots() const; - const std::vector& render_player_data() const; - std::vector& render_player_data(); glm::vec3 sunlight_dir() const; bool sphere_collide_world(glm::vec3 center, float radius) const; @@ -88,6 +83,7 @@ public: const AudioEngine& get_audio() const; Config& get_config(); WorldScene& world_scene(); + ClientPlayerManager& player_manager(); void set_direct_exit(); void receive_chat_message(ChatMsg& msg); @@ -131,7 +127,7 @@ private: static constexpr int WORLD_EXIT_TIMEOUT = 200; static constexpr int MAX_UPLOAD_CHUNK_SUM = 16; - LocalPlayer m_player; + ClientPlayerManager m_player_manager; ChunkHashMap m_chunks; AudioEngine& m_audio; Config& m_config; @@ -139,11 +135,6 @@ private: std::vector m_planes; std::jthread m_client_thread; - mutable std::shared_mutex m_players_date_mutex; - using PlayerHandle = SparseVector::Handle; - SparseVector m_players_data; - std::unordered_map m_players_handle; - tbb::concurrent_queue> m_pending_upload_queue; tbb::concurrent_queue m_dirty_chunk_queue; tbb::concurrent_queue m_pending_sound; @@ -152,7 +143,6 @@ private: std::deque m_dirty_queue; std::vector m_render_snapshots; - std::vector m_render_player_data; tbb::concurrent_unordered_map m_ticktimers; std::unordered_map m_timers; @@ -176,8 +166,6 @@ private: void client_run(std::stop_token token); - void report_player_info(); - void set_block(const glm::ivec3& pos, unsigned id); void update_chunk(const ChunkPosSet& old, const ChunkPosSet& now); diff --git a/include/Cubed/gameplay/creatures/pig.hpp b/include/Cubed/gameplay/creatures/pig.hpp new file mode 100644 index 0000000..cf2e83d --- /dev/null +++ b/include/Cubed/gameplay/creatures/pig.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace Cubed { +struct PigTag {}; + +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/ecs/animation.hpp b/include/Cubed/gameplay/ecs/animation.hpp new file mode 100644 index 0000000..4b02337 --- /dev/null +++ b/include/Cubed/gameplay/ecs/animation.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "Cubed/gameplay/player.hpp" +namespace Cubed { + +struct WalkPose { + Gait gait = Gait::STOP; + // for arm roll caculate + float walk_time = 0.0f; + // for sound play + float moving_time = 0.0f; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/ecs/client_entity.hpp b/include/Cubed/gameplay/ecs/client_entity.hpp new file mode 100644 index 0000000..042e76e --- /dev/null +++ b/include/Cubed/gameplay/ecs/client_entity.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "Cubed/gameplay/ecs/animation.hpp" +#include "Cubed/gameplay/ecs/entity.hpp" +#include "Cubed/gameplay/ecs/identity.hpp" +#include "Cubed/gameplay/ecs/transform.hpp" +#include "Cubed/gameplay/model.hpp" +namespace Cubed { +struct ClientEntity { + + Entity entity; + + EntityInfo info; + + Transform transform; + + WalkPose pose; + + ModelID model; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/ecs/entity.hpp b/include/Cubed/gameplay/ecs/entity.hpp new file mode 100644 index 0000000..d959538 --- /dev/null +++ b/include/Cubed/gameplay/ecs/entity.hpp @@ -0,0 +1,11 @@ +#pragma once +#include +namespace Cubed { +using EntityID = uint64_t; + +struct Entity { + EntityID id; + explicit Entity(EntityID id) : id(id) {} +}; + +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/ecs/health.hpp b/include/Cubed/gameplay/ecs/health.hpp new file mode 100644 index 0000000..7d65a76 --- /dev/null +++ b/include/Cubed/gameplay/ecs/health.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace Cubed { + +struct Health { + float hp = 20; + float max_hp = 20; +}; + +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/ecs/identity.hpp b/include/Cubed/gameplay/ecs/identity.hpp new file mode 100644 index 0000000..8982d52 --- /dev/null +++ b/include/Cubed/gameplay/ecs/identity.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace Cubed { +struct EntityInfo { + std::string name; + std::string uuid; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/ecs/movement.hpp b/include/Cubed/gameplay/ecs/movement.hpp new file mode 100644 index 0000000..1307d73 --- /dev/null +++ b/include/Cubed/gameplay/ecs/movement.hpp @@ -0,0 +1,26 @@ +#pragma once +#include "Cubed/constants.hpp" + +#include +namespace Cubed { +struct Velocity { + + glm::vec3 value{0.0f}; + + glm::vec3 max{4.5f, 7.5f, 7.5f}; +}; + +struct Movement { + + float acceleration = DEFAULT_ACCELERATION; + + float deceleration = DEFAULT_DECELERATION; + + float jump_power = 7.5f; +}; + +struct Gravity { + + float value = DEFAULT_G; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/ecs/server_entity.hpp b/include/Cubed/gameplay/ecs/server_entity.hpp new file mode 100644 index 0000000..d181110 --- /dev/null +++ b/include/Cubed/gameplay/ecs/server_entity.hpp @@ -0,0 +1,32 @@ +#pragma once +#include "Cubed/gameplay/ecs/entity.hpp" +#include "Cubed/gameplay/ecs/health.hpp" +#include "Cubed/gameplay/ecs/identity.hpp" +#include "Cubed/gameplay/ecs/movement.hpp" +#include "Cubed/gameplay/ecs/state.hpp" +#include "Cubed/gameplay/ecs/transform.hpp" +#include "Cubed/gameplay/hitbox.hpp" +namespace Cubed { +struct ServerEntity { + + Entity entity; + + EntityInfo info; + + Transform transform; + + Velocity velocity; + + Movement movement; + + MoveState move_state; + + Direction direction; + + Gravity gravity; + + Health health; + + HitboxID hitbox; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/ecs/state.hpp b/include/Cubed/gameplay/ecs/state.hpp new file mode 100644 index 0000000..4a2e91d --- /dev/null +++ b/include/Cubed/gameplay/ecs/state.hpp @@ -0,0 +1,18 @@ +#pragma once + +namespace Cubed { +struct MoveState { + + bool forward = false; + bool back = false; + bool left = false; + bool right = false; + + bool down = false; + bool up = false; + + bool is_fly = false; + bool can_up = true; +}; + +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/ecs/transform.hpp b/include/Cubed/gameplay/ecs/transform.hpp new file mode 100644 index 0000000..99aa8d7 --- /dev/null +++ b/include/Cubed/gameplay/ecs/transform.hpp @@ -0,0 +1,24 @@ +#pragma once +#include +namespace Cubed { +struct Position { + glm::vec3 value{0.0f}; +}; + +struct Orientation { + float yaw = 0.0f; + float pitch = 0.0f; + float roll = 0.0f; +}; + +struct Direction { + glm::vec3 value{0.0f}; +}; + +struct Transform { + Position position; + Orientation orientation; + Direction direction; +}; + +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/entity.hpp b/include/Cubed/gameplay/entity.hpp deleted file mode 100644 index d13860e..0000000 --- a/include/Cubed/gameplay/entity.hpp +++ /dev/null @@ -1,120 +0,0 @@ -#pragma once -#include "Cubed/constants.hpp" -#include "Cubed/gameplay/hitbox.hpp" -#include "Cubed/gameplay/model.hpp" -#include "Cubed/gameplay/player.hpp" - -#include -#include -namespace Cubed { -using EntityID = uint64_t; -struct Position { - glm::vec3 value{0.0f}; -}; - -struct WalkPose { - Gait gait = Gait::STOP; - // for arm roll caculate - float walk_time = 0.0f; - // for sound play - float moving_time = 0.0f; -}; - -struct EntityInfo { - std::string name; - std::string uuid; - EntityID id; - HitboxID hitbox; - ModelID model; -}; - -struct Health { - float hp = 20; - float max_hp = 20; -}; - -struct Orientation { - float yaw = 0.0f; - float pitch = 0.0f; - float roll = 0.0f; -}; - -struct Velocity { - glm::vec3 value{0.0f}; - glm::vec3 max{4.5f, 7.5f, 7.5f}; -}; - -struct Movement { - float acceleration = DEFAULT_ACCELERATION; - float deceleration = DEFAULT_DECELERATION; - float jump_power = 7.5f; -}; - -struct Gravity { - float value = DEFAULT_G; -}; - -struct MoveState { - bool forward = false; - bool back = false; - bool left = false; - bool right = false; - bool down = false; - bool up = false; - - bool is_fly = false; - bool can_up = true; -}; - -struct Direction { - glm::vec3 value{0.0f}; -}; - -class Entity { -public: - Entity(EntityID id, const std::string& name); - - glm::vec3& max_speed(); - float& acceleration(); - float& deceleration(); - float& g(); - void set_gait(Gait gait); - float yaw() const; - float pitch() const; - float& roll(); - float& walk_time(); - Gait get_gait() const; - - Velocity& velocity(); - Position& pos(); - WalkPose& walk_pose(); - Orientation& angle(); - Movement& movement(); - Gravity& gravity(); - MoveState& move_state(); - Direction& direction(); - EntityInfo& info(); - - const Velocity& velocity() const; - const Position& pos() const; - const WalkPose& walk_pose() const; - const Orientation& angle() const; - const Movement& movement() const; - const Gravity& gravity() const; - const MoveState& move_state() const; - const Direction& direction() const; - const EntityInfo& info() const; - -protected: - EntityInfo m_info; - Position m_pos; - WalkPose m_walk_pose; - Velocity m_velocity; - Orientation m_angle; - Movement m_movement; - Gravity m_gravity; - MoveState m_move_state; - Direction m_direction; -}; - -} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/local_player.hpp b/include/Cubed/gameplay/local_player.hpp index 0329eeb..4f3c535 100644 --- a/include/Cubed/gameplay/local_player.hpp +++ b/include/Cubed/gameplay/local_player.hpp @@ -2,9 +2,14 @@ #include "Cubed/constants.hpp" #include "Cubed/gameplay/block.hpp" #include "Cubed/gameplay/chunk_pos.hpp" -#include "Cubed/gameplay/entity.hpp" +#include "Cubed/gameplay/ecs/animation.hpp" +#include "Cubed/gameplay/ecs/identity.hpp" +#include "Cubed/gameplay/ecs/movement.hpp" +#include "Cubed/gameplay/ecs/state.hpp" +#include "Cubed/gameplay/ecs/transform.hpp" #include "Cubed/gameplay/game_mode.hpp" #include "Cubed/gameplay/game_time.hpp" +#include "Cubed/gameplay/hitbox.hpp" #include "Cubed/gameplay/item_stack.hpp" #include "Cubed/gameplay/player.hpp" #include "Cubed/input/event.hpp" @@ -17,7 +22,7 @@ namespace Cubed { class ClientWorld; -class LocalPlayer : public Entity { +class LocalPlayer { public: static constexpr size_t HOTBAR_SUM = 10; static constexpr float WALK_SOUND_INTERVAL = 0.45f; @@ -35,6 +40,7 @@ public: bool update_scroll(float yoffset); void update_chunk_set(const ChunkPosSet& set); + const ChunkPosSet& get_chunk_pos_set() const; ChunkPosSet get_chunk_pos_set(); @@ -77,6 +83,17 @@ public: void set_hotbar(int pos, const ItemStack& item); std::span get_hotbar() const; + glm::vec3& max_speed(); + float& acceleration(); + float& deceleration(); + float& g(); + void set_gait(Gait gait); + float yaw() const; + float pitch() const; + float& roll(); + float& walk_time(); + Gait get_gait() const; + private: using enum GameMode; float m_max_walk_speed = DEFAULT_MAX_WALK_SPEED; @@ -84,8 +101,18 @@ private: float m_max_y_speed = 7.5f; static constexpr float MAX_SPACE_ON_TIME = 0.3f; static constexpr float PLACE_BLOCK_INTERVAL = 0.2f; - Movement m_movement{}; - Gravity m_gravity{}; + + EntityInfo m_info; + Position m_pos; + WalkPose m_walk_pose; + Velocity m_velocity; + Orientation m_angle; + Movement m_movement; + Gravity m_gravity; + MoveState m_move_state; + Direction m_direction; + HitboxID m_hitbox = 0; + float m_place_time = PLACE_BLOCK_INTERVAL; std::array m_hotbar; diff --git a/include/Cubed/gameplay/systems/physical_system.hpp b/include/Cubed/gameplay/systems/physical_system.hpp index f606621..c5f60ad 100644 --- a/include/Cubed/gameplay/systems/physical_system.hpp +++ b/include/Cubed/gameplay/systems/physical_system.hpp @@ -1,15 +1,20 @@ #pragma once - -#include "Cubed/gameplay/entity.hpp" +#include "Cubed//gameplay/ecs/server_entity.hpp" #include "Cubed/gameplay/world.hpp" namespace Cubed { + class PhysicalSystem { public: - static glm::vec3 get_move_distance(float dt, const Entity& e); - static std::tuple update(float dt, Entity& e, + static glm::vec3 get_move_distance(float dt, const Direction& d, + const Velocity& v); + static std::tuple update(float dt, ServerEntity& e, World& world); static std::tuple - update(float dt, Entity& e, World& world, glm::vec3& moved_pos); + update(float dt, ServerEntity& e, World& world, glm::vec3& moved_pos); + + static std::tuple + update(float dt, World& world, glm::vec3& moved_pos, Velocity& v, + Direction& direction, MoveState& move_state, HitboxID hitbox); private: }; diff --git a/include/Cubed/gameplay/systems/speed_system.hpp b/include/Cubed/gameplay/systems/speed_system.hpp index 6537db6..31b3966 100644 --- a/include/Cubed/gameplay/systems/speed_system.hpp +++ b/include/Cubed/gameplay/systems/speed_system.hpp @@ -1,11 +1,15 @@ #pragma once -#include "Cubed/gameplay/entity.hpp" +#include "Cubed/gameplay/ecs/server_entity.hpp" +#include "Cubed/gameplay/ecs/state.hpp" namespace Cubed { class SpeedSystem { public: - static void update(float dt, Entity& e); + static void update(float dt, ServerEntity& e); + static void update(float dt, Velocity& v, MoveState& move_state, + Movement& movement, Direction& direction, + const Gravity& g); private: }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a43a62a..b1ff10f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,7 +97,7 @@ target_sources(${PROJECT_NAME} render/model_renderer.cpp gameplay/chunk.cpp gameplay/hitbox_manager.cpp - gameplay/entity.cpp gameplay/systems/physical_system.cpp gameplay/systems/speed_system.cpp + gameplay/client_player_manager.cpp ) \ No newline at end of file diff --git a/src/gameplay/client_player_manager.cpp b/src/gameplay/client_player_manager.cpp new file mode 100644 index 0000000..2589834 --- /dev/null +++ b/src/gameplay/client_player_manager.cpp @@ -0,0 +1,219 @@ +#pragma once +#include "Cubed/gameplay/client_player_manager.hpp" + +#include "Cubed/gameplay/client_world.hpp" +#include "Cubed/gameplay/hitbox_manager.hpp" +#include "Cubed/tools/math_tools.hpp" + +using namespace google::protobuf; + +namespace Cubed { +ClientPlayerManager::ClientPlayerManager(ClientWorld& world) + : m_world(world), m_local(world) {} +ClientPlayerManager::~ClientPlayerManager() { + +}; + +void ClientPlayerManager::init(std::string_view local_name) { + m_local.init(local_name); +} + +void ClientPlayerManager::update(float dt) { + m_local.update(dt); + + update_players_data(dt); +} + +bool ClientPlayerManager::has_player(const Hitbox& hitbox) const { + std::shared_lock lock(m_players_mutex); + + for (const auto& player : m_players) { + + auto box = HitboxManager::hitbox("cubed:player"); + box.box.center += player.pos.value; + if (box.box.intersects(hitbox)) { + return true; + } + } + return false; +} + +void ClientPlayerManager::receive_remote_player(const PlayerInfoRsp& rsp) { + auto pitch = rsp.pitch(); + auto yaw = rsp.yaw(); + { + std::lock_guard lock(m_players_mutex); + glm::vec3 pos{rsp.pos().x(), rsp.pos().y(), rsp.pos().z()}; + auto it = m_players_handle.find(rsp.uuid()); + if (it == m_players_handle.end()) { + ClientPlayer data{}; + data.entity.name = rsp.name(); + data.entity.uuid = rsp.uuid(); + data.angle.pitch = pitch; + data.angle.yaw = yaw; + data.render_angle.pitch = pitch; + data.render_angle.yaw = yaw; + data.pos.value = pos; + data.render_pos.value = pos; + data.walk.gait = get_gait_from_id(rsp.gait()); + auto handle = m_players.emplace(std::move(data)); + m_players_handle.try_emplace(rsp.uuid(), handle); + } else { + auto it = m_players_handle.find(rsp.uuid()); + if (it != m_players_handle.end()) { + auto& data = m_players[it->second]; + data.pos.value = pos; + data.walk.gait = get_gait_from_id(rsp.gait()); + data.angle.yaw = yaw; + data.angle.pitch = pitch; + } + } + // Logger::info("Player {} pos Update", rsp.name()); + } +} + +void ClientPlayerManager::receive_player_logout(const LogoutRsp& rsp) { + { + std::lock_guard lock(m_players_mutex); + auto it = m_players_handle.find(rsp.uuid()); + if (it == m_players_handle.end()) { + Logger::warn("Player {} not find", rsp.uuid()); + } else { + m_players.erase(it->second); + m_players_handle.erase(it); + Logger::info("Player {} erase", rsp.uuid()); + } + } +} + +void ClientPlayerManager::reload_config() { m_local.reload_config(); } + +void ClientPlayerManager::report_player_info(NetworkClient* client) { + if (!client) { + return; + } + Arena arena; + auto* info = Arena::Create(&arena); + info->set_uuid(m_local.get_uuid()); + glm::vec3 player_pos = m_local.get_player_pos(); + auto* v3 = info->mutable_pos(); + v3->set_x(player_pos.x); + v3->set_y(player_pos.y); + v3->set_z(player_pos.z); + info->set_yaw(m_local.yaw()); + info->set_pitch(m_local.pitch()); + info->set_gait(get_gait_id(m_local.get_gait())); + + client->send(make_packet(*info), 0); +} + +void ClientPlayerManager::update_players_data(float dt) { + m_render_data.clear(); + auto m_rendering_distance = m_world.rendering_distance(); + auto update_renderinfo = [this, dt, + m_rendering_distance](ClientPlayer& player) { + player.render_pos.value = + glm::mix(player.render_pos.value, player.pos.value, 0.15f); + if (Math::distance2(player.render_pos.value, m_local.get_player_pos()) > + m_rendering_distance * CHUNK_SIZE * m_rendering_distance * + CHUNK_SIZE) { + return; + } + player.render_angle.yaw = + glm::mix(player.render_angle.yaw, player.angle.yaw, 0.15); + player.render_angle.pitch = + glm::mix(player.render_angle.pitch, player.angle.pitch, 0.15); + + if (player.walk.gait == Gait::WALK || player.walk.gait == Gait::RUN) { + + player.walk.walk_time += dt; + + float speed = player.walk.gait == Gait::RUN ? 14.0f : 8.0f; + float amp = player.walk.gait == Gait::RUN ? 50.0f : 35.0f; + // float amp = 90.0f; + player.render_angle.roll = + glm::sin(player.walk.walk_time * speed) * glm::radians(amp); + } else if (player.walk.gait == Gait::STOP) { + float t = glm::clamp(dt * 10.0f, 0.0f, 1.0f); + player.render_angle.roll = + glm::mix(player.render_angle.roll, 0.0f, t); + } + + // walking sound + if (player.walk.gait == Gait::STOP) { + player.walk.moving_time = 0.0f; + } else { + player.walk.moving_time += dt; + } + auto play_walk_sound = [&]() { + glm::ivec3 block = glm::floor(player.render_pos.value); + block.y -= 1; + BlockType id = m_world.get_block_tpye(block); + if (id == 0) { + return; + } + std::string name = BlockManager::name_form_id(id); + std::string sound = "block/" + name + "/walk.ogg"; + m_world.get_audio().play_3d(sound, player.render_pos.value); + }; + if (player.walk.gait == Gait::WALK) { + if (player.walk.moving_time >= LocalPlayer::WALK_SOUND_INTERVAL) { + player.walk.moving_time = 0.0f; + play_walk_sound(); + } + } + if (player.walk.gait == Gait::RUN) { + if (player.walk.moving_time >= LocalPlayer::RUN_SOUND_INTERVAL) { + player.walk.moving_time = 0.0f; + play_walk_sound(); + } + } + PlayerRenderData render_data; + render_data.render_pos = player.render_pos; + render_data.angle = player.render_angle; + render_data.gait = player.walk.gait; + render_data.info = player.entity; + m_render_data.emplace_back(std::move(render_data)); + }; + + { + std::lock_guard lock(m_players_mutex); + + for (auto& player : m_players) { + update_renderinfo(player); + } + { + auto gait = m_local.get_gait(); + auto& walk_time = m_local.walk_time(); + auto& angle = m_local.roll(); + if (gait == Gait::WALK || gait == Gait::RUN) { + + walk_time += dt; + + float speed = gait == Gait::RUN ? 14.0f : 8.0f; + float amp = gait == Gait::RUN ? 50.0f : 35.0f; + // float amp = 90.0f; + angle = glm::sin(walk_time * speed) * glm::radians(amp); + } else if (gait == Gait::STOP) { + float t = glm::clamp(dt * 10.0f, 0.0f, 1.0f); + angle = glm::mix(angle, 0.0f, t); + } + PlayerRenderData render_data{}; + render_data.render_pos.value = m_local.get_player_pos(); + render_data.angle.yaw = m_local.yaw(); + render_data.angle.pitch = m_local.pitch(); + render_data.angle.roll = angle; + render_data.gait = m_local.get_gait(); + render_data.info.name = m_local.get_name(); + render_data.info.uuid = m_local.get_uuid(); + m_render_data.emplace_back(std::move(render_data)); + } + } +} + +LocalPlayer& ClientPlayerManager::get_local() { return m_local; } +const LocalPlayer& ClientPlayerManager::get_local() const { return m_local; } +std::span ClientPlayerManager::render_player_data() { + return m_render_data; +} +} // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/client_world.cpp b/src/gameplay/client_world.cpp index abff8d3..8ff7157 100644 --- a/src/gameplay/client_world.cpp +++ b/src/gameplay/client_world.cpp @@ -2,12 +2,9 @@ #include "Cubed/config.hpp" #include "Cubed/gameplay/chunk_generator.hpp" -#include "Cubed/gameplay/entity.hpp" #include "Cubed/gameplay/game_time.hpp" -#include "Cubed/gameplay/hitbox_manager.hpp" #include "Cubed/gameplay/packet.hpp" #include "Cubed/scene/world_scene.hpp" -#include "Cubed/tools/math_tools.hpp" #include "Cubed/tools/time_tools.hpp" #include @@ -26,7 +23,8 @@ struct ChunkRenderData { } // namespace ClientWorld::ClientWorld(AudioEngine& auido, Config& config, WorldScene& scene) - : m_player(*this), m_audio(auido), m_config(config), m_world_scene(scene) {} + : m_player_manager(*this), m_audio(auido), m_config(config), + m_world_scene(scene) {} ClientWorld::~ClientWorld() { m_client->close(); @@ -58,11 +56,13 @@ ClientWorld::~ClientWorld() { const std::optional& ClientWorld::get_look_block_pos() const { - return m_player.get_look_block_pos(); + return m_player_manager.get_local().get_look_block_pos(); } -LocalPlayer& ClientWorld::get_player() { return m_player; } -const LocalPlayer& ClientWorld::get_player() const { return m_player; } +LocalPlayer& ClientWorld::get_player() { return m_player_manager.get_local(); } +const LocalPlayer& ClientWorld::get_player() const { + return m_player_manager.get_local(); +} int ClientWorld::get_block(const glm::ivec3& block_pos) const { auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z); chunk_cacc cacc; @@ -129,7 +129,7 @@ void ClientWorld::rebuild_world() { m_pending_upload_queue.clear(); start_thread_pool(); - start_client_thread(m_player.get_uuid()); + start_client_thread(m_player_manager.get_local().get_uuid()); request_chunk(); m_is_rebuilding = false; } @@ -296,21 +296,14 @@ void ClientWorld::report_block_change(const glm::ivec3& pos, unsigned id) const { if (id != 0) { Hitbox block_box = get_block_aabb(pos); - std::shared_lock lock(m_players_date_mutex); - - for (const auto& player : m_players_data) { - - auto box = HitboxManager::hitbox("cubed:player"); - box.box.center += player.pos.value; - if (box.box.intersects(block_box)) { - return; - } + if (m_player_manager.has_player(block_box)) { + return; } } Arena arena; auto* req = Arena::Create(&arena); - req->set_uuid(m_player.get_uuid()); + req->set_uuid(m_player_manager.get_local().get_uuid()); req->set_block(id); auto* p = req->mutable_pos(); p->set_x(pos.x); @@ -329,64 +322,20 @@ void ClientWorld::receive_time(const UpdateTime& rsp) { m_day_tick = rsp.day_tick(); } -void ClientWorld::receive_remote_player(const PlayerInfoRsp& rsp) { - auto pitch = rsp.pitch(); - auto yaw = rsp.yaw(); - { - std::lock_guard lock(m_players_date_mutex); - glm::vec3 pos{rsp.pos().x(), rsp.pos().y(), rsp.pos().z()}; - auto it = m_players_handle.find(rsp.uuid()); - if (it == m_players_handle.end()) { - PlayerData data{}; - data.entity.name = rsp.name(); - data.entity.uuid = rsp.uuid(); - data.angle.pitch = pitch; - data.angle.yaw = yaw; - data.render_angle.pitch = pitch; - data.render_angle.yaw = yaw; - data.pos.value = pos; - data.render_pos.value = pos; - data.walk.gait = get_gait_from_id(rsp.gait()); - auto handle = m_players_data.emplace(std::move(data)); - m_players_handle.try_emplace(rsp.uuid(), handle); - } else { - auto it = m_players_handle.find(rsp.uuid()); - if (it != m_players_handle.end()) { - auto& data = m_players_data[it->second]; - data.pos.value = pos; - data.walk.gait = get_gait_from_id(rsp.gait()); - data.angle.yaw = yaw; - data.angle.pitch = pitch; - } - } - // Logger::info("Player {} pos Update", rsp.name()); - } -} - void ClientWorld::receive_player_logout(const LogoutRsp& rsp) { if (rsp.server_stop()) { m_receive_exit = true; return; } - if (rsp.uuid() == m_player.get_uuid()) { + if (rsp.uuid() == m_player_manager.get_local().get_uuid()) { m_receive_exit = true; return; } - { - std::lock_guard lock(m_players_date_mutex); - auto it = m_players_handle.find(rsp.uuid()); - if (it == m_players_handle.end()) { - Logger::warn("Player {} not find", rsp.uuid()); - } else { - m_players_data.erase(it->second); - m_players_handle.erase(it); - Logger::info("Player {} erase", rsp.uuid()); - } - } + m_player_manager.receive_player_logout(rsp); } void ClientWorld::receive_player_water_sound(const PlayerWaterSound& rsp) { - if (rsp.uuid() == m_player.get_uuid()) { + if (rsp.uuid() == m_player_manager.get_local().get_uuid()) { return; } glm::vec3 pos = {rsp.pos().x(), rsp.pos().y(), rsp.pos().z()}; @@ -406,7 +355,7 @@ void ClientWorld::send_player_water_sound(bool underwater, p->set_x(pos.x); p->set_y(pos.y); p->set_z(pos.z); - r->set_uuid(m_player.get_uuid()); + r->set_uuid(m_player_manager.get_local().get_uuid()); m_client->send(make_packet(*r)); Logger::info("Client: Send Player Water Sound"); @@ -414,7 +363,7 @@ void ClientWorld::send_player_water_sound(bool underwater, void ClientWorld::init(std::string_view player_name, std::shared_ptr client) { - m_player.init(player_name); + m_player_manager.init(player_name); m_client = client; reload_config(false); @@ -422,9 +371,11 @@ void ClientWorld::init(std::string_view player_name, m_random.init(ChunkGenerator::seed()); // timer - register_ticktimer("player_pos", 1, [this]() { report_player_info(); }); + register_ticktimer("player_pos", 1, [this]() { + m_player_manager.report_player_info(m_client.get()); + }); m_timers.try_emplace("Birds Sound", 60.0f, [this]() { - auto player_pos = m_player.get_player_pos(); + auto player_pos = m_player_manager.get_local().get_player_pos(); if (player_pos.y < SEA_LEVEL) { return; } @@ -440,7 +391,7 @@ void ClientWorld::init(std::string_view player_name, }); m_timers.try_emplace("Ocean Wave", 3.0f, [this]() { - auto player_pos = m_player.get_player_pos(); + auto player_pos = m_player_manager.get_local().get_player_pos(); if (player_pos.y < SEA_LEVEL - 10 || player_pos.y > SEA_LEVEL + 10) { return; } @@ -460,11 +411,12 @@ void ClientWorld::init(std::string_view player_name, }); m_timers.try_emplace("under water bubble", 1.5f, [this]() { - if (m_player.is_underwater()) { + if (m_player_manager.get_local().is_underwater()) { auto ans = m_random.random_int(1, 2); std::string sound = "ambient/water/bubble00" + std::to_string(ans) + ".ogg"; - m_audio.play_3d(sound, m_player.get_player_pos(), true); + m_audio.play_3d( + sound, m_player_manager.get_local().get_player_pos(), true); } }); @@ -477,7 +429,7 @@ void ClientWorld::init(std::string_view player_name, }); LoginReq req; - req.set_name(m_player.get_name()); + req.set_name(m_player_manager.get_local().get_name()); while (!client->is_connected()) { if (client->is_connect_error()) { throw std::runtime_error(client->get_error_string()); @@ -502,7 +454,7 @@ void ClientWorld::start_client_thread(std::string_view uuid) { return; } // response - m_player.set_uuid(uuid); + m_player_manager.get_local().set_uuid(uuid); m_client_thread = std::jthread([this](std::stop_token token) { m_game_running = true; @@ -557,7 +509,7 @@ void ClientWorld::reload_config(bool chunk_build) { request_chunk(); } - m_player.reload_config(); + m_player_manager.reload_config(); } void ClientWorld::client_run(std::stop_token stoken) { @@ -576,25 +528,6 @@ void ClientWorld::client_run(std::stop_token stoken) { } } -void ClientWorld::report_player_info() { - if (!m_client) { - return; - } - Arena arena; - auto* info = Arena::Create(&arena); - info->set_uuid(m_player.get_uuid()); - glm::vec3 player_pos = m_player.get_player_pos(); - auto* v3 = info->mutable_pos(); - v3->set_x(player_pos.x); - v3->set_y(player_pos.y); - v3->set_z(player_pos.z); - info->set_yaw(m_player.yaw()); - info->set_pitch(m_player.pitch()); - info->set_gait(get_gait_id(m_player.get_gait())); - - m_client->send(make_packet(*info), 0); -} - void ClientWorld::update_chunk(const ChunkPosSet& old, const ChunkPosSet& now) { // Elements in the old set that are not contained in now are not needed by @@ -622,7 +555,7 @@ void ClientWorld::request_chunk() { } ChunkPosSet required_chunks; - glm::vec3 player_pos = m_player.get_player_pos(); + glm::vec3 player_pos = m_player_manager.get_local().get_player_pos(); int x = std::floor(player_pos.x); int z = std::floor(player_pos.z); @@ -640,8 +573,8 @@ void ClientWorld::request_chunk() { } } - ChunkPosSet old = m_player.get_chunk_pos_set(); - m_player.update_chunk_set(required_chunks); + ChunkPosSet old = m_player_manager.get_local().get_chunk_pos_set(); + m_player_manager.get_local().update_chunk_set(required_chunks); ChunkPosVector need_send_pos; @@ -665,7 +598,7 @@ void ClientWorld::request_chunk() { break; case CENTER: { - glm::vec3 player_pos = m_player.get_player_pos(); + glm::vec3 player_pos = m_player_manager.get_local().get_player_pos(); ChunkPos player_chunk_pos = get_chunk_pos(player_pos.x, player_pos.z); auto dist2 = [player_chunk_pos](ChunkPos chunk_pos) { float dx = player_chunk_pos.x - chunk_pos.x; @@ -679,7 +612,7 @@ void ClientWorld::request_chunk() { }); } } - auto uuid = m_player.get_uuid(); + auto uuid = m_player_manager.get_local().get_uuid(); Arena arena; ++m_chunk_task_id; auto* req = Arena::Create(&arena); @@ -694,7 +627,9 @@ void ClientWorld::request_chunk() { Logger::info("Send Chunk Request Success"); m_requesting_chunk = false; } -void ClientWorld::reset_key_status() { m_player.reset_input_status(); } +void ClientWorld::reset_key_status() { + m_player_manager.get_local().reset_input_status(); +} void ClientWorld::receive_chunk(std::vector raw_data, PacketHeader header) { @@ -741,6 +676,7 @@ AudioEngine& ClientWorld::get_audio() { return m_audio; } const AudioEngine& ClientWorld::get_audio() const { return m_audio; } Config& ClientWorld::get_config() { return m_config; } WorldScene& ClientWorld::world_scene() { return m_world_scene; } +ClientPlayerManager& ClientWorld::player_manager() { return m_player_manager; } void ClientWorld::set_direct_exit() { m_exit_direct = true; } void ClientWorld::request_exit() { if (m_receive_exit) { @@ -748,7 +684,7 @@ void ClientWorld::request_exit() { } Arena arena; auto* req = Arena::Create(&arena); - req->set_uuid(m_player.get_uuid()); + req->set_uuid(m_player_manager.get_local().get_uuid()); m_client->send(make_packet(*req)); int cnt = 0; while (!m_receive_exit) { @@ -789,8 +725,7 @@ void ClientWorld::send_chat_message(ChatMessage& message) { } void ClientWorld::update(float delta_time) { - - m_player.update(delta_time); + m_player_manager.update(delta_time); { std::lock_guard lk(m_delete_vbo_mutex); m_pending_delete_vbo.clear(); @@ -841,7 +776,7 @@ void ClientWorld::update(float delta_time) { chunk->upload_to_gpu(); } - auto chunk_pos_set = m_player.get_chunk_pos_set(); + auto chunk_pos_set = m_player_manager.get_local().get_chunk_pos_set(); for (auto& pos : chunk_pos_set) { std::shared_ptr chunk; @@ -858,9 +793,6 @@ void ClientWorld::update(float delta_time) { m_render_snapshots.push_back(chunk->get_render_snapshot()); } - m_render_player_data.clear(); - update_players(delta_time); - // sound PendingSound pending_sound; while (m_pending_sound.try_pop(pending_sound)) { @@ -881,134 +813,32 @@ void ClientWorld::update(float delta_time) { } } -void ClientWorld::update_players(float dt) { - - auto update_renderinfo = [this, dt](PlayerData& player) { - player.render_pos.value = - glm::mix(player.render_pos.value, player.pos.value, 0.15f); - if (Math::distance2(player.render_pos.value, - m_player.get_player_pos()) > - m_rendering_distance * CHUNK_SIZE * m_rendering_distance * - CHUNK_SIZE) { - return; - } - player.render_angle.yaw = - glm::mix(player.render_angle.yaw, player.angle.yaw, 0.15); - player.render_angle.pitch = - glm::mix(player.render_angle.pitch, player.angle.pitch, 0.15); - - if (player.walk.gait == Gait::WALK || player.walk.gait == Gait::RUN) { - - player.walk.walk_time += dt; - - float speed = player.walk.gait == Gait::RUN ? 14.0f : 8.0f; - float amp = player.walk.gait == Gait::RUN ? 50.0f : 35.0f; - // float amp = 90.0f; - player.render_angle.roll = - glm::sin(player.walk.walk_time * speed) * glm::radians(amp); - } else if (player.walk.gait == Gait::STOP) { - float t = glm::clamp(dt * 10.0f, 0.0f, 1.0f); - player.render_angle.roll = - glm::mix(player.render_angle.roll, 0.0f, t); - } - - // walking sound - if (player.walk.gait == Gait::STOP) { - player.walk.moving_time = 0.0f; - } else { - player.walk.moving_time += dt; - } - auto play_walk_sound = [&]() { - glm::ivec3 block = glm::floor(player.render_pos.value); - block.y -= 1; - BlockType id = get_block_tpye(block); - if (id == 0) { - return; - } - std::string name = BlockManager::name_form_id(id); - std::string sound = "block/" + name + "/walk.ogg"; - m_audio.play_3d(sound, player.render_pos.value); - }; - if (player.walk.gait == Gait::WALK) { - if (player.walk.moving_time >= LocalPlayer::WALK_SOUND_INTERVAL) { - player.walk.moving_time = 0.0f; - play_walk_sound(); - } - } - if (player.walk.gait == Gait::RUN) { - if (player.walk.moving_time >= LocalPlayer::RUN_SOUND_INTERVAL) { - player.walk.moving_time = 0.0f; - play_walk_sound(); - } - } - PlayerRenderData render_data; - render_data.render_pos = player.render_pos; - render_data.angle = player.render_angle; - render_data.gait = player.walk.gait; - render_data.info = player.entity; - m_render_player_data.emplace_back(std::move(render_data)); - }; - - { - std::lock_guard lock(m_players_date_mutex); - - for (auto& player : m_players_data) { - update_renderinfo(player); - } - { - auto gait = m_player.get_gait(); - auto& walk_time = m_player.walk_time(); - auto& angle = m_player.roll(); - if (gait == Gait::WALK || gait == Gait::RUN) { - - walk_time += dt; - - float speed = gait == Gait::RUN ? 14.0f : 8.0f; - float amp = gait == Gait::RUN ? 50.0f : 35.0f; - // float amp = 90.0f; - angle = glm::sin(walk_time * speed) * glm::radians(amp); - } else if (gait == Gait::STOP) { - float t = glm::clamp(dt * 10.0f, 0.0f, 1.0f); - angle = glm::mix(angle, 0.0f, t); - } - PlayerRenderData render_data{}; - render_data.render_pos.value = m_player.get_player_pos(); - render_data.angle.yaw = m_player.yaw(); - render_data.angle.pitch = m_player.pitch(); - render_data.angle.roll = angle; - render_data.gait = m_player.get_gait(); - render_data.info.name = m_player.get_name(); - render_data.info.uuid = m_player.get_uuid(); - m_render_player_data.emplace_back(std::move(render_data)); - } - } -} - bool ClientWorld::handle_event(const Event& e) { return std::visit( - Overloaded{[this](const MouseButtonEvent& e) { - if (m_player.handle_mouse_button_event(e)) { - return true; - } - return false; - }, - [](const MouseMoveEvent&) { return false; }, - [this](const MouseWheelEvent& e) { - if (m_player.handle_mouse_wheel_event(e)) { - return true; - } - return false; - }, - [this](const KeyEvent& e) { - if (m_player.handle_key_event(e)) { - return true; - } + Overloaded{ + [this](const MouseButtonEvent& e) { + if (m_player_manager.get_local().handle_mouse_button_event(e)) { + return true; + } + return false; + }, + [](const MouseMoveEvent&) { return false; }, + [this](const MouseWheelEvent& e) { + if (m_player_manager.get_local().handle_mouse_wheel_event(e)) { + return true; + } + return false; + }, + [this](const KeyEvent& e) { + if (m_player_manager.get_local().handle_key_event(e)) { + return true; + } - return false; - }, - [](const TextInputEvent&) { return false; }, - [](const WindowResizeEvent&) { return false; }, - [](const FrameBufferResizeEvent&) { return false; } + return false; + }, + [](const TextInputEvent&) { return false; }, + [](const WindowResizeEvent&) { return false; }, + [](const FrameBufferResizeEvent&) { return false; } }, e); @@ -1075,11 +905,6 @@ const std::vector& ClientWorld::render_snapshots() const { return m_render_snapshots; }; -const std::vector& ClientWorld::render_player_data() const { - return m_render_player_data; -} -std::vector& ClientWorld::render_player_data() { - return m_render_player_data; -} + std::vector& ClientWorld::planes() { return m_planes; } } // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/entity.cpp b/src/gameplay/entity.cpp deleted file mode 100644 index 2d98c92..0000000 --- a/src/gameplay/entity.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "Cubed/gameplay/entity.hpp" - -#include "Cubed/gameplay/hitbox_manager.hpp" -#include "Cubed/render/model_manager.hpp" -namespace Cubed { - -Entity::Entity(EntityID id, const std::string& name) { - m_info.id = id; - m_info.name = name; - auto h = ModelManager::model(name); - m_info.model = h.id; - auto b = HitboxManager::hitbox(name); - m_info.hitbox = b.id; -} - -glm::vec3& Entity::max_speed() { return m_velocity.max; } -float& Entity::acceleration() { return m_movement.acceleration; } -float& Entity::deceleration() { return m_movement.deceleration; } -float& Entity::g() { return m_gravity.value; } -void Entity::set_gait(Gait gait) { m_walk_pose.gait = gait; } -float Entity::yaw() const { return m_angle.yaw; } -float Entity::pitch() const { return m_angle.pitch; } -float& Entity::roll() { return m_angle.roll; } -float& Entity::walk_time() { return m_walk_pose.walk_time; } -Gait Entity::get_gait() const { return m_walk_pose.gait; } - -Velocity& Entity::velocity() { return m_velocity; } -Position& Entity::pos() { return m_pos; } -WalkPose& Entity::walk_pose() { return m_walk_pose; } -Orientation& Entity::angle() { return m_angle; } -Movement& Entity::movement() { return m_movement; } -Gravity& Entity::gravity() { return m_gravity; } -MoveState& Entity::move_state() { return m_move_state; } -Direction& Entity::direction() { return m_direction; } -EntityInfo& Entity::info() { return m_info; } - -const Velocity& Entity::velocity() const { return m_velocity; } -const Position& Entity::pos() const { return m_pos; } -const WalkPose& Entity::walk_pose() const { return m_walk_pose; } -const Orientation& Entity::angle() const { return m_angle; } -const Movement& Entity::movement() const { return m_movement; } -const Gravity& Entity::gravity() const { return m_gravity; } -const MoveState& Entity::move_state() const { return m_move_state; } -const Direction& Entity::direction() const { return m_direction; } -const EntityInfo& Entity::info() const { return m_info; } - -} // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/local_player.cpp b/src/gameplay/local_player.cpp index 9955304..3d70e0b 100644 --- a/src/gameplay/local_player.cpp +++ b/src/gameplay/local_player.cpp @@ -10,8 +10,7 @@ namespace {} // namespace namespace Cubed { -LocalPlayer::LocalPlayer(ClientWorld& world) - : Entity(0, "cubed:player"), m_world(world) {} +LocalPlayer::LocalPlayer(ClientWorld& world) : m_world(world) {} LocalPlayer::~LocalPlayer() {} const glm::vec3& LocalPlayer::get_front() const { return m_front; } @@ -361,7 +360,8 @@ void LocalPlayer::update_move(float delta_time) { glm::vec3{m_max_run_speed, m_max_y_speed, m_max_run_speed}; } - SpeedSystem::update(delta_time, *this); + SpeedSystem::update(delta_time, m_velocity, m_move_state, m_movement, + m_direction, m_gravity); update_direction(); @@ -374,10 +374,12 @@ void LocalPlayer::update_move(float delta_time) { } if (m_game_mode == SPECTATOR) { - player_pos += PhysicalSystem::get_move_distance(delta_time, *this); + player_pos += PhysicalSystem::get_move_distance(delta_time, m_direction, + m_velocity); } else { auto [x, y, z] = - PhysicalSystem::update(delta_time, *this, m_world, player_pos); + PhysicalSystem::update(delta_time, m_world, player_pos, m_velocity, + m_direction, m_move_state, m_hitbox); if (!x || !z) { m_sprinting = false; } @@ -552,6 +554,9 @@ void LocalPlayer::reset_input_status() { } void LocalPlayer::init(std::string_view name) { + + m_hitbox = HitboxManager::hitbox("cubed:player").id; + { std::lock_guard lock(m_player_pos_mutex); m_pos.value = {0.0f, 255.0f, 0.0f}; @@ -590,4 +595,16 @@ void LocalPlayer::init(std::string_view name) { bool LocalPlayer::is_underwater() const { return m_underwater; } void LocalPlayer::set_underwater(bool u) { m_underwater = u; } + +glm::vec3& LocalPlayer::max_speed() { return m_velocity.max; } +float& LocalPlayer::acceleration() { return m_movement.acceleration; } +float& LocalPlayer::deceleration() { return m_movement.deceleration; } +float& LocalPlayer::g() { return m_gravity.value; } +void LocalPlayer::set_gait(Gait gait) { m_walk_pose.gait = gait; } +float LocalPlayer::yaw() const { return m_angle.yaw; } +float LocalPlayer::pitch() const { return m_angle.pitch; } +float& LocalPlayer::roll() { return m_angle.roll; } +float& LocalPlayer::walk_time() { return m_walk_pose.walk_time; } +Gait LocalPlayer::get_gait() const { return m_walk_pose.gait; } + } // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/network_client.cpp b/src/gameplay/network_client.cpp index e8a03e5..8ceebcc 100644 --- a/src/gameplay/network_client.cpp +++ b/src/gameplay/network_client.cpp @@ -107,7 +107,7 @@ asio::awaitable NetworkClient::read_loop() { case std::to_underlying(PacketEnum::PLAYER_INFO_RSP): { auto* rsp = Arena::Create(&arena); if (decode_packet(*rsp, body_data, header)) { - m_world.receive_remote_player(*rsp); + m_world.player_manager().receive_remote_player(*rsp); } } break; case std::to_underlying(PacketEnum::LOGOUT_RSP): { diff --git a/src/gameplay/systems/physical_system.cpp b/src/gameplay/systems/physical_system.cpp index 1115ccb..91eb0eb 100644 --- a/src/gameplay/systems/physical_system.cpp +++ b/src/gameplay/systems/physical_system.cpp @@ -99,21 +99,28 @@ bool update_z(const glm::vec3& pos, const glm::vec3& distance, World& world, } } // namespace -std::tuple PhysicalSystem::update(float dt, Entity& e, +std::tuple PhysicalSystem::update(float dt, ServerEntity& e, World& world) { - glm::vec3 pos = e.pos().value; + glm::vec3 pos = e.transform.position.value; auto ans = update(dt, e, world, pos); - e.pos().value = pos; + e.transform.position.value = pos; return ans; } -std::tuple PhysicalSystem::update(float dt, Entity& e, +std::tuple PhysicalSystem::update(float dt, ServerEntity& e, World& world, glm::vec3& moved_pos) { - auto distance = get_move_distance(dt, e); - auto& m_velocity = e.velocity(); - auto& m_move_state = e.move_state(); - auto box = HitboxManager::hitbox(e.info().hitbox); + + return update(dt, world, moved_pos, e.velocity, e.direction, e.move_state, + e.hitbox); +} + +std::tuple +PhysicalSystem::update(float dt, World& world, glm::vec3& moved_pos, + Velocity& v, Direction& direction, MoveState& move_state, + HitboxID hitbox) { + auto distance = get_move_distance(dt, direction, v); + auto box = HitboxManager::hitbox(hitbox); bool x = false; bool y = false; bool z = false; @@ -121,17 +128,17 @@ std::tuple PhysicalSystem::update(float dt, Entity& e, moved_pos.x += distance.x; x = true; } else { - m_velocity.value.x = 0.0f; + v.value.x = 0.0f; } if (update_y(moved_pos, distance, world, box.box)) { moved_pos.y += distance.y; y = true; } else { - m_velocity.value.y = 0.0f; + v.value.y = 0.0f; if (distance.y < 0) { - m_move_state.can_up = true; - m_move_state.is_fly = false; + move_state.can_up = true; + move_state.is_fly = false; } } @@ -139,16 +146,14 @@ std::tuple PhysicalSystem::update(float dt, Entity& e, moved_pos.z += distance.z; z = true; } else { - m_velocity.value.z = 0.0f; + v.value.z = 0.0f; } return {x, y, z}; } -glm::vec3 PhysicalSystem::get_move_distance(float dt, const Entity& e) { - auto& m_direction = e.direction(); - auto& m_velocity = e.velocity(); - return glm::vec3{m_direction.value.x * m_velocity.value.x * dt, - m_velocity.value.y * dt, - m_direction.value.z * m_velocity.value.z * dt}; +glm::vec3 PhysicalSystem::get_move_distance(float dt, const Direction& d, + const Velocity& v) { + return glm::vec3{d.value.x * v.value.x * dt, v.value.y * dt, + d.value.z * v.value.z * dt}; } } // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/systems/speed_system.cpp b/src/gameplay/systems/speed_system.cpp index 03e09c9..20e6f93 100644 --- a/src/gameplay/systems/speed_system.cpp +++ b/src/gameplay/systems/speed_system.cpp @@ -1,56 +1,58 @@ #include "Cubed/gameplay/systems/speed_system.hpp" namespace Cubed { -void SpeedSystem::update(float dt, Entity& e) { - auto& m_velocity = e.velocity(); - auto& m_move_state = e.move_state(); - auto& m_movement = e.movement(); - auto& direction = e.direction(); - auto& m_gravity = e.gravity(); +void SpeedSystem::update(float dt, ServerEntity& e) { + update(dt, e.velocity, e.move_state, e.movement, e.direction, e.gravity); +} + +void SpeedSystem::update(float dt, Velocity& v, MoveState& move_state, + Movement& movement, Direction& direction, + const Gravity& g) { // calculate speed - if (m_move_state.forward || m_move_state.back || m_move_state.left || - m_move_state.right) { + if (move_state.forward || move_state.back || move_state.left || + move_state.right) { direction.value = glm::vec3(0.0f, 0.0f, 0.0f); - m_velocity.value.x += m_movement.acceleration * dt; - m_velocity.value.z += m_movement.acceleration * dt; - if (m_velocity.value.x > m_velocity.max.x) { - m_velocity.value.x = m_velocity.max.x; + v.value.x += movement.acceleration * dt; + v.value.z += movement.acceleration * dt; + if (v.value.x > v.max.x) { + v.value.x = v.max.x; } - if (m_velocity.value.z > m_velocity.max.z) { - m_velocity.value.z = m_velocity.max.z; + if (v.value.z > v.max.z) { + v.value.z = v.max.z; } } else { - m_velocity.value.x += -m_movement.deceleration * dt; - m_velocity.value.z += -m_movement.deceleration * dt; - if (m_velocity.value.z < 0.0f) { - m_velocity.value.z = 0.0f; + v.value.x += -movement.deceleration * dt; + v.value.z += -movement.deceleration * dt; + if (v.value.z < 0.0f) { + v.value.z = 0.0f; } - if (m_velocity.value.x < 0.0f) { - m_velocity.value.x = 0.0f; + if (v.value.x < 0.0f) { + v.value.x = 0.0f; } - if (m_velocity.value.z < 0.0f && m_velocity.value.x < 0.0f) { + if (v.value.z < 0.0f && v.value.x < 0.0f) { direction.value = glm::vec3(0.0f, 0.0f, 0.0f); } } - if (m_move_state.is_fly) { - if (m_move_state.up) { - m_velocity.value.y = m_velocity.max.y; + if (move_state.is_fly) { + if (move_state.up) { + v.value.y = v.max.y; } - if (m_move_state.down) { - m_velocity.value.y = -m_velocity.max.y; + if (move_state.down) { + v.value.y = -v.max.y; } - if (!m_move_state.down && !m_move_state.up) { - m_velocity.value.y = 0.0f; + if (!move_state.down && !move_state.up) { + v.value.y = 0.0f; } } else { - if (m_move_state.up && m_move_state.can_up) { - m_velocity.value.y = m_movement.jump_power; - m_move_state.can_up = false; + if (move_state.up && move_state.can_up) { + v.value.y = movement.jump_power; + move_state.can_up = false; } - m_velocity.value.y += -m_gravity.value * dt; + v.value.y += -g.value * dt; } } + } // namespace Cubed \ No newline at end of file diff --git a/src/render/player_renderer.cpp b/src/render/player_renderer.cpp index e286788..c61ccde 100644 --- a/src/render/player_renderer.cpp +++ b/src/render/player_renderer.cpp @@ -201,8 +201,10 @@ void PlayerRenderer::render(const Shader& shader, ClientWorld& world, glm::mat4 m_v_mat = camera.get_camera_lookat(); glm::mat4 m_p_mat = m_renderer.world_proj_matrix(); - auto& players = world.render_player_data(); - shader.set_loc("proj_matrix", m_p_mat); + auto players = world.player_manager().render_player_data(); + if (!shadow_render) { + shader.set_loc("proj_matrix", m_p_mat); + } for (auto& player : players) {