#pragma once #include "ZoneProxy.hpp" #include "interest_management/FixedGrid.hpp" #include "network/SessionId.hpp" #include "systems/Interest.hpp" #include "systems/InterestSystem.hpp" #include "world/JoltPhysicsWorld.hpp" #include "world/World.hpp" #include "PlayerMove.pb.h" #include #include #include #include #include namespace tw::net { using SpatialBackendType = im::FixedGrid<500, 500>; static constexpr float kNeighborBorderOverlap = 100.0f; /** * Manages one zone: contains state of all entities inside and does logic for them. */ class ZoneManager : public ZoneProxy { struct NeighborEntry { ZoneProxy* proxy; im::InterestId interest_id; }; std::unique_ptr m_world; JoltPhysicsWorld m_physics_world; std::unique_ptr m_spatial_backend; std::unique_ptr> m_interest_system; std::unordered_map m_client_entities; std::unordered_map m_entity_sessions; std::unordered_map m_session_input_frame; std::unordered_map m_session_acked_frame; std::vector m_neighbors; uint32_t m_next_neighbor_id = 0x80000000u; entt::entity client_entity(im::InterestId interest_id) const; void check_neighbor_transfers(); public: entt::registry& registry() { return m_world->registry(); } im::InterestSystem* interest() const { return m_interest_system.get(); } ZoneManager(im::AreaBounds zone_bounds); im::AreaBounds area() const override; void transfer_entity(EntityInfo&& info) override; entt::entity spawn_entity(EntityInfo&& info); void add_client(im::InterestId interest_id, entt::entity entity); void on_player_move(SessionId session_id, mmo::PlayerMoveMessage&& message); void register_neighbor_zone(ZoneProxy* neighbor); const im::Interest* get_interest(im::InterestId id) const; uint32_t acked_input_frame(im::InterestId interest_id) const; void update(uint32_t frame_idx, float delta_time); }; } // namespace tw::net