mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
Compare commits
2 Commits
5e96c1573b
...
d15037e7a3
| Author | SHA1 | Date | |
|---|---|---|---|
| d15037e7a3 | |||
| 0ff5820e6e |
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
class ClientPlayer;
|
||||
class LocalPlayer;
|
||||
|
||||
class Camera {
|
||||
private:
|
||||
@@ -18,7 +18,7 @@ private:
|
||||
THIRD_PERSON_FRONT,
|
||||
};
|
||||
|
||||
ClientPlayer* m_player;
|
||||
LocalPlayer* m_player;
|
||||
float m_last_mouse_x, m_last_mouse_y;
|
||||
glm::vec3 m_camera_pos;
|
||||
bool m_under_water = false;
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
|
||||
void update_move_camera();
|
||||
|
||||
void camera_init(ClientPlayer* player);
|
||||
void camera_init(LocalPlayer* player);
|
||||
void hot_reload();
|
||||
void update_cursor_position_camera(float offset_x, float offset_y);
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
void change_perspective();
|
||||
bool is_first_person() const;
|
||||
bool handle_event(const Event& e);
|
||||
ClientPlayer* player();
|
||||
LocalPlayer* player();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
namespace Cubed {
|
||||
|
||||
class WorldScene;
|
||||
class ClientPlayer;
|
||||
class LocalPlayer;
|
||||
class App;
|
||||
class DevPanel {
|
||||
struct ConfigView {
|
||||
@@ -42,7 +42,7 @@ private:
|
||||
WorldScene& m_world_scene;
|
||||
Config& m_config;
|
||||
ConfigView m_config_view;
|
||||
ClientPlayer* m_player;
|
||||
LocalPlayer* m_player;
|
||||
PlayerProfile m_player_profile;
|
||||
bool m_need_save_config = false;
|
||||
bool m_gen_thread_running = true;
|
||||
|
||||
@@ -1,133 +1,25 @@
|
||||
#pragma once
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/entity.hpp"
|
||||
#include "Cubed/gameplay/game_mode.hpp"
|
||||
#include "Cubed/gameplay/game_time.hpp"
|
||||
#include "Cubed/gameplay/item_stack.hpp"
|
||||
#include "Cubed/gameplay/player.hpp"
|
||||
#include "Cubed/input/event.hpp"
|
||||
#include "Cubed/input/input.hpp"
|
||||
|
||||
#include <absl/container/flat_hash_set.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#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 {
|
||||
|
||||
class ClientWorld;
|
||||
class ClientPlayer : public Entity {
|
||||
public:
|
||||
static constexpr size_t HOTBAR_SUM = 10;
|
||||
static constexpr float WALK_SOUND_INTERVAL = 0.45f;
|
||||
static constexpr float RUN_SOUND_INTERVAL = 0.3f;
|
||||
using ChunkPosSet = absl::flat_hash_set<ChunkPos, ChunkPos::Hash>;
|
||||
ClientPlayer(ClientWorld& world);
|
||||
~ClientPlayer();
|
||||
|
||||
bool handle_mouse_button_event(const MouseButtonEvent& e);
|
||||
bool handle_key_event(const KeyEvent& e);
|
||||
bool handle_mouse_wheel_event(const MouseWheelEvent& e);
|
||||
|
||||
void update_front_vec(float offset_x, float offset_y);
|
||||
bool update_player_move_state(Key key, KeyAction action);
|
||||
bool update_scroll(float yoffset);
|
||||
|
||||
void update_chunk_set(const ChunkPosSet& set);
|
||||
const ChunkPosSet& get_chunk_pos_set() const;
|
||||
ChunkPosSet get_chunk_pos_set();
|
||||
|
||||
const glm::vec3& get_front() const;
|
||||
|
||||
const std::optional<LookBlock>& get_look_block_pos() const;
|
||||
// thread safe
|
||||
glm::vec3 get_player_pos() const;
|
||||
const MoveState& get_move_state() const;
|
||||
|
||||
void change_mode(GameMode mode);
|
||||
void reload_config();
|
||||
void set_player_pos(const glm::vec3& pos);
|
||||
void update(float delta_time);
|
||||
|
||||
float& max_walk_speed();
|
||||
float& max_run_speed();
|
||||
float& fly_y_speed();
|
||||
|
||||
const ItemStack& get_current_itemstack() const;
|
||||
|
||||
GameMode& game_mode();
|
||||
|
||||
ClientWorld& get_world();
|
||||
|
||||
void set_uuid(std::string_view uuid);
|
||||
std::string get_uuid() const;
|
||||
const std::string& get_name() const;
|
||||
void reset_input_status();
|
||||
void init(std::string_view name);
|
||||
|
||||
bool ray_cast(const glm::vec3& start, const glm::vec3& dir,
|
||||
glm::ivec3& block_pos, glm::vec3& normal,
|
||||
float distance = 4.0f);
|
||||
bool is_underwater() const;
|
||||
void set_underwater(bool u);
|
||||
void place_block(float dt);
|
||||
|
||||
int selected_hotbar() const;
|
||||
void set_hotbar(int pos, const ItemStack& item);
|
||||
std::span<const ItemStack, HOTBAR_SUM> get_hotbar() const;
|
||||
|
||||
private:
|
||||
using enum GameMode;
|
||||
float m_max_walk_speed = DEFAULT_MAX_WALK_SPEED;
|
||||
float m_max_run_speed = DEFAULT_MAX_RUN_SPEED;
|
||||
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{};
|
||||
float m_place_time = PLACE_BLOCK_INTERVAL;
|
||||
|
||||
std::array<ItemStack, HOTBAR_SUM> m_hotbar;
|
||||
float m_sensitivity = 0.15f;
|
||||
|
||||
float space_on_time = 0.0f;
|
||||
bool space_on = false;
|
||||
|
||||
int m_selected_hotbar = 0;
|
||||
|
||||
bool m_moving = false;
|
||||
bool m_sprinting = false;
|
||||
bool m_underwater = false;
|
||||
|
||||
// player is tow block tall, the pos is the lower pos
|
||||
ChunkPos m_last_chunk_pos{0, 0};
|
||||
|
||||
glm::vec3 m_front{0, 0, -1};
|
||||
glm::vec3 m_right{0, 0, 0};
|
||||
|
||||
MouseState m_mouse_state{};
|
||||
GameMode m_game_mode = CREATIVE;
|
||||
std::optional<LookBlock> m_look_block = std::nullopt;
|
||||
std::string m_name{};
|
||||
mutable std::shared_mutex m_uuid_mutex;
|
||||
std::string m_uuid;
|
||||
ClientWorld& m_world;
|
||||
|
||||
std::unordered_map<std::string, Timer> m_timers;
|
||||
|
||||
mutable std::shared_mutex m_player_pos_mutex;
|
||||
mutable std::shared_mutex m_chunk_pos_mutex;
|
||||
ChunkPosSet m_player_chunk_pos_set;
|
||||
|
||||
void update_direction();
|
||||
void update_lookup_block();
|
||||
|
||||
void update_move(float delta_time);
|
||||
|
||||
void update_player_chunk();
|
||||
|
||||
void play_walk_sound(float dt);
|
||||
Gait compute_gait() const;
|
||||
struct ClientPlayer {
|
||||
Position pos{};
|
||||
Position render_pos{};
|
||||
EntityInfo entity{};
|
||||
WalkPose walk{};
|
||||
Orientation angle{};
|
||||
Orientation render_angle{};
|
||||
};
|
||||
|
||||
struct PlayerRenderData {
|
||||
EntityInfo info{};
|
||||
Position render_pos{};
|
||||
Orientation angle{};
|
||||
Gait gait{};
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
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/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/client_chunk.hpp"
|
||||
#include "Cubed/gameplay/client_player.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 <absl/container/flat_hash_set.h>
|
||||
#include <deque>
|
||||
@@ -34,11 +33,10 @@ public:
|
||||
void init(std::string_view player_name,
|
||||
std::shared_ptr<NetworkClient> client);
|
||||
void update(float dt);
|
||||
void update_players(float dt);
|
||||
bool handle_event(const Event& e);
|
||||
const std::optional<LookBlock>& get_look_block_pos() const;
|
||||
ClientPlayer& get_player();
|
||||
const ClientPlayer& get_player() const;
|
||||
LocalPlayer& get_player();
|
||||
const LocalPlayer& get_player() const;
|
||||
int get_block(const glm::ivec3& block_pos) const override;
|
||||
bool is_solid(const glm::ivec3& block_pos) const override;
|
||||
bool can_pass_block(const glm::ivec3& block_pos) const override;
|
||||
@@ -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<glm::vec4>& planes();
|
||||
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;
|
||||
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;
|
||||
|
||||
ClientPlayer m_player;
|
||||
ClientPlayerManager m_player_manager;
|
||||
ChunkHashMap m_chunks;
|
||||
AudioEngine& m_audio;
|
||||
Config& m_config;
|
||||
@@ -139,11 +135,6 @@ private:
|
||||
std::vector<glm::vec4> m_planes;
|
||||
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<ChunkPos> m_dirty_chunk_queue;
|
||||
tbb::concurrent_queue<PendingSound> m_pending_sound;
|
||||
@@ -152,7 +143,6 @@ private:
|
||||
|
||||
std::deque<ChunkPos> m_dirty_queue;
|
||||
std::vector<const ChunkRenderSnapshot*> m_render_snapshots;
|
||||
std::vector<PlayerRenderData> m_render_player_data;
|
||||
|
||||
tbb::concurrent_unordered_map<std::string, TickTimer> m_ticktimers;
|
||||
std::unordered_map<std::string, Timer> 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);
|
||||
|
||||
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
|
||||
160
include/Cubed/gameplay/local_player.hpp
Normal file
160
include/Cubed/gameplay/local_player.hpp
Normal file
@@ -0,0 +1,160 @@
|
||||
#pragma once
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/gameplay/chunk_pos.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"
|
||||
#include "Cubed/input/input.hpp"
|
||||
|
||||
#include <absl/container/flat_hash_set.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
namespace Cubed {
|
||||
|
||||
class ClientWorld;
|
||||
class LocalPlayer {
|
||||
public:
|
||||
static constexpr size_t HOTBAR_SUM = 10;
|
||||
static constexpr float WALK_SOUND_INTERVAL = 0.45f;
|
||||
static constexpr float RUN_SOUND_INTERVAL = 0.3f;
|
||||
using ChunkPosSet = absl::flat_hash_set<ChunkPos, ChunkPos::Hash>;
|
||||
LocalPlayer(ClientWorld& world);
|
||||
~LocalPlayer();
|
||||
|
||||
bool handle_mouse_button_event(const MouseButtonEvent& e);
|
||||
bool handle_key_event(const KeyEvent& e);
|
||||
bool handle_mouse_wheel_event(const MouseWheelEvent& e);
|
||||
|
||||
void update_front_vec(float offset_x, float offset_y);
|
||||
bool update_player_move_state(Key key, KeyAction action);
|
||||
bool update_scroll(float yoffset);
|
||||
|
||||
void update_chunk_set(const ChunkPosSet& set);
|
||||
|
||||
const ChunkPosSet& get_chunk_pos_set() const;
|
||||
ChunkPosSet get_chunk_pos_set();
|
||||
|
||||
const glm::vec3& get_front() const;
|
||||
|
||||
const std::optional<LookBlock>& get_look_block_pos() const;
|
||||
// thread safe
|
||||
glm::vec3 get_player_pos() const;
|
||||
const MoveState& get_move_state() const;
|
||||
|
||||
void change_mode(GameMode mode);
|
||||
void reload_config();
|
||||
void set_player_pos(const glm::vec3& pos);
|
||||
void update(float delta_time);
|
||||
|
||||
float& max_walk_speed();
|
||||
float& max_run_speed();
|
||||
float& fly_y_speed();
|
||||
|
||||
const ItemStack& get_current_itemstack() const;
|
||||
|
||||
GameMode& game_mode();
|
||||
|
||||
ClientWorld& get_world();
|
||||
|
||||
void set_uuid(std::string_view uuid);
|
||||
std::string get_uuid() const;
|
||||
const std::string& get_name() const;
|
||||
void reset_input_status();
|
||||
void init(std::string_view name);
|
||||
|
||||
bool ray_cast(const glm::vec3& start, const glm::vec3& dir,
|
||||
glm::ivec3& block_pos, glm::vec3& normal,
|
||||
float distance = 4.0f);
|
||||
bool is_underwater() const;
|
||||
void set_underwater(bool u);
|
||||
void place_block(float dt);
|
||||
|
||||
int selected_hotbar() const;
|
||||
void set_hotbar(int pos, const ItemStack& item);
|
||||
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:
|
||||
using enum GameMode;
|
||||
float m_max_walk_speed = DEFAULT_MAX_WALK_SPEED;
|
||||
float m_max_run_speed = DEFAULT_MAX_RUN_SPEED;
|
||||
float m_max_y_speed = 7.5f;
|
||||
static constexpr float MAX_SPACE_ON_TIME = 0.3f;
|
||||
static constexpr float PLACE_BLOCK_INTERVAL = 0.2f;
|
||||
|
||||
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<ItemStack, HOTBAR_SUM> m_hotbar;
|
||||
float m_sensitivity = 0.15f;
|
||||
|
||||
float space_on_time = 0.0f;
|
||||
bool space_on = false;
|
||||
|
||||
int m_selected_hotbar = 0;
|
||||
|
||||
bool m_moving = false;
|
||||
bool m_sprinting = false;
|
||||
bool m_underwater = false;
|
||||
|
||||
// player is tow block tall, the pos is the lower pos
|
||||
ChunkPos m_last_chunk_pos{0, 0};
|
||||
|
||||
glm::vec3 m_front{0, 0, -1};
|
||||
glm::vec3 m_right{0, 0, 0};
|
||||
|
||||
MouseState m_mouse_state{};
|
||||
GameMode m_game_mode = CREATIVE;
|
||||
std::optional<LookBlock> m_look_block = std::nullopt;
|
||||
std::string m_name{};
|
||||
mutable std::shared_mutex m_uuid_mutex;
|
||||
std::string m_uuid;
|
||||
ClientWorld& m_world;
|
||||
|
||||
std::unordered_map<std::string, Timer> m_timers;
|
||||
|
||||
mutable std::shared_mutex m_player_pos_mutex;
|
||||
mutable std::shared_mutex m_chunk_pos_mutex;
|
||||
ChunkPosSet m_player_chunk_pos_set;
|
||||
|
||||
void update_direction();
|
||||
void update_lookup_block();
|
||||
|
||||
void update_move(float delta_time);
|
||||
|
||||
void update_player_chunk();
|
||||
|
||||
void play_walk_sound(float dt);
|
||||
Gait compute_gait() const;
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/entity.hpp"
|
||||
namespace Cubed {
|
||||
struct PlayerData {
|
||||
Position pos{};
|
||||
Position render_pos{};
|
||||
EntityInfo entity{};
|
||||
WalkPose walk{};
|
||||
Orientation angle{};
|
||||
Orientation render_angle{};
|
||||
};
|
||||
|
||||
struct PlayerRenderData {
|
||||
EntityInfo info{};
|
||||
Position render_pos{};
|
||||
Orientation angle{};
|
||||
Gait gait{};
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -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<bool, bool, bool> update(float dt, Entity& e,
|
||||
static glm::vec3 get_move_distance(float dt, const Direction& d,
|
||||
const Velocity& v);
|
||||
static std::tuple<bool, bool, bool> update(float dt, ServerEntity& e,
|
||||
World& world);
|
||||
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:
|
||||
};
|
||||
|
||||
@@ -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:
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ target_sources(${PROJECT_NAME}
|
||||
gameplay/server_chunk.cpp
|
||||
gameplay/client_chunk.cpp
|
||||
gameplay/server_player.cpp
|
||||
gameplay/client_player.cpp
|
||||
gameplay/local_player.cpp
|
||||
gameplay/session.cpp
|
||||
gameplay/network_client.cpp
|
||||
render/player_renderer.cpp
|
||||
@@ -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
|
||||
)
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Cubed/camera.hpp"
|
||||
|
||||
#include "Cubed/gameplay/client_player.hpp"
|
||||
#include "Cubed/gameplay/client_world.hpp"
|
||||
#include "Cubed/gameplay/local_player.hpp"
|
||||
#include "Cubed/tools/cubed_assert.hpp"
|
||||
|
||||
namespace {
|
||||
@@ -58,7 +58,7 @@ void Camera::update_move_camera() {
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::camera_init(ClientPlayer* player) {
|
||||
void Camera::camera_init(LocalPlayer* player) {
|
||||
m_player = player;
|
||||
update_move_camera();
|
||||
hot_reload();
|
||||
@@ -100,7 +100,7 @@ void Camera::change_perspective() {
|
||||
bool Camera::is_first_person() const {
|
||||
return m_perspective == Perspective::FIRST_PERSON;
|
||||
}
|
||||
ClientPlayer* Camera::player() { return m_player; }
|
||||
LocalPlayer* Camera::player() { return m_player; }
|
||||
bool Camera::handle_event(const Event& e) {
|
||||
return std::visit(
|
||||
Overloaded{[this](const MouseMoveEvent& e) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "Cubed/app.hpp"
|
||||
#include "Cubed/config.hpp"
|
||||
#include "Cubed/gameplay/cave_path.hpp"
|
||||
#include "Cubed/gameplay/client_player.hpp"
|
||||
#include "Cubed/gameplay/local_player.hpp"
|
||||
#include "Cubed/gameplay/river.path.hpp"
|
||||
#include "Cubed/scene/world_scene.hpp"
|
||||
#include "Cubed/tools/log.hpp"
|
||||
|
||||
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/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 <absl/container/inlined_vector.h>
|
||||
@@ -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<LookBlock>& ClientWorld::get_look_block_pos() const {
|
||||
|
||||
return m_player.get_look_block_pos();
|
||||
return m_player_manager.get_local().get_look_block_pos();
|
||||
}
|
||||
|
||||
ClientPlayer& ClientWorld::get_player() { return m_player; }
|
||||
const ClientPlayer& 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)) {
|
||||
if (m_player_manager.has_player(block_box)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Arena 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);
|
||||
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<NetworkClient> 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<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) {
|
||||
|
||||
// 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<ChunkDataReq>(&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<uint8_t> 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<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));
|
||||
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<ClientChunk> 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,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 >= ClientPlayer::WALK_SOUND_INTERVAL) {
|
||||
player.walk.moving_time = 0.0f;
|
||||
play_walk_sound();
|
||||
}
|
||||
}
|
||||
if (player.walk.gait == Gait::RUN) {
|
||||
if (player.walk.moving_time >= ClientPlayer::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)) {
|
||||
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.handle_mouse_wheel_event(e)) {
|
||||
if (m_player_manager.get_local().handle_mouse_wheel_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[this](const KeyEvent& e) {
|
||||
if (m_player.handle_key_event(e)) {
|
||||
if (m_player_manager.get_local().handle_key_event(e)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1075,11 +905,6 @@ const std::vector<const ChunkRenderSnapshot*>&
|
||||
ClientWorld::render_snapshots() const {
|
||||
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; }
|
||||
} // 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
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "Cubed/gameplay/client_player.hpp"
|
||||
#include "Cubed/gameplay/local_player.hpp"
|
||||
|
||||
#include "Cubed/audio/audio_engine.hpp"
|
||||
#include "Cubed/config.hpp"
|
||||
@@ -10,24 +10,23 @@
|
||||
namespace {} // namespace
|
||||
|
||||
namespace Cubed {
|
||||
ClientPlayer::ClientPlayer(ClientWorld& world)
|
||||
: Entity(0, "cubed:player"), m_world(world) {}
|
||||
ClientPlayer::~ClientPlayer() {}
|
||||
LocalPlayer::LocalPlayer(ClientWorld& world) : m_world(world) {}
|
||||
LocalPlayer::~LocalPlayer() {}
|
||||
|
||||
const glm::vec3& ClientPlayer::get_front() const { return m_front; }
|
||||
const glm::vec3& LocalPlayer::get_front() const { return m_front; }
|
||||
|
||||
const std::optional<LookBlock>& ClientPlayer::get_look_block_pos() const {
|
||||
const std::optional<LookBlock>& LocalPlayer::get_look_block_pos() const {
|
||||
return m_look_block;
|
||||
}
|
||||
glm::vec3 ClientPlayer::get_player_pos() const {
|
||||
glm::vec3 LocalPlayer::get_player_pos() const {
|
||||
|
||||
std::shared_lock lock(m_player_pos_mutex);
|
||||
return m_pos.value;
|
||||
}
|
||||
|
||||
const MoveState& ClientPlayer::get_move_state() const { return m_move_state; }
|
||||
const MoveState& LocalPlayer::get_move_state() const { return m_move_state; }
|
||||
|
||||
bool ClientPlayer::ray_cast(const glm::vec3& start, const glm::vec3& front,
|
||||
bool LocalPlayer::ray_cast(const glm::vec3& start, const glm::vec3& front,
|
||||
glm::ivec3& block_pos, glm::vec3& normal,
|
||||
float distance) {
|
||||
glm::vec3 dir = glm::normalize(front);
|
||||
@@ -100,7 +99,7 @@ bool ClientPlayer::ray_cast(const glm::vec3& start, const glm::vec3& front,
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientPlayer::change_mode(GameMode mode) {
|
||||
void LocalPlayer::change_mode(GameMode mode) {
|
||||
m_game_mode = mode;
|
||||
Logger::info("Change GameMode to {}", to_str(mode));
|
||||
if (mode == CREATIVE) {
|
||||
@@ -115,17 +114,17 @@ void ClientPlayer::change_mode(GameMode mode) {
|
||||
glm::vec3{m_max_run_speed, m_max_y_speed, m_max_run_speed};
|
||||
}
|
||||
}
|
||||
void ClientPlayer::reload_config() {
|
||||
void LocalPlayer::reload_config() {
|
||||
auto& config = m_world.get_config();
|
||||
m_sensitivity = config.get("player.mouse_sensitivity", 0.15f);
|
||||
}
|
||||
void ClientPlayer::set_player_pos(const glm::vec3& pos) {
|
||||
void LocalPlayer::set_player_pos(const glm::vec3& pos) {
|
||||
|
||||
std::lock_guard lock(m_player_pos_mutex);
|
||||
m_pos.value = pos;
|
||||
}
|
||||
|
||||
void ClientPlayer::update(float delta_time) {
|
||||
void LocalPlayer::update(float delta_time) {
|
||||
WalkPose pos = m_walk_pose;
|
||||
pos.gait = compute_gait();
|
||||
m_walk_pose = pos;
|
||||
@@ -138,7 +137,7 @@ void ClientPlayer::update(float delta_time) {
|
||||
d_rep("speed", "Speed(x, y, z): {:.2} m/s {:.2} m/s {:.2} m/s",
|
||||
m_velocity.value.x, m_velocity.value.y, m_velocity.value.z);
|
||||
}
|
||||
bool ClientPlayer::update_player_move_state(Key key, KeyAction action) {
|
||||
bool LocalPlayer::update_player_move_state(Key key, KeyAction action) {
|
||||
if (key == Key::W) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
m_move_state.forward = true;
|
||||
@@ -238,7 +237,7 @@ bool ClientPlayer::update_player_move_state(Key key, KeyAction action) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientPlayer::update_front_vec(float offset_x, float offset_y) {
|
||||
void LocalPlayer::update_front_vec(float offset_x, float offset_y) {
|
||||
Orientation& angle = m_angle;
|
||||
angle.yaw += offset_x * m_sensitivity;
|
||||
angle.pitch += offset_y * m_sensitivity;
|
||||
@@ -254,7 +253,7 @@ void ClientPlayer::update_front_vec(float offset_x, float offset_y) {
|
||||
m_front = glm::normalize(m_front);
|
||||
}
|
||||
|
||||
void ClientPlayer::update_direction() {
|
||||
void LocalPlayer::update_direction() {
|
||||
m_right = glm::normalize(glm::cross(m_front, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
|
||||
glm::vec3 move_dir_front = glm::vec3(0.0f);
|
||||
@@ -279,7 +278,7 @@ void ClientPlayer::update_direction() {
|
||||
}
|
||||
}
|
||||
|
||||
void ClientPlayer::update_lookup_block() {
|
||||
void LocalPlayer::update_lookup_block() {
|
||||
// calculate the block that is looked
|
||||
glm::ivec3 block_pos;
|
||||
glm::vec3 block_normal;
|
||||
@@ -292,7 +291,7 @@ void ClientPlayer::update_lookup_block() {
|
||||
m_look_block = std::nullopt;
|
||||
}
|
||||
}
|
||||
void ClientPlayer::place_block(float dt) {
|
||||
void LocalPlayer::place_block(float dt) {
|
||||
|
||||
if (m_look_block == std::nullopt) {
|
||||
return;
|
||||
@@ -324,17 +323,17 @@ void ClientPlayer::place_block(float dt) {
|
||||
}
|
||||
}
|
||||
|
||||
int ClientPlayer::selected_hotbar() const { return m_selected_hotbar; }
|
||||
void ClientPlayer::set_hotbar(int pos, const ItemStack& item) {
|
||||
int LocalPlayer::selected_hotbar() const { return m_selected_hotbar; }
|
||||
void LocalPlayer::set_hotbar(int pos, const ItemStack& item) {
|
||||
ASSERT(pos >= 0 && static_cast<size_t>(pos) < HOTBAR_SUM);
|
||||
m_hotbar[pos] = item;
|
||||
}
|
||||
std::span<const ItemStack, ClientPlayer::HOTBAR_SUM>
|
||||
ClientPlayer::get_hotbar() const {
|
||||
std::span<const ItemStack, LocalPlayer::HOTBAR_SUM>
|
||||
LocalPlayer::get_hotbar() const {
|
||||
return m_hotbar;
|
||||
}
|
||||
|
||||
void ClientPlayer::update_move(float delta_time) {
|
||||
void LocalPlayer::update_move(float delta_time) {
|
||||
// if frame rate less than 1 frame per second, don't update
|
||||
if (delta_time > 1.0f) {
|
||||
return;
|
||||
@@ -361,7 +360,8 @@ void ClientPlayer::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 ClientPlayer::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;
|
||||
}
|
||||
@@ -408,7 +410,7 @@ void ClientPlayer::update_move(float delta_time) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClientPlayer::update_player_chunk() {
|
||||
void LocalPlayer::update_player_chunk() {
|
||||
float x, z;
|
||||
{
|
||||
std::shared_lock lock(m_player_pos_mutex);
|
||||
@@ -424,7 +426,7 @@ void ClientPlayer::update_player_chunk() {
|
||||
}
|
||||
}
|
||||
|
||||
Gait ClientPlayer::compute_gait() const {
|
||||
Gait LocalPlayer::compute_gait() const {
|
||||
if (m_velocity.value.x < 0.01f && m_velocity.value.z < 0.01f)
|
||||
return Gait::STOP;
|
||||
|
||||
@@ -434,7 +436,7 @@ Gait ClientPlayer::compute_gait() const {
|
||||
return Gait::WALK;
|
||||
}
|
||||
|
||||
bool ClientPlayer::update_scroll(float yoffset) {
|
||||
bool LocalPlayer::update_scroll(float yoffset) {
|
||||
if (m_game_mode == SPECTATOR) {
|
||||
if (yoffset > 0) {
|
||||
if (m_max_run_speed < 500.0f) {
|
||||
@@ -462,7 +464,7 @@ bool ClientPlayer::update_scroll(float yoffset) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClientPlayer::handle_mouse_button_event(const MouseButtonEvent& e) {
|
||||
bool LocalPlayer::handle_mouse_button_event(const MouseButtonEvent& e) {
|
||||
if (e.action == KeyAction::PRESS) {
|
||||
if (e.key == MouseKey::LEFT_BUTTON) {
|
||||
m_mouse_state.left = true;
|
||||
@@ -488,7 +490,7 @@ bool ClientPlayer::handle_mouse_button_event(const MouseButtonEvent& e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClientPlayer::handle_key_event(const KeyEvent& e) {
|
||||
bool LocalPlayer::handle_key_event(const KeyEvent& e) {
|
||||
|
||||
if (update_player_move_state(e.key, e.action)) {
|
||||
return true;
|
||||
@@ -496,51 +498,51 @@ bool ClientPlayer::handle_key_event(const KeyEvent& e) {
|
||||
|
||||
return false;
|
||||
}
|
||||
bool ClientPlayer::handle_mouse_wheel_event(const MouseWheelEvent& e) {
|
||||
bool LocalPlayer::handle_mouse_wheel_event(const MouseWheelEvent& e) {
|
||||
if (update_scroll(e.offset)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientPlayer::update_chunk_set(const ChunkPosSet& set) {
|
||||
void LocalPlayer::update_chunk_set(const ChunkPosSet& set) {
|
||||
std::lock_guard lock(m_chunk_pos_mutex);
|
||||
m_player_chunk_pos_set.clear();
|
||||
m_player_chunk_pos_set.insert(set.begin(), set.end());
|
||||
}
|
||||
|
||||
const ClientPlayer::ChunkPosSet& ClientPlayer::get_chunk_pos_set() const {
|
||||
const LocalPlayer::ChunkPosSet& LocalPlayer::get_chunk_pos_set() const {
|
||||
std::shared_lock lock(m_chunk_pos_mutex);
|
||||
return m_player_chunk_pos_set;
|
||||
}
|
||||
|
||||
ClientPlayer::ChunkPosSet ClientPlayer::get_chunk_pos_set() {
|
||||
LocalPlayer::ChunkPosSet LocalPlayer::get_chunk_pos_set() {
|
||||
std::lock_guard lock(m_chunk_pos_mutex);
|
||||
return m_player_chunk_pos_set;
|
||||
}
|
||||
|
||||
float& ClientPlayer::max_walk_speed() { return m_max_walk_speed; }
|
||||
float& ClientPlayer::max_run_speed() { return m_max_run_speed; }
|
||||
float& ClientPlayer::fly_y_speed() { return m_max_y_speed; }
|
||||
const ItemStack& ClientPlayer::get_current_itemstack() const {
|
||||
float& LocalPlayer::max_walk_speed() { return m_max_walk_speed; }
|
||||
float& LocalPlayer::max_run_speed() { return m_max_run_speed; }
|
||||
float& LocalPlayer::fly_y_speed() { return m_max_y_speed; }
|
||||
const ItemStack& LocalPlayer::get_current_itemstack() const {
|
||||
return m_hotbar[m_selected_hotbar];
|
||||
};
|
||||
|
||||
GameMode& ClientPlayer::game_mode() { return m_game_mode; }
|
||||
ClientWorld& ClientPlayer::get_world() { return m_world; }
|
||||
GameMode& LocalPlayer::game_mode() { return m_game_mode; }
|
||||
ClientWorld& LocalPlayer::get_world() { return m_world; }
|
||||
|
||||
void ClientPlayer::set_uuid(std::string_view uuid) {
|
||||
void LocalPlayer::set_uuid(std::string_view uuid) {
|
||||
std::lock_guard lock(m_uuid_mutex);
|
||||
m_uuid = uuid;
|
||||
}
|
||||
std::string ClientPlayer::get_uuid() const {
|
||||
std::string LocalPlayer::get_uuid() const {
|
||||
|
||||
std::shared_lock lock(m_uuid_mutex);
|
||||
return m_uuid;
|
||||
}
|
||||
const std::string& ClientPlayer::get_name() const { return m_name; }
|
||||
const std::string& LocalPlayer::get_name() const { return m_name; }
|
||||
|
||||
void ClientPlayer::reset_input_status() {
|
||||
void LocalPlayer::reset_input_status() {
|
||||
m_mouse_state.left = false;
|
||||
m_mouse_state.right = false;
|
||||
m_move_state.left = false;
|
||||
@@ -551,7 +553,10 @@ void ClientPlayer::reset_input_status() {
|
||||
m_move_state.up = false;
|
||||
}
|
||||
|
||||
void ClientPlayer::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);
|
||||
m_pos.value = {0.0f, 255.0f, 0.0f};
|
||||
@@ -588,6 +593,18 @@ void ClientPlayer::init(std::string_view name) {
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientPlayer::is_underwater() const { return m_underwater; }
|
||||
void ClientPlayer::set_underwater(bool u) { m_underwater = u; }
|
||||
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
|
||||
@@ -107,7 +107,7 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
||||
case std::to_underlying(PacketEnum::PLAYER_INFO_RSP): {
|
||||
auto* rsp = Arena::Create<PlayerInfoRsp>(&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): {
|
||||
|
||||
@@ -99,21 +99,28 @@ bool update_z(const glm::vec3& pos, const glm::vec3& distance, World& world,
|
||||
}
|
||||
|
||||
} // 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) {
|
||||
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<bool, bool, bool> PhysicalSystem::update(float dt, Entity& e,
|
||||
std::tuple<bool, bool, bool> 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<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 y = false;
|
||||
bool z = false;
|
||||
@@ -121,17 +128,17 @@ std::tuple<bool, bool, bool> 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<bool, bool, bool> 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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
auto players = world.player_manager().render_player_data();
|
||||
if (!shadow_render) {
|
||||
shader.set_loc("proj_matrix", m_p_mat);
|
||||
}
|
||||
|
||||
for (auto& player : players) {
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ ItemSlot* InventoryUI::get_hovered_slot() {
|
||||
return nullptr;
|
||||
}
|
||||
std::pair<ItemSlot*, size_t> InventoryUI::get_hovered_hotbar_slot() {
|
||||
for (size_t i = 0; i < ClientPlayer::HOTBAR_SUM; ++i) {
|
||||
for (size_t i = 0; i < LocalPlayer::HOTBAR_SUM; ++i) {
|
||||
auto& slot = m_hotbar[i];
|
||||
if (slot->hovered()) {
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ void WorldUIManager::init() {
|
||||
auto& hotbar = m_root_widget->add_child<RowLayout>();
|
||||
hotbar.set_anchor(Anchor::BOTTOM_CENTER);
|
||||
m_hotbar = &hotbar;
|
||||
for (size_t i = 0; i < ClientPlayer::HOTBAR_SUM; ++i) {
|
||||
for (size_t i = 0; i < LocalPlayer::HOTBAR_SUM; ++i) {
|
||||
auto& slot = hotbar.add_child<ItemSlot>();
|
||||
slot.set_default_background(texture_manager);
|
||||
slot.set_scale(5.0f);
|
||||
@@ -130,7 +130,7 @@ void WorldUIManager::update_hotbar() {
|
||||
auto& player = m_scene.client_world().get_player();
|
||||
auto hotbar = player.get_hotbar();
|
||||
size_t selected = player.selected_hotbar();
|
||||
for (size_t i = 0; i < ClientPlayer::HOTBAR_SUM; ++i) {
|
||||
for (size_t i = 0; i < LocalPlayer::HOTBAR_SUM; ++i) {
|
||||
auto type = hotbar[i].type;
|
||||
if (selected == i) {
|
||||
m_hotbar_slot[i]->set_border_visale(true);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Cubed/window.hpp"
|
||||
|
||||
#include "Cubed/camera.hpp"
|
||||
#include "Cubed/gameplay/client_player.hpp"
|
||||
#include "Cubed/gameplay/local_player.hpp"
|
||||
#include "Cubed/tools/cubed_assert.hpp"
|
||||
#include "Cubed/tools/env_tools.hpp"
|
||||
#include "Cubed/tools/font.hpp"
|
||||
|
||||
Reference in New Issue
Block a user