diff --git a/include/Cubed/gameplay/client_entity_manager.hpp b/include/Cubed/gameplay/client_entity_manager.hpp index 2485bc5..6d90d36 100644 --- a/include/Cubed/gameplay/client_entity_manager.hpp +++ b/include/Cubed/gameplay/client_entity_manager.hpp @@ -10,14 +10,15 @@ namespace Cubed { class ClientWorld; class ClientEntityManager { public: - enum class Command { CREATE, DESTORY }; + enum class Command { CREATE, DESTORY, UPDATE }; ClientEntityManager(ClientWorld& world); void update(); void init(); - void receive_entity_create(S2CEntityCreate& s2c); + void receive_entity_create(S2CEntityCreate& msg); void receive_entity_destory(EntityID id); + void receive_entity_update(S2CEntityUpdate& msg); void destory(EntityID id); void create(std::string_view name, const glm::vec3& pos); @@ -30,11 +31,17 @@ private: std::string name; glm::vec3 pos; }; + + struct UpdateInfo { + EntityID id; + glm::vec3 pos; + }; + using EntityMap = tbb::concurrent_hash_map; using acc = EntityMap::accessor; using cacc = EntityMap::const_accessor; using CreateFunc = std::function; - using TaskElement = std::variant; + using TaskElement = std::variant; using TaskPair = std::pair; ClientWorld& m_world; @@ -48,6 +55,7 @@ private: // not thread safe void handle_entity_create(EntityID id, std::string_view name, const glm::vec3& pos); + void handle_entity_update(UpdateInfo& info); template void create_entity_in_registry(EntityID id, Args&&... args) { { diff --git a/include/Cubed/gameplay/packet.hpp b/include/Cubed/gameplay/packet.hpp index c5f8e62..aa4f3f8 100644 --- a/include/Cubed/gameplay/packet.hpp +++ b/include/Cubed/gameplay/packet.hpp @@ -51,10 +51,12 @@ enum class PacketEnum : uint16_t { LOGIN_RSP = 1002, LOGOUT_REQ = 1003, LOGOUT_RSP = 1004, + PLAYER_INFO = 2001, C2S_PLAYER_INFO = 2002, PLAYER_INFO_RSP = 2003, PLAYER_WATER_SOUND = 2004, + CHUNK_DATA_REQ = 3001, CHUNK_DATA_RSP = 3002, BLOCK_CHANGE_REQ = 3003, @@ -65,8 +67,11 @@ enum class PacketEnum : uint16_t { S2C_ENTITY_DESTORY = 3008, C2S_ENTITY_CREATE_REQUEST = 3009, C2S_ENTITY_DESTORY_REQUEST = 3010, + S2C_ENTITY_UPDATE = 3011, + CHAT_MSG = 4001, VOICE_MSG = 4002, + PING = 9001, PONG = 9002 @@ -145,6 +150,9 @@ template <> constexpr uint16_t get_packet_id() { template <> constexpr uint16_t get_packet_id() { return std::to_underlying(PacketEnum::VOICE_MSG); } +template <> constexpr uint16_t get_packet_id() { + return std::to_underlying(PacketEnum::S2C_ENTITY_UPDATE); +} template requires std::derived_from diff --git a/include/Cubed/gameplay/server_entity_manager.hpp b/include/Cubed/gameplay/server_entity_manager.hpp index 3c95860..d4f6771 100644 --- a/include/Cubed/gameplay/server_entity_manager.hpp +++ b/include/Cubed/gameplay/server_entity_manager.hpp @@ -44,6 +44,7 @@ private: void handle_entity_destory(EntityID id); void handle_task(); void send_all_entities(std::shared_ptr& session); + void update_ai(); template EntityID create_entity_in_factory(Args&&... args) { auto entity = m_registry.create(); diff --git a/src/gameplay/client_entity_manager.cpp b/src/gameplay/client_entity_manager.cpp index 7dc0937..46a8c66 100644 --- a/src/gameplay/client_entity_manager.cpp +++ b/src/gameplay/client_entity_manager.cpp @@ -36,8 +36,23 @@ void ClientEntityManager::handle_entity_create(EntityID id, c->transform.position.value = pos; } +void ClientEntityManager::handle_entity_update(UpdateInfo& info) { + entt::entity e; + { + cacc a; + if (m_entities.find(a, info.id)) { + e = a->second; + } else { + return; + } + } + auto creature = m_registry.try_get(e); + ASSERT(creature); + creature->transform.position.value = info.pos; +} + void ClientEntityManager::receive_entity_create(S2CEntityCreate& s2c) { - EntityCreateElement c; + EntityCreateElement c{}; c.id = s2c.id(); c.name = s2c.name(); c.pos = {s2c.pos().x(), s2c.pos().y(), s2c.pos().z()}; @@ -48,6 +63,13 @@ void ClientEntityManager::receive_entity_destory(EntityID id) { m_tasks.emplace(Command::DESTORY, id); } +void ClientEntityManager::receive_entity_update(S2CEntityUpdate& msg) { + UpdateInfo e; + e.id = msg.id(); + e.pos = Tools::get_net_pos(msg.pos()); + m_tasks.emplace(Command::UPDATE, std::move(e)); +} + void ClientEntityManager::destory(EntityID id) { auto client = m_world.get_client(); Arena arena; @@ -81,6 +103,11 @@ void ClientEntityManager::handle_task() { ASSERT(p); handle_entity_destory(*p); } break; + case Command::UPDATE: { + auto* p = std::get_if(&pair.second); + ASSERT(p); + handle_entity_update(*p); + } } } } diff --git a/src/gameplay/network_client.cpp b/src/gameplay/network_client.cpp index 82e65fe..7791b6f 100644 --- a/src/gameplay/network_client.cpp +++ b/src/gameplay/network_client.cpp @@ -156,6 +156,12 @@ asio::awaitable NetworkClient::read_loop() { m_world.entity_manager().receive_entity_destory(msg->id()); } } break; + case std::to_underlying(PacketEnum::S2C_ENTITY_UPDATE): { + auto* msg = Arena::Create(&arena); + if (decode_packet(*msg, body_data, header)) { + m_world.entity_manager().receive_entity_update(*msg); + } + } break; } } } catch (const asio::system_error& e) { diff --git a/src/gameplay/server_entity_manager.cpp b/src/gameplay/server_entity_manager.cpp index 0dc6d1b..53a1297 100644 --- a/src/gameplay/server_entity_manager.cpp +++ b/src/gameplay/server_entity_manager.cpp @@ -22,7 +22,10 @@ void ServerEntityManager::init() { std::move(c), PigTag{}); }); } -void ServerEntityManager::update() { handle_task(); } +void ServerEntityManager::update() { + handle_task(); + update_ai(); +} void ServerEntityManager::handle_task() { TaskPair pair; diff --git a/src/proto/world/entity.proto b/src/proto/world/entity.proto index 14e1ee6..99fb89f 100644 --- a/src/proto/world/entity.proto +++ b/src/proto/world/entity.proto @@ -21,4 +21,9 @@ message C2SEntityCreateRequest { string uuid = 1; string name = 2; Vec3 pos = 3; +} + +message S2CEntityUpdate { + uint64 id = 1; + Vec3 pos = 2; } \ No newline at end of file