#include #include #include #include #include #include #include #include #include using namespace godot; namespace blitz { static const char FirstPersonPlayerScenePath[] = "res://Scenes/Characters/first_person_player.tscn"; static const char PlayerScenePath[] = "res://Scenes/Characters/player.tscn"; void World::_bind_methods() {} void World::_ready() { if (Engine::get_singleton()->is_editor_hint()) return; m_Players = find_child("Players"); DEV_ASSERT(m_Players); m_NetworkInterface = Object::cast_to(get_parent()->find_child("Network")); DEV_ASSERT(m_NetworkInterface); m_NetworkInterface->RegisterHandler(protocol::PacketType::PlayerJoin, *this); m_NetworkInterface->RegisterHandler(protocol::PacketType::PlayerLeave, *this); m_NetworkInterface->RegisterHandler(protocol::PacketType::PlayerPositionAndRotation, *this); } World::World() {} World::~World() { if (Engine::get_singleton()->is_editor_hint()) return; m_NetworkInterface->UnregisterHandler(*this); } Player* World::GetPlayerById(PlayerID a_PlayerId) { String stringId = UtilityFunctions::var_to_str(a_PlayerId); for (int i = 0; i < m_Players->get_child_count(); i++) { Node* player = m_Players->get_child(i); if (player->get_name() == stringId) { return Object::cast_to(player); } } return nullptr; } void World::HandlePacket(const protocol::packets::PlayerJoin& a_PlayerJoin) { const protocol::PlayerInfo& playerInfo = a_PlayerJoin.m_Data.m_Player; AddPlayer(playerInfo.m_PlayerId, playerInfo.m_PlayerName); } void World::HandlePacket(const protocol::packets::PlayerLeave& a_PlayerLeave) { RemovePlayer(a_PlayerLeave.m_Data.m_PlayerId); } void World::HandlePacket(const protocol::packets::PlayerPositionAndRotation& a_PlayerPos) { const auto& data = a_PlayerPos.m_Data; if (data.m_Player == get_multiplayer()->get_unique_id() || data.m_Player != a_PlayerPos.m_Sender) return; SetPlayerPositionAndRotation(data.m_Player, data.m_Position, data.m_Rotation, data.m_Velocity); } void World::AddPlayer(PlayerID a_PlayerId, String a_PlayerName) { UtilityFunctions::print("New Player with id : ", a_PlayerId, " and name ", a_PlayerName); if (a_PlayerId == get_multiplayer()->get_unique_id()) { Ref serverScene = ResourceLoader::get_singleton()->load(FirstPersonPlayerScenePath); FirstPersonPlayer* player = Object::cast_to(serverScene->instantiate()); player->set_name(UtilityFunctions::var_to_str(a_PlayerId)); player->m_PeerId = a_PlayerId; m_Players->add_child(player); } else { Ref serverScene = ResourceLoader::get_singleton()->load(PlayerScenePath); Player* player = Object::cast_to(serverScene->instantiate()); player->set_name(UtilityFunctions::var_to_str(a_PlayerId)); player->m_PeerId = a_PlayerId; m_Players->add_child(player); } } void World::RemovePlayer(PlayerID a_PlayerId) { UtilityFunctions::print("Removing Player with id : ", a_PlayerId); Player* player = GetPlayerById(a_PlayerId); if (player) { player->queue_free(); } } void World::SetPlayerPositionAndRotation( PlayerID a_PlayerId, const Vector3& a_Position, const Vector3& a_Rotation, const godot::Vector3& a_Velocity) { Player* player = GetPlayerById(a_PlayerId); if (player) { player->set_position(a_Position); player->SetCameraRotation(a_Rotation); player->set_velocity(a_Velocity); } } } // namespace blitz