mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
refactor(gameplay): separate player logic into manager and ECS components
This commit is contained in:
@@ -1,7 +1,12 @@
|
|||||||
#pragma once
|
#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 {
|
namespace Cubed {
|
||||||
struct PlayerData {
|
|
||||||
|
struct ClientPlayer {
|
||||||
Position pos{};
|
Position pos{};
|
||||||
Position render_pos{};
|
Position render_pos{};
|
||||||
EntityInfo entity{};
|
EntityInfo entity{};
|
||||||
45
include/Cubed/gameplay/client_player_manager.hpp
Normal file
45
include/Cubed/gameplay/client_player_manager.hpp
Normal file
@@ -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<PlayerRenderData> 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<ClientPlayer>::Handle;
|
||||||
|
SparseVector<ClientPlayer> m_players;
|
||||||
|
std::vector<PlayerRenderData> m_render_data;
|
||||||
|
std::unordered_map<std::string, PlayerHandle> m_players_handle;
|
||||||
|
LocalPlayer m_local;
|
||||||
|
|
||||||
|
void update_players_data(float dt);
|
||||||
|
};
|
||||||
|
} // namespace Cubed
|
||||||
@@ -5,15 +5,14 @@
|
|||||||
#include "Cubed/gameplay/chat_message.hpp"
|
#include "Cubed/gameplay/chat_message.hpp"
|
||||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||||
#include "Cubed/gameplay/client_chunk.hpp"
|
#include "Cubed/gameplay/client_chunk.hpp"
|
||||||
|
#include "Cubed/gameplay/client_player_manager.hpp"
|
||||||
#include "Cubed/gameplay/game_time.hpp"
|
#include "Cubed/gameplay/game_time.hpp"
|
||||||
#include "Cubed/gameplay/local_player.hpp"
|
#include "Cubed/gameplay/local_player.hpp"
|
||||||
#include "Cubed/gameplay/network_client.hpp"
|
#include "Cubed/gameplay/network_client.hpp"
|
||||||
#include "Cubed/gameplay/player_data.hpp"
|
|
||||||
#include "Cubed/gameplay/world.hpp"
|
#include "Cubed/gameplay/world.hpp"
|
||||||
#include "Cubed/input/event.hpp"
|
#include "Cubed/input/event.hpp"
|
||||||
#include "Cubed/tools/cubed_random.hpp"
|
#include "Cubed/tools/cubed_random.hpp"
|
||||||
#include "Cubed/tools/priority_thread_pool.hpp"
|
#include "Cubed/tools/priority_thread_pool.hpp"
|
||||||
#include "Cubed/tools/sparse_vector.hpp"
|
|
||||||
|
|
||||||
#include <absl/container/flat_hash_set.h>
|
#include <absl/container/flat_hash_set.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@@ -34,7 +33,6 @@ public:
|
|||||||
void init(std::string_view player_name,
|
void init(std::string_view player_name,
|
||||||
std::shared_ptr<NetworkClient> client);
|
std::shared_ptr<NetworkClient> client);
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
void update_players(float dt);
|
|
||||||
bool handle_event(const Event& e);
|
bool handle_event(const Event& e);
|
||||||
const std::optional<LookBlock>& get_look_block_pos() const;
|
const std::optional<LookBlock>& get_look_block_pos() const;
|
||||||
LocalPlayer& get_player();
|
LocalPlayer& get_player();
|
||||||
@@ -55,7 +53,6 @@ public:
|
|||||||
void receive_block_change(const BlockChangeRsp& rsp);
|
void receive_block_change(const BlockChangeRsp& rsp);
|
||||||
void receive_time(const UpdateTime& rsp);
|
void receive_time(const UpdateTime& rsp);
|
||||||
|
|
||||||
void receive_remote_player(const PlayerInfoRsp& rsp);
|
|
||||||
void receive_player_logout(const LogoutRsp& rsp);
|
void receive_player_logout(const LogoutRsp& rsp);
|
||||||
void receive_player_water_sound(const PlayerWaterSound& rsp);
|
void receive_player_water_sound(const PlayerWaterSound& rsp);
|
||||||
void send_player_water_sound(bool underwater, const glm::vec3& pos);
|
void send_player_water_sound(bool underwater, const glm::vec3& pos);
|
||||||
@@ -74,8 +71,6 @@ public:
|
|||||||
void reset_key_status();
|
void reset_key_status();
|
||||||
std::vector<glm::vec4>& planes();
|
std::vector<glm::vec4>& planes();
|
||||||
const std::vector<const ChunkRenderSnapshot*>& render_snapshots() const;
|
const std::vector<const ChunkRenderSnapshot*>& render_snapshots() const;
|
||||||
const std::vector<PlayerRenderData>& render_player_data() const;
|
|
||||||
std::vector<PlayerRenderData>& render_player_data();
|
|
||||||
|
|
||||||
glm::vec3 sunlight_dir() const;
|
glm::vec3 sunlight_dir() const;
|
||||||
bool sphere_collide_world(glm::vec3 center, float radius) const;
|
bool sphere_collide_world(glm::vec3 center, float radius) const;
|
||||||
@@ -88,6 +83,7 @@ public:
|
|||||||
const AudioEngine& get_audio() const;
|
const AudioEngine& get_audio() const;
|
||||||
Config& get_config();
|
Config& get_config();
|
||||||
WorldScene& world_scene();
|
WorldScene& world_scene();
|
||||||
|
ClientPlayerManager& player_manager();
|
||||||
void set_direct_exit();
|
void set_direct_exit();
|
||||||
|
|
||||||
void receive_chat_message(ChatMsg& msg);
|
void receive_chat_message(ChatMsg& msg);
|
||||||
@@ -131,7 +127,7 @@ private:
|
|||||||
static constexpr int WORLD_EXIT_TIMEOUT = 200;
|
static constexpr int WORLD_EXIT_TIMEOUT = 200;
|
||||||
static constexpr int MAX_UPLOAD_CHUNK_SUM = 16;
|
static constexpr int MAX_UPLOAD_CHUNK_SUM = 16;
|
||||||
|
|
||||||
LocalPlayer m_player;
|
ClientPlayerManager m_player_manager;
|
||||||
ChunkHashMap m_chunks;
|
ChunkHashMap m_chunks;
|
||||||
AudioEngine& m_audio;
|
AudioEngine& m_audio;
|
||||||
Config& m_config;
|
Config& m_config;
|
||||||
@@ -139,11 +135,6 @@ private:
|
|||||||
std::vector<glm::vec4> m_planes;
|
std::vector<glm::vec4> m_planes;
|
||||||
std::jthread m_client_thread;
|
std::jthread m_client_thread;
|
||||||
|
|
||||||
mutable std::shared_mutex m_players_date_mutex;
|
|
||||||
using PlayerHandle = SparseVector<PlayerData>::Handle;
|
|
||||||
SparseVector<PlayerData> m_players_data;
|
|
||||||
std::unordered_map<std::string, PlayerHandle> m_players_handle;
|
|
||||||
|
|
||||||
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
||||||
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
||||||
tbb::concurrent_queue<PendingSound> m_pending_sound;
|
tbb::concurrent_queue<PendingSound> m_pending_sound;
|
||||||
@@ -152,7 +143,6 @@ private:
|
|||||||
|
|
||||||
std::deque<ChunkPos> m_dirty_queue;
|
std::deque<ChunkPos> m_dirty_queue;
|
||||||
std::vector<const ChunkRenderSnapshot*> m_render_snapshots;
|
std::vector<const ChunkRenderSnapshot*> m_render_snapshots;
|
||||||
std::vector<PlayerRenderData> m_render_player_data;
|
|
||||||
|
|
||||||
tbb::concurrent_unordered_map<std::string, TickTimer> m_ticktimers;
|
tbb::concurrent_unordered_map<std::string, TickTimer> m_ticktimers;
|
||||||
std::unordered_map<std::string, Timer> m_timers;
|
std::unordered_map<std::string, Timer> m_timers;
|
||||||
@@ -176,8 +166,6 @@ private:
|
|||||||
|
|
||||||
void client_run(std::stop_token token);
|
void client_run(std::stop_token token);
|
||||||
|
|
||||||
void report_player_info();
|
|
||||||
|
|
||||||
void set_block(const glm::ivec3& pos, unsigned id);
|
void set_block(const glm::ivec3& pos, unsigned id);
|
||||||
|
|
||||||
void update_chunk(const ChunkPosSet& old, const ChunkPosSet& now);
|
void update_chunk(const ChunkPosSet& old, const ChunkPosSet& now);
|
||||||
|
|||||||
6
include/Cubed/gameplay/creatures/pig.hpp
Normal file
6
include/Cubed/gameplay/creatures/pig.hpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Cubed {
|
||||||
|
struct PigTag {};
|
||||||
|
|
||||||
|
} // namespace Cubed
|
||||||
13
include/Cubed/gameplay/ecs/animation.hpp
Normal file
13
include/Cubed/gameplay/ecs/animation.hpp
Normal file
@@ -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
|
||||||
20
include/Cubed/gameplay/ecs/client_entity.hpp
Normal file
20
include/Cubed/gameplay/ecs/client_entity.hpp
Normal file
@@ -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
|
||||||
11
include/Cubed/gameplay/ecs/entity.hpp
Normal file
11
include/Cubed/gameplay/ecs/entity.hpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
namespace Cubed {
|
||||||
|
using EntityID = uint64_t;
|
||||||
|
|
||||||
|
struct Entity {
|
||||||
|
EntityID id;
|
||||||
|
explicit Entity(EntityID id) : id(id) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Cubed
|
||||||
10
include/Cubed/gameplay/ecs/health.hpp
Normal file
10
include/Cubed/gameplay/ecs/health.hpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Cubed {
|
||||||
|
|
||||||
|
struct Health {
|
||||||
|
float hp = 20;
|
||||||
|
float max_hp = 20;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Cubed
|
||||||
10
include/Cubed/gameplay/ecs/identity.hpp
Normal file
10
include/Cubed/gameplay/ecs/identity.hpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Cubed {
|
||||||
|
struct EntityInfo {
|
||||||
|
std::string name;
|
||||||
|
std::string uuid;
|
||||||
|
};
|
||||||
|
} // namespace Cubed
|
||||||
26
include/Cubed/gameplay/ecs/movement.hpp
Normal file
26
include/Cubed/gameplay/ecs/movement.hpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Cubed/constants.hpp"
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
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
|
||||||
32
include/Cubed/gameplay/ecs/server_entity.hpp
Normal file
32
include/Cubed/gameplay/ecs/server_entity.hpp
Normal file
@@ -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
|
||||||
18
include/Cubed/gameplay/ecs/state.hpp
Normal file
18
include/Cubed/gameplay/ecs/state.hpp
Normal file
@@ -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
|
||||||
24
include/Cubed/gameplay/ecs/transform.hpp
Normal file
24
include/Cubed/gameplay/ecs/transform.hpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
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
|
||||||
@@ -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 <glm/glm.hpp>
|
|
||||||
#include <string>
|
|
||||||
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
|
|
||||||
@@ -2,9 +2,14 @@
|
|||||||
#include "Cubed/constants.hpp"
|
#include "Cubed/constants.hpp"
|
||||||
#include "Cubed/gameplay/block.hpp"
|
#include "Cubed/gameplay/block.hpp"
|
||||||
#include "Cubed/gameplay/chunk_pos.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_mode.hpp"
|
||||||
#include "Cubed/gameplay/game_time.hpp"
|
#include "Cubed/gameplay/game_time.hpp"
|
||||||
|
#include "Cubed/gameplay/hitbox.hpp"
|
||||||
#include "Cubed/gameplay/item_stack.hpp"
|
#include "Cubed/gameplay/item_stack.hpp"
|
||||||
#include "Cubed/gameplay/player.hpp"
|
#include "Cubed/gameplay/player.hpp"
|
||||||
#include "Cubed/input/event.hpp"
|
#include "Cubed/input/event.hpp"
|
||||||
@@ -17,7 +22,7 @@
|
|||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
class ClientWorld;
|
class ClientWorld;
|
||||||
class LocalPlayer : public Entity {
|
class LocalPlayer {
|
||||||
public:
|
public:
|
||||||
static constexpr size_t HOTBAR_SUM = 10;
|
static constexpr size_t HOTBAR_SUM = 10;
|
||||||
static constexpr float WALK_SOUND_INTERVAL = 0.45f;
|
static constexpr float WALK_SOUND_INTERVAL = 0.45f;
|
||||||
@@ -35,6 +40,7 @@ public:
|
|||||||
bool update_scroll(float yoffset);
|
bool update_scroll(float yoffset);
|
||||||
|
|
||||||
void update_chunk_set(const ChunkPosSet& set);
|
void update_chunk_set(const ChunkPosSet& set);
|
||||||
|
|
||||||
const ChunkPosSet& get_chunk_pos_set() const;
|
const ChunkPosSet& get_chunk_pos_set() const;
|
||||||
ChunkPosSet get_chunk_pos_set();
|
ChunkPosSet get_chunk_pos_set();
|
||||||
|
|
||||||
@@ -77,6 +83,17 @@ public:
|
|||||||
void set_hotbar(int pos, const ItemStack& item);
|
void set_hotbar(int pos, const ItemStack& item);
|
||||||
std::span<const ItemStack, HOTBAR_SUM> get_hotbar() const;
|
std::span<const ItemStack, HOTBAR_SUM> 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:
|
private:
|
||||||
using enum GameMode;
|
using enum GameMode;
|
||||||
float m_max_walk_speed = DEFAULT_MAX_WALK_SPEED;
|
float m_max_walk_speed = DEFAULT_MAX_WALK_SPEED;
|
||||||
@@ -84,8 +101,18 @@ private:
|
|||||||
float m_max_y_speed = 7.5f;
|
float m_max_y_speed = 7.5f;
|
||||||
static constexpr float MAX_SPACE_ON_TIME = 0.3f;
|
static constexpr float MAX_SPACE_ON_TIME = 0.3f;
|
||||||
static constexpr float PLACE_BLOCK_INTERVAL = 0.2f;
|
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;
|
float m_place_time = PLACE_BLOCK_INTERVAL;
|
||||||
|
|
||||||
std::array<ItemStack, HOTBAR_SUM> m_hotbar;
|
std::array<ItemStack, HOTBAR_SUM> m_hotbar;
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Cubed//gameplay/ecs/server_entity.hpp"
|
||||||
#include "Cubed/gameplay/entity.hpp"
|
|
||||||
#include "Cubed/gameplay/world.hpp"
|
#include "Cubed/gameplay/world.hpp"
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
class PhysicalSystem {
|
class PhysicalSystem {
|
||||||
public:
|
public:
|
||||||
static glm::vec3 get_move_distance(float dt, const Entity& e);
|
static glm::vec3 get_move_distance(float dt, const Direction& d,
|
||||||
static std::tuple<bool, bool, bool> update(float dt, Entity& e,
|
const Velocity& v);
|
||||||
|
static std::tuple<bool, bool, bool> update(float dt, ServerEntity& e,
|
||||||
World& world);
|
World& world);
|
||||||
static std::tuple<bool, bool, bool>
|
static std::tuple<bool, bool, bool>
|
||||||
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<bool, bool, bool>
|
||||||
|
update(float dt, World& world, glm::vec3& moved_pos, Velocity& v,
|
||||||
|
Direction& direction, MoveState& move_state, HitboxID hitbox);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Cubed/gameplay/entity.hpp"
|
#include "Cubed/gameplay/ecs/server_entity.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/state.hpp"
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
class SpeedSystem {
|
class SpeedSystem {
|
||||||
public:
|
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:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ target_sources(${PROJECT_NAME}
|
|||||||
render/model_renderer.cpp
|
render/model_renderer.cpp
|
||||||
gameplay/chunk.cpp
|
gameplay/chunk.cpp
|
||||||
gameplay/hitbox_manager.cpp
|
gameplay/hitbox_manager.cpp
|
||||||
gameplay/entity.cpp
|
|
||||||
gameplay/systems/physical_system.cpp
|
gameplay/systems/physical_system.cpp
|
||||||
gameplay/systems/speed_system.cpp
|
gameplay/systems/speed_system.cpp
|
||||||
|
gameplay/client_player_manager.cpp
|
||||||
)
|
)
|
||||||
219
src/gameplay/client_player_manager.cpp
Normal file
219
src/gameplay/client_player_manager.cpp
Normal file
@@ -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<C2S_PlayerInfo>(&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<PlayerRenderData> ClientPlayerManager::render_player_data() {
|
||||||
|
return m_render_data;
|
||||||
|
}
|
||||||
|
} // namespace Cubed
|
||||||
@@ -2,12 +2,9 @@
|
|||||||
|
|
||||||
#include "Cubed/config.hpp"
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/gameplay/chunk_generator.hpp"
|
#include "Cubed/gameplay/chunk_generator.hpp"
|
||||||
#include "Cubed/gameplay/entity.hpp"
|
|
||||||
#include "Cubed/gameplay/game_time.hpp"
|
#include "Cubed/gameplay/game_time.hpp"
|
||||||
#include "Cubed/gameplay/hitbox_manager.hpp"
|
|
||||||
#include "Cubed/gameplay/packet.hpp"
|
#include "Cubed/gameplay/packet.hpp"
|
||||||
#include "Cubed/scene/world_scene.hpp"
|
#include "Cubed/scene/world_scene.hpp"
|
||||||
#include "Cubed/tools/math_tools.hpp"
|
|
||||||
#include "Cubed/tools/time_tools.hpp"
|
#include "Cubed/tools/time_tools.hpp"
|
||||||
|
|
||||||
#include <absl/container/inlined_vector.h>
|
#include <absl/container/inlined_vector.h>
|
||||||
@@ -26,7 +23,8 @@ struct ChunkRenderData {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ClientWorld::ClientWorld(AudioEngine& auido, Config& config, WorldScene& scene)
|
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() {
|
ClientWorld::~ClientWorld() {
|
||||||
m_client->close();
|
m_client->close();
|
||||||
@@ -58,11 +56,13 @@ ClientWorld::~ClientWorld() {
|
|||||||
|
|
||||||
const std::optional<LookBlock>& ClientWorld::get_look_block_pos() const {
|
const std::optional<LookBlock>& 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; }
|
LocalPlayer& ClientWorld::get_player() { return m_player_manager.get_local(); }
|
||||||
const LocalPlayer& ClientWorld::get_player() const { return m_player; }
|
const LocalPlayer& ClientWorld::get_player() const {
|
||||||
|
return m_player_manager.get_local();
|
||||||
|
}
|
||||||
int ClientWorld::get_block(const glm::ivec3& block_pos) const {
|
int ClientWorld::get_block(const glm::ivec3& block_pos) const {
|
||||||
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||||
chunk_cacc cacc;
|
chunk_cacc cacc;
|
||||||
@@ -129,7 +129,7 @@ void ClientWorld::rebuild_world() {
|
|||||||
m_pending_upload_queue.clear();
|
m_pending_upload_queue.clear();
|
||||||
|
|
||||||
start_thread_pool();
|
start_thread_pool();
|
||||||
start_client_thread(m_player.get_uuid());
|
start_client_thread(m_player_manager.get_local().get_uuid());
|
||||||
request_chunk();
|
request_chunk();
|
||||||
m_is_rebuilding = false;
|
m_is_rebuilding = false;
|
||||||
}
|
}
|
||||||
@@ -296,21 +296,14 @@ void ClientWorld::report_block_change(const glm::ivec3& pos,
|
|||||||
unsigned id) const {
|
unsigned id) const {
|
||||||
if (id != 0) {
|
if (id != 0) {
|
||||||
Hitbox block_box = get_block_aabb(pos);
|
Hitbox block_box = get_block_aabb(pos);
|
||||||
std::shared_lock lock(m_players_date_mutex);
|
if (m_player_manager.has_player(block_box)) {
|
||||||
|
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Arena arena;
|
Arena arena;
|
||||||
auto* req = Arena::Create<BlockChangeReq>(&arena);
|
auto* req = Arena::Create<BlockChangeReq>(&arena);
|
||||||
req->set_uuid(m_player.get_uuid());
|
req->set_uuid(m_player_manager.get_local().get_uuid());
|
||||||
req->set_block(id);
|
req->set_block(id);
|
||||||
auto* p = req->mutable_pos();
|
auto* p = req->mutable_pos();
|
||||||
p->set_x(pos.x);
|
p->set_x(pos.x);
|
||||||
@@ -329,64 +322,20 @@ void ClientWorld::receive_time(const UpdateTime& rsp) {
|
|||||||
m_day_tick = rsp.day_tick();
|
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) {
|
void ClientWorld::receive_player_logout(const LogoutRsp& rsp) {
|
||||||
if (rsp.server_stop()) {
|
if (rsp.server_stop()) {
|
||||||
m_receive_exit = true;
|
m_receive_exit = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (rsp.uuid() == m_player.get_uuid()) {
|
if (rsp.uuid() == m_player_manager.get_local().get_uuid()) {
|
||||||
m_receive_exit = true;
|
m_receive_exit = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
{
|
m_player_manager.receive_player_logout(rsp);
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::receive_player_water_sound(const PlayerWaterSound& 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;
|
return;
|
||||||
}
|
}
|
||||||
glm::vec3 pos = {rsp.pos().x(), rsp.pos().y(), rsp.pos().z()};
|
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_x(pos.x);
|
||||||
p->set_y(pos.y);
|
p->set_y(pos.y);
|
||||||
p->set_z(pos.z);
|
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));
|
m_client->send(make_packet(*r));
|
||||||
Logger::info("Client: Send Player Water Sound");
|
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,
|
void ClientWorld::init(std::string_view player_name,
|
||||||
std::shared_ptr<NetworkClient> client) {
|
std::shared_ptr<NetworkClient> client) {
|
||||||
m_player.init(player_name);
|
m_player_manager.init(player_name);
|
||||||
m_client = client;
|
m_client = client;
|
||||||
|
|
||||||
reload_config(false);
|
reload_config(false);
|
||||||
@@ -422,9 +371,11 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
m_random.init(ChunkGenerator::seed());
|
m_random.init(ChunkGenerator::seed());
|
||||||
|
|
||||||
// timer
|
// 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]() {
|
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) {
|
if (player_pos.y < SEA_LEVEL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -440,7 +391,7 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
});
|
});
|
||||||
|
|
||||||
m_timers.try_emplace("Ocean Wave", 3.0f, [this]() {
|
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) {
|
if (player_pos.y < SEA_LEVEL - 10 || player_pos.y > SEA_LEVEL + 10) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -460,11 +411,12 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
});
|
});
|
||||||
|
|
||||||
m_timers.try_emplace("under water bubble", 1.5f, [this]() {
|
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);
|
auto ans = m_random.random_int(1, 2);
|
||||||
std::string sound =
|
std::string sound =
|
||||||
"ambient/water/bubble00" + std::to_string(ans) + ".ogg";
|
"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;
|
LoginReq req;
|
||||||
req.set_name(m_player.get_name());
|
req.set_name(m_player_manager.get_local().get_name());
|
||||||
while (!client->is_connected()) {
|
while (!client->is_connected()) {
|
||||||
if (client->is_connect_error()) {
|
if (client->is_connect_error()) {
|
||||||
throw std::runtime_error(client->get_error_string());
|
throw std::runtime_error(client->get_error_string());
|
||||||
@@ -502,7 +454,7 @@ void ClientWorld::start_client_thread(std::string_view uuid) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// response
|
// 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_client_thread = std::jthread([this](std::stop_token token) {
|
||||||
m_game_running = true;
|
m_game_running = true;
|
||||||
@@ -557,7 +509,7 @@ void ClientWorld::reload_config(bool chunk_build) {
|
|||||||
request_chunk();
|
request_chunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_player.reload_config();
|
m_player_manager.reload_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::client_run(std::stop_token stoken) {
|
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<C2S_PlayerInfo>(&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) {
|
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
|
// 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;
|
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 x = std::floor(player_pos.x);
|
||||||
int z = std::floor(player_pos.z);
|
int z = std::floor(player_pos.z);
|
||||||
@@ -640,8 +573,8 @@ void ClientWorld::request_chunk() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChunkPosSet old = m_player.get_chunk_pos_set();
|
ChunkPosSet old = m_player_manager.get_local().get_chunk_pos_set();
|
||||||
m_player.update_chunk_set(required_chunks);
|
m_player_manager.get_local().update_chunk_set(required_chunks);
|
||||||
|
|
||||||
ChunkPosVector need_send_pos;
|
ChunkPosVector need_send_pos;
|
||||||
|
|
||||||
@@ -665,7 +598,7 @@ void ClientWorld::request_chunk() {
|
|||||||
break;
|
break;
|
||||||
case CENTER: {
|
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);
|
ChunkPos player_chunk_pos = get_chunk_pos(player_pos.x, player_pos.z);
|
||||||
auto dist2 = [player_chunk_pos](ChunkPos chunk_pos) {
|
auto dist2 = [player_chunk_pos](ChunkPos chunk_pos) {
|
||||||
float dx = player_chunk_pos.x - chunk_pos.x;
|
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;
|
Arena arena;
|
||||||
++m_chunk_task_id;
|
++m_chunk_task_id;
|
||||||
auto* req = Arena::Create<ChunkDataReq>(&arena);
|
auto* req = Arena::Create<ChunkDataReq>(&arena);
|
||||||
@@ -694,7 +627,9 @@ void ClientWorld::request_chunk() {
|
|||||||
Logger::info("Send Chunk Request Success");
|
Logger::info("Send Chunk Request Success");
|
||||||
m_requesting_chunk = false;
|
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<uint8_t> raw_data,
|
void ClientWorld::receive_chunk(std::vector<uint8_t> raw_data,
|
||||||
PacketHeader header) {
|
PacketHeader header) {
|
||||||
|
|
||||||
@@ -741,6 +676,7 @@ AudioEngine& ClientWorld::get_audio() { return m_audio; }
|
|||||||
const AudioEngine& ClientWorld::get_audio() const { return m_audio; }
|
const AudioEngine& ClientWorld::get_audio() const { return m_audio; }
|
||||||
Config& ClientWorld::get_config() { return m_config; }
|
Config& ClientWorld::get_config() { return m_config; }
|
||||||
WorldScene& ClientWorld::world_scene() { return m_world_scene; }
|
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::set_direct_exit() { m_exit_direct = true; }
|
||||||
void ClientWorld::request_exit() {
|
void ClientWorld::request_exit() {
|
||||||
if (m_receive_exit) {
|
if (m_receive_exit) {
|
||||||
@@ -748,7 +684,7 @@ void ClientWorld::request_exit() {
|
|||||||
}
|
}
|
||||||
Arena arena;
|
Arena arena;
|
||||||
auto* req = Arena::Create<LogoutReq>(&arena);
|
auto* req = Arena::Create<LogoutReq>(&arena);
|
||||||
req->set_uuid(m_player.get_uuid());
|
req->set_uuid(m_player_manager.get_local().get_uuid());
|
||||||
m_client->send(make_packet(*req));
|
m_client->send(make_packet(*req));
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
while (!m_receive_exit) {
|
while (!m_receive_exit) {
|
||||||
@@ -789,8 +725,7 @@ void ClientWorld::send_chat_message(ChatMessage& message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::update(float delta_time) {
|
void ClientWorld::update(float delta_time) {
|
||||||
|
m_player_manager.update(delta_time);
|
||||||
m_player.update(delta_time);
|
|
||||||
{
|
{
|
||||||
std::lock_guard lk(m_delete_vbo_mutex);
|
std::lock_guard lk(m_delete_vbo_mutex);
|
||||||
m_pending_delete_vbo.clear();
|
m_pending_delete_vbo.clear();
|
||||||
@@ -841,7 +776,7 @@ void ClientWorld::update(float delta_time) {
|
|||||||
chunk->upload_to_gpu();
|
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) {
|
for (auto& pos : chunk_pos_set) {
|
||||||
std::shared_ptr<ClientChunk> chunk;
|
std::shared_ptr<ClientChunk> chunk;
|
||||||
@@ -858,9 +793,6 @@ void ClientWorld::update(float delta_time) {
|
|||||||
m_render_snapshots.push_back(chunk->get_render_snapshot());
|
m_render_snapshots.push_back(chunk->get_render_snapshot());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_render_player_data.clear();
|
|
||||||
update_players(delta_time);
|
|
||||||
|
|
||||||
// sound
|
// sound
|
||||||
PendingSound pending_sound;
|
PendingSound pending_sound;
|
||||||
while (m_pending_sound.try_pop(pending_sound)) {
|
while (m_pending_sound.try_pop(pending_sound)) {
|
||||||
@@ -881,126 +813,24 @@ 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) {
|
bool ClientWorld::handle_event(const Event& e) {
|
||||||
return std::visit(
|
return std::visit(
|
||||||
Overloaded{[this](const MouseButtonEvent& e) {
|
Overloaded{
|
||||||
if (m_player.handle_mouse_button_event(e)) {
|
[this](const MouseButtonEvent& e) {
|
||||||
|
if (m_player_manager.get_local().handle_mouse_button_event(e)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
[](const MouseMoveEvent&) { return false; },
|
[](const MouseMoveEvent&) { return false; },
|
||||||
[this](const MouseWheelEvent& e) {
|
[this](const MouseWheelEvent& e) {
|
||||||
if (m_player.handle_mouse_wheel_event(e)) {
|
if (m_player_manager.get_local().handle_mouse_wheel_event(e)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
[this](const KeyEvent& e) {
|
[this](const KeyEvent& e) {
|
||||||
if (m_player.handle_key_event(e)) {
|
if (m_player_manager.get_local().handle_key_event(e)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1075,11 +905,6 @@ const std::vector<const ChunkRenderSnapshot*>&
|
|||||||
ClientWorld::render_snapshots() const {
|
ClientWorld::render_snapshots() const {
|
||||||
return m_render_snapshots;
|
return m_render_snapshots;
|
||||||
};
|
};
|
||||||
const std::vector<PlayerRenderData>& ClientWorld::render_player_data() const {
|
|
||||||
return m_render_player_data;
|
|
||||||
}
|
|
||||||
std::vector<PlayerRenderData>& ClientWorld::render_player_data() {
|
|
||||||
return m_render_player_data;
|
|
||||||
}
|
|
||||||
std::vector<glm::vec4>& ClientWorld::planes() { return m_planes; }
|
std::vector<glm::vec4>& ClientWorld::planes() { return m_planes; }
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -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
|
|
||||||
@@ -10,8 +10,7 @@
|
|||||||
namespace {} // namespace
|
namespace {} // namespace
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
LocalPlayer::LocalPlayer(ClientWorld& world)
|
LocalPlayer::LocalPlayer(ClientWorld& world) : m_world(world) {}
|
||||||
: Entity(0, "cubed:player"), m_world(world) {}
|
|
||||||
LocalPlayer::~LocalPlayer() {}
|
LocalPlayer::~LocalPlayer() {}
|
||||||
|
|
||||||
const glm::vec3& LocalPlayer::get_front() const { return m_front; }
|
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};
|
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();
|
update_direction();
|
||||||
|
|
||||||
@@ -374,10 +374,12 @@ void LocalPlayer::update_move(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_game_mode == SPECTATOR) {
|
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 {
|
} else {
|
||||||
auto [x, y, z] =
|
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) {
|
if (!x || !z) {
|
||||||
m_sprinting = false;
|
m_sprinting = false;
|
||||||
}
|
}
|
||||||
@@ -552,6 +554,9 @@ void LocalPlayer::reset_input_status() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LocalPlayer::init(std::string_view name) {
|
void LocalPlayer::init(std::string_view name) {
|
||||||
|
|
||||||
|
m_hitbox = HitboxManager::hitbox("cubed:player").id;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_player_pos_mutex);
|
std::lock_guard lock(m_player_pos_mutex);
|
||||||
m_pos.value = {0.0f, 255.0f, 0.0f};
|
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; }
|
bool LocalPlayer::is_underwater() const { return m_underwater; }
|
||||||
void LocalPlayer::set_underwater(bool u) { m_underwater = u; }
|
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
|
} // namespace Cubed
|
||||||
@@ -107,7 +107,7 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
|||||||
case std::to_underlying(PacketEnum::PLAYER_INFO_RSP): {
|
case std::to_underlying(PacketEnum::PLAYER_INFO_RSP): {
|
||||||
auto* rsp = Arena::Create<PlayerInfoRsp>(&arena);
|
auto* rsp = Arena::Create<PlayerInfoRsp>(&arena);
|
||||||
if (decode_packet(*rsp, body_data, header)) {
|
if (decode_packet(*rsp, body_data, header)) {
|
||||||
m_world.receive_remote_player(*rsp);
|
m_world.player_manager().receive_remote_player(*rsp);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case std::to_underlying(PacketEnum::LOGOUT_RSP): {
|
case std::to_underlying(PacketEnum::LOGOUT_RSP): {
|
||||||
|
|||||||
@@ -99,21 +99,28 @@ bool update_z(const glm::vec3& pos, const glm::vec3& distance, World& world,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
std::tuple<bool, bool, bool> PhysicalSystem::update(float dt, Entity& e,
|
std::tuple<bool, bool, bool> PhysicalSystem::update(float dt, ServerEntity& e,
|
||||||
World& world) {
|
World& world) {
|
||||||
glm::vec3 pos = e.pos().value;
|
glm::vec3 pos = e.transform.position.value;
|
||||||
auto ans = update(dt, e, world, pos);
|
auto ans = update(dt, e, world, pos);
|
||||||
e.pos().value = pos;
|
e.transform.position.value = pos;
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<bool, bool, bool> PhysicalSystem::update(float dt, Entity& e,
|
std::tuple<bool, bool, bool> PhysicalSystem::update(float dt, ServerEntity& e,
|
||||||
World& world,
|
World& world,
|
||||||
glm::vec3& moved_pos) {
|
glm::vec3& moved_pos) {
|
||||||
auto distance = get_move_distance(dt, e);
|
|
||||||
auto& m_velocity = e.velocity();
|
return update(dt, world, moved_pos, e.velocity, e.direction, e.move_state,
|
||||||
auto& m_move_state = e.move_state();
|
e.hitbox);
|
||||||
auto box = HitboxManager::hitbox(e.info().hitbox);
|
}
|
||||||
|
|
||||||
|
std::tuple<bool, bool, bool>
|
||||||
|
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 x = false;
|
||||||
bool y = false;
|
bool y = false;
|
||||||
bool z = false;
|
bool z = false;
|
||||||
@@ -121,17 +128,17 @@ std::tuple<bool, bool, bool> PhysicalSystem::update(float dt, Entity& e,
|
|||||||
moved_pos.x += distance.x;
|
moved_pos.x += distance.x;
|
||||||
x = true;
|
x = true;
|
||||||
} else {
|
} else {
|
||||||
m_velocity.value.x = 0.0f;
|
v.value.x = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_y(moved_pos, distance, world, box.box)) {
|
if (update_y(moved_pos, distance, world, box.box)) {
|
||||||
moved_pos.y += distance.y;
|
moved_pos.y += distance.y;
|
||||||
y = true;
|
y = true;
|
||||||
} else {
|
} else {
|
||||||
m_velocity.value.y = 0.0f;
|
v.value.y = 0.0f;
|
||||||
if (distance.y < 0) {
|
if (distance.y < 0) {
|
||||||
m_move_state.can_up = true;
|
move_state.can_up = true;
|
||||||
m_move_state.is_fly = false;
|
move_state.is_fly = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,16 +146,14 @@ std::tuple<bool, bool, bool> PhysicalSystem::update(float dt, Entity& e,
|
|||||||
moved_pos.z += distance.z;
|
moved_pos.z += distance.z;
|
||||||
z = true;
|
z = true;
|
||||||
} else {
|
} else {
|
||||||
m_velocity.value.z = 0.0f;
|
v.value.z = 0.0f;
|
||||||
}
|
}
|
||||||
return {x, y, z};
|
return {x, y, z};
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 PhysicalSystem::get_move_distance(float dt, const Entity& e) {
|
glm::vec3 PhysicalSystem::get_move_distance(float dt, const Direction& d,
|
||||||
auto& m_direction = e.direction();
|
const Velocity& v) {
|
||||||
auto& m_velocity = e.velocity();
|
return glm::vec3{d.value.x * v.value.x * dt, v.value.y * dt,
|
||||||
return glm::vec3{m_direction.value.x * m_velocity.value.x * dt,
|
d.value.z * v.value.z * dt};
|
||||||
m_velocity.value.y * dt,
|
|
||||||
m_direction.value.z * m_velocity.value.z * dt};
|
|
||||||
}
|
}
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -1,56 +1,58 @@
|
|||||||
#include "Cubed/gameplay/systems/speed_system.hpp"
|
#include "Cubed/gameplay/systems/speed_system.hpp"
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
void SpeedSystem::update(float dt, Entity& e) {
|
void SpeedSystem::update(float dt, ServerEntity& e) {
|
||||||
auto& m_velocity = e.velocity();
|
update(dt, e.velocity, e.move_state, e.movement, e.direction, e.gravity);
|
||||||
auto& m_move_state = e.move_state();
|
}
|
||||||
auto& m_movement = e.movement();
|
|
||||||
auto& direction = e.direction();
|
void SpeedSystem::update(float dt, Velocity& v, MoveState& move_state,
|
||||||
auto& m_gravity = e.gravity();
|
Movement& movement, Direction& direction,
|
||||||
|
const Gravity& g) {
|
||||||
// calculate speed
|
// calculate speed
|
||||||
if (m_move_state.forward || m_move_state.back || m_move_state.left ||
|
if (move_state.forward || move_state.back || move_state.left ||
|
||||||
m_move_state.right) {
|
move_state.right) {
|
||||||
direction.value = glm::vec3(0.0f, 0.0f, 0.0f);
|
direction.value = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
m_velocity.value.x += m_movement.acceleration * dt;
|
v.value.x += movement.acceleration * dt;
|
||||||
m_velocity.value.z += m_movement.acceleration * dt;
|
v.value.z += movement.acceleration * dt;
|
||||||
if (m_velocity.value.x > m_velocity.max.x) {
|
if (v.value.x > v.max.x) {
|
||||||
m_velocity.value.x = m_velocity.max.x;
|
v.value.x = v.max.x;
|
||||||
}
|
}
|
||||||
if (m_velocity.value.z > m_velocity.max.z) {
|
if (v.value.z > v.max.z) {
|
||||||
m_velocity.value.z = m_velocity.max.z;
|
v.value.z = v.max.z;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_velocity.value.x += -m_movement.deceleration * dt;
|
v.value.x += -movement.deceleration * dt;
|
||||||
m_velocity.value.z += -m_movement.deceleration * dt;
|
v.value.z += -movement.deceleration * dt;
|
||||||
if (m_velocity.value.z < 0.0f) {
|
if (v.value.z < 0.0f) {
|
||||||
m_velocity.value.z = 0.0f;
|
v.value.z = 0.0f;
|
||||||
}
|
}
|
||||||
if (m_velocity.value.x < 0.0f) {
|
if (v.value.x < 0.0f) {
|
||||||
m_velocity.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);
|
direction.value = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_move_state.is_fly) {
|
if (move_state.is_fly) {
|
||||||
if (m_move_state.up) {
|
if (move_state.up) {
|
||||||
m_velocity.value.y = m_velocity.max.y;
|
v.value.y = v.max.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_move_state.down) {
|
if (move_state.down) {
|
||||||
m_velocity.value.y = -m_velocity.max.y;
|
v.value.y = -v.max.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_move_state.down && !m_move_state.up) {
|
if (!move_state.down && !move_state.up) {
|
||||||
m_velocity.value.y = 0.0f;
|
v.value.y = 0.0f;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_move_state.up && m_move_state.can_up) {
|
if (move_state.up && move_state.can_up) {
|
||||||
m_velocity.value.y = m_movement.jump_power;
|
v.value.y = movement.jump_power;
|
||||||
m_move_state.can_up = false;
|
move_state.can_up = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_velocity.value.y += -m_gravity.value * dt;
|
v.value.y += -g.value * dt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -201,8 +201,10 @@ void PlayerRenderer::render(const Shader& shader, ClientWorld& world,
|
|||||||
glm::mat4 m_v_mat = camera.get_camera_lookat();
|
glm::mat4 m_v_mat = camera.get_camera_lookat();
|
||||||
glm::mat4 m_p_mat = m_renderer.world_proj_matrix();
|
glm::mat4 m_p_mat = m_renderer.world_proj_matrix();
|
||||||
|
|
||||||
auto& players = world.render_player_data();
|
auto players = world.player_manager().render_player_data();
|
||||||
|
if (!shadow_render) {
|
||||||
shader.set_loc("proj_matrix", m_p_mat);
|
shader.set_loc("proj_matrix", m_p_mat);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& player : players) {
|
for (auto& player : players) {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user