🥵 Fix blunders in world switching

This commit is contained in:
tovjemam 2026-03-21 23:31:50 +01:00
parent af865a16e5
commit 9c7ae446c1
5 changed files with 70 additions and 53 deletions

View File

@ -204,6 +204,7 @@ static void PollEvents()
#ifndef NDEBUG #ifndef NDEBUG
#define USE_LOCAL_SERVER #define USE_LOCAL_SERVER
#endif #endif
#define USE_LOCAL_SERVER
#ifdef USE_LOCAL_SERVER #ifdef USE_LOCAL_SERVER
#define WS_URL "ws://127.0.0.1:11200/ws" #define WS_URL "ws://127.0.0.1:11200/ws"

View File

@ -53,52 +53,6 @@ void game::EnterableWorld::RemovePlayer(Player& player)
RemovePlayerCharacter(player); RemovePlayerCharacter(player);
} }
game::PlayerCharacter& game::EnterableWorld::MovePlayerToWorld(Player& player, EnterableWorld& new_world, const glm::vec3& pos, float yaw)
{
auto old_character = player_characters_.at(&player);
auto& tuning = old_character->GetTuning();
RemovePlayer(player);
player.SetWorld(&new_world);
auto& new_character = new_world.InsertPlayer(player, tuning, pos, yaw);
return new_character;
}
void game::EnterableWorld::MoveVehicleToWorld(DrivableVehicle& vehicle, EnterableWorld& new_world, const glm::vec3& pos,
float yaw)
{
if (&vehicle.GetWorld() != this)
throw std::runtime_error("Attempt to move vehicle from other world");
auto& tuning = vehicle.GetTuning();
auto& new_vehicle = new_world.Spawn<DrivableVehicle>(tuning);
new_vehicle.SetPosition(pos);
// TODO: yaw
// move passengers
size_t num_seats = vehicle.GetNumSeats();
for (size_t i = 0; i < num_seats; ++i)
{
auto passenger = vehicle.GetPassenger(i);
if (!passenger)
continue; // empty seat
auto player_passenger = dynamic_cast<PlayerCharacter*>(passenger);
if (!player_passenger)
continue; // not player but npc, will be ejected automatically upon vehicle deletion
auto player = player_passenger->GetPlayer();
if (!player)
continue; // moved already or sth
auto& new_character = MovePlayerToWorld(*player, new_world, glm::vec3(0.0f), 0.0f);
new_character.SetVehicle(&new_vehicle, i);
}
vehicle.Remove();
}
game::PlayerCharacter* game::EnterableWorld::GetPlayerCharacter(Player& player) game::PlayerCharacter* game::EnterableWorld::GetPlayerCharacter(Player& player)
{ {
auto it = player_characters_.find(&player); auto it = player_characters_.find(&player);
@ -122,10 +76,16 @@ game::PlayerCharacter& game::EnterableWorld::CreatePlayerCharacter(Player& playe
void game::EnterableWorld::RemovePlayerCharacter(Player& player) void game::EnterableWorld::RemovePlayerCharacter(Player& player)
{ {
auto character = GetPlayerCharacter(player); auto it = player_characters_.find(&player);
if (it == player_characters_.end())
return;
auto character = it->second;
if (character) if (character)
{ {
character->DetachFromPlayer(); character->DetachFromPlayer();
character->Remove(); character->Remove();
} }
player_characters_.erase(it);
} }

View File

@ -21,10 +21,6 @@ public:
virtual void PlayerViewAnglesChanged(Player& player, float yaw, float pitch); virtual void PlayerViewAnglesChanged(Player& player, float yaw, float pitch);
virtual void RemovePlayer(Player& player); virtual void RemovePlayer(Player& player);
// moves
PlayerCharacter& MovePlayerToWorld(Player& player, EnterableWorld& new_world, const glm::vec3& pos, float yaw);
void MoveVehicleToWorld(DrivableVehicle& vehicle, EnterableWorld& new_world, const glm::vec3& pos, float yaw);
PlayerCharacter* GetPlayerCharacter(Player& player); PlayerCharacter* GetPlayerCharacter(Player& player);
private: private:

View File

@ -115,6 +115,57 @@ void game::Game::BroadcastChat(const std::string& text)
} }
} }
game::PlayerCharacter& game::Game::MovePlayerToWorld(PlayerGameInfo& player_info, EnterableWorld& new_world,
const glm::vec3& pos, float yaw)
{
auto& player = player_info.player;
auto& old_world = *player_info.world;
auto old_character = old_world.GetPlayerCharacter(player);
auto& tuning = old_character->GetTuning();
old_world.RemovePlayer(player);
player.SetWorld(&new_world);
auto& new_character = new_world.InsertPlayer(player, tuning, pos, yaw);
player_info.world = &new_world;
return new_character;
}
void game::Game::MoveVehicleToWorld(DrivableVehicle& vehicle, EnterableWorld& new_world, const glm::vec3& pos,
float yaw)
{
auto& tuning = vehicle.GetTuning();
auto& new_vehicle = new_world.Spawn<DrivableVehicle>(tuning);
new_vehicle.SetPosition(pos);
// TODO: yaw
// move passengers
size_t num_seats = vehicle.GetNumSeats();
for (size_t i = 0; i < num_seats; ++i)
{
auto passenger = vehicle.GetPassenger(i);
if (!passenger)
continue; // empty seat
auto player_passenger = dynamic_cast<PlayerCharacter*>(passenger);
if (!player_passenger)
continue; // not player but npc, will be ejected automatically upon vehicle deletion
auto player = player_passenger->GetPlayer();
if (!player)
continue; // moved already or sth
auto& player_info = GetPlayerInfo(*player);
auto& new_character = MovePlayerToWorld(player_info, new_world, glm::vec3(0.0f), 0.0f);
new_character.SetVehicle(&new_vehicle, i);
}
vehicle.Remove();
}
void game::Game::MovePlayerToWorld(PlayerGameInfo& player_info, EnterableWorld* new_world, const glm::vec3& pos, void game::Game::MovePlayerToWorld(PlayerGameInfo& player_info, EnterableWorld* new_world, const glm::vec3& pos,
float yaw, bool with_vehicle) float yaw, bool with_vehicle)
{ {
@ -130,13 +181,18 @@ void game::Game::MovePlayerToWorld(PlayerGameInfo& player_info, EnterableWorld*
} }
if (vehicle) if (vehicle)
world.MoveVehicleToWorld(*vehicle, *new_world, pos, yaw); MoveVehicleToWorld(*vehicle, *new_world, pos, yaw);
else else
world.MovePlayerToWorld(player, *new_world, pos, yaw); MovePlayerToWorld(player_info, *new_world, pos, yaw);
player_info.world = new_world; player_info.world = new_world;
} }
game::PlayerGameInfo& game::Game::GetPlayerInfo(Player& player)
{
return players_.at(&player);
}
game::EnterableWorld* game::Game::FindPlayerWorld(Player& player) const game::EnterableWorld* game::Game::FindPlayerWorld(Player& player) const
{ {
auto it = players_.find(&player); auto it = players_.find(&player);

View File

@ -34,8 +34,12 @@ public:
private: private:
void BroadcastChat(const std::string& text); void BroadcastChat(const std::string& text);
PlayerCharacter& MovePlayerToWorld(PlayerGameInfo& player_info, EnterableWorld& new_world, const glm::vec3& pos, float yaw);
void MoveVehicleToWorld(DrivableVehicle& vehicle, EnterableWorld& new_world, const glm::vec3& pos, float yaw);
void MovePlayerToWorld(PlayerGameInfo& player_info, EnterableWorld* new_world, const glm::vec3& pos, float yaw, bool with_vehicle = false); void MovePlayerToWorld(PlayerGameInfo& player_info, EnterableWorld* new_world, const glm::vec3& pos, float yaw, bool with_vehicle = false);
PlayerGameInfo& GetPlayerInfo(Player& player);
EnterableWorld* FindPlayerWorld(Player& player) const; EnterableWorld* FindPlayerWorld(Player& player) const;
private: private: