🥵 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
#define USE_LOCAL_SERVER
#endif
#define USE_LOCAL_SERVER
#ifdef USE_LOCAL_SERVER
#define WS_URL "ws://127.0.0.1:11200/ws"

View File

@ -53,52 +53,6 @@ void game::EnterableWorld::RemovePlayer(Player& 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)
{
auto it = player_characters_.find(&player);
@ -122,10 +76,16 @@ game::PlayerCharacter& game::EnterableWorld::CreatePlayerCharacter(Player& playe
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)
{
character->DetachFromPlayer();
character->Remove();
}
player_characters_.erase(it);
}

View File

@ -21,10 +21,6 @@ public:
virtual void PlayerViewAnglesChanged(Player& player, float yaw, float pitch);
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);
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,
float yaw, bool with_vehicle)
{
@ -130,13 +181,18 @@ void game::Game::MovePlayerToWorld(PlayerGameInfo& player_info, EnterableWorld*
}
if (vehicle)
world.MoveVehicleToWorld(*vehicle, *new_world, pos, yaw);
MoveVehicleToWorld(*vehicle, *new_world, pos, yaw);
else
world.MovePlayerToWorld(player, *new_world, pos, yaw);
MovePlayerToWorld(player_info, *new_world, pos, yaw);
player_info.world = new_world;
}
game::PlayerGameInfo& game::Game::GetPlayerInfo(Player& player)
{
return players_.at(&player);
}
game::EnterableWorld* game::Game::FindPlayerWorld(Player& player) const
{
auto it = players_.find(&player);

View File

@ -34,8 +34,12 @@ public:
private:
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);
PlayerGameInfo& GetPlayerInfo(Player& player);
EnterableWorld* FindPlayerWorld(Player& player) const;
private: