From 17aab41a9e868a67150080269ee858abc4b28a27 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Tue, 9 May 2023 10:58:57 -0500 Subject: [PATCH] WIP --- dGame/dComponents/RacingControlComponent.cpp | 571 ++++++++----------- dGame/dComponents/RacingControlComponent.h | 11 +- 2 files changed, 238 insertions(+), 344 deletions(-) diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 3134d5fe..f415801a 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -33,7 +33,9 @@ RacingControlComponent::RacingControlComponent(Entity* parent) : Component(parent) { m_PathName = u"MainPath"; + m_DirtyPathName = true; m_RemainingLaps = 3; + m_DirtyRaceInfo = true; m_LeadingPlayer = LWOOBJID_EMPTY; m_RaceBestTime = 0; m_RaceBestLap = 0; @@ -77,36 +79,27 @@ void RacingControlComponent::OnPlayerLoaded(Entity* player) { m_LoadedPlayers); m_LobbyPlayers.push_back(objectID); + m_DirtyLoadPlayer = true; } -void RacingControlComponent::LoadPlayerVehicle(Entity* player, - uint32_t positionNumber, bool initialLoad) { +void RacingControlComponent::LoadPlayerVehicle(Entity* player, uint32_t positionNumber, bool initialLoad) { // Load the player's vehicle. - if (player == nullptr) { - return; - } - - auto* inventoryComponent = player->GetComponent(); - - if (inventoryComponent == nullptr) { - return; - } + if (!player) return; // Find the player's vehicle. - + auto* inventoryComponent = player->GetComponent(); + if (!inventoryComponent) return; auto* item = inventoryComponent->FindItemByLot(8092); - if (item == nullptr) { + if (!item) { Game::logger->Log("RacingControlComponent", "Failed to find item"); - return; } // Calculate the vehicle's starting position. - auto* path = dZoneManager::Instance()->GetZone()->GetPath( - GeneralUtils::UTF16ToWTF8(m_PathName)); + auto* path = dZoneManager::Instance()->GetZone()->GetPath(GeneralUtils::UTF16ToWTF8(m_PathName)); auto spawnPointEntities = EntityManager::Instance()->GetEntitiesByLOT(4843); auto startPosition = NiPoint3::ZERO; @@ -123,9 +116,13 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Make sure the player is at the correct position. - GameMessages::SendTeleport(player->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + GameMessages::SendTeleport( + player->GetObjectID(), + startPosition, + startRotation, + player->GetSystemAddress(), + true, true + ); // Spawn the vehicle entity. @@ -135,32 +132,26 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, info.rot = startRotation; info.spawnerID = m_Parent->GetObjectID(); - auto* carEntity = - EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent); + auto* carEntity = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent); // Make the vehicle a child of the racing controller. m_Parent->AddChild(carEntity); - auto* destroyableComponent = - carEntity->GetComponent(); + auto* destroyableComponent = carEntity->GetComponent(); // Setup the vehicle stats. - if (destroyableComponent != nullptr) { + if (destroyableComponent) { destroyableComponent->SetMaxImagination(60); destroyableComponent->SetImagination(0); } // Setup the vehicle as being possessed by the player. - auto* possessableComponent = - carEntity->GetComponent(); + auto* possessableComponent = carEntity->GetComponent(); - if (possessableComponent != nullptr) { - possessableComponent->SetPossessor(player->GetObjectID()); - } + if (possessableComponent) possessableComponent->SetPossessor(player->GetObjectID()); // Load the vehicle's assemblyPartLOTs for display. - auto* moduleAssemblyComponent = - carEntity->GetComponent(); + auto* moduleAssemblyComponent = carEntity->GetComponent(); if (moduleAssemblyComponent) { moduleAssemblyComponent->SetSubKey(item->GetSubKey()); @@ -177,7 +168,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Setup the player as possessing the vehicle. auto* possessorComponent = player->GetComponent(); - if (possessorComponent != nullptr) { + if (possessorComponent) { possessorComponent->SetPossessable(carEntity->GetObjectID()); possessorComponent->SetPossessableType(ePossessionType::ATTACHED_VISIBLE); // for racing it's always Attached_Visible } @@ -185,24 +176,19 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Set the player's current activity as racing. auto* characterComponent = player->GetComponent(); - if (characterComponent != nullptr) { - characterComponent->SetIsRacing(true); - } + if (characterComponent) characterComponent->SetIsRacing(true); // Init the player's racing entry. if (initialLoad) { m_RacingPlayers.push_back( - { player->GetObjectID(), - carEntity->GetObjectID(), - static_cast(m_RacingPlayers.size()), - false, - {}, - startPosition, - startRotation, - 0, - 0, - 0, - 0 }); + { + player->GetObjectID(), + carEntity->GetObjectID(), + static_cast(m_RacingPlayers.size()), + false, {}, startPosition, startRotation, 0, 0, 0, 0 + } + ); + m_DirtyLoadPlayer = true; } // Construct and serialize everything when done. @@ -212,42 +198,50 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, EntityManager::Instance()->SerializeEntity(m_Parent); GameMessages::SendRacingSetPlayerResetInfo( - m_Parent->GetObjectID(), 0, 0, player->GetObjectID(), startPosition, 1, - UNASSIGNED_SYSTEM_ADDRESS); + m_Parent->GetObjectID(), 0, 0, + player->GetObjectID(), startPosition, 1, + UNASSIGNED_SYSTEM_ADDRESS + ); const auto playerID = player->GetObjectID(); // Reset the player to the start position during downtime, in case something // went wrong. m_Parent->AddCallbackTimer(1, [this, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); - - if (player == nullptr) { - return; + auto* player = EntityManager::Instance()->GetEntity(playerID); + if (!player) return; + GameMessages::SendRacingResetPlayerToLastReset( + m_Parent->GetObjectID(), playerID, + UNASSIGNED_SYSTEM_ADDRESS + ); } - - GameMessages::SendRacingResetPlayerToLastReset( - m_Parent->GetObjectID(), playerID, UNASSIGNED_SYSTEM_ADDRESS); - }); + ); GameMessages::SendSetJetPackMode(player, false); // Set the vehicle's state. - GameMessages::SendNotifyVehicleOfRacingObject(carEntity->GetObjectID(), + GameMessages::SendNotifyVehicleOfRacingObject( + carEntity->GetObjectID(), m_Parent->GetObjectID(), - UNASSIGNED_SYSTEM_ADDRESS); + UNASSIGNED_SYSTEM_ADDRESS + ); - GameMessages::SendVehicleSetWheelLockState(carEntity->GetObjectID(), false, - initialLoad, - UNASSIGNED_SYSTEM_ADDRESS); + GameMessages::SendVehicleSetWheelLockState( + carEntity->GetObjectID(), false, initialLoad, + UNASSIGNED_SYSTEM_ADDRESS + ); // Make sure everything has the correct position. - GameMessages::SendTeleport(player->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); - GameMessages::SendTeleport(carEntity->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + GameMessages::SendTeleport( + player->GetObjectID(), startPosition, + startRotation, player->GetSystemAddress(), + true, true + ); + GameMessages::SendTeleport( + carEntity->GetObjectID(), startPosition, + startRotation, player->GetSystemAddress(), + true, true + ); } void RacingControlComponent::OnRacingClientReady(Entity* player) { @@ -257,18 +251,23 @@ void RacingControlComponent::OnRacingClientReady(Entity* player) { if (racingPlayer.playerID != player->GetObjectID()) { if (racingPlayer.playerLoaded) { GameMessages::SendRacingPlayerLoaded( - m_Parent->GetObjectID(), racingPlayer.playerID, - racingPlayer.vehicleID, UNASSIGNED_SYSTEM_ADDRESS); + m_Parent->GetObjectID(), + racingPlayer.playerID, + racingPlayer.vehicleID, + UNASSIGNED_SYSTEM_ADDRESS + ); } - continue; } racingPlayer.playerLoaded = true; GameMessages::SendRacingPlayerLoaded( - m_Parent->GetObjectID(), racingPlayer.playerID, - racingPlayer.vehicleID, UNASSIGNED_SYSTEM_ADDRESS); + m_Parent->GetObjectID(), + racingPlayer.playerID, + racingPlayer.vehicleID, + UNASSIGNED_SYSTEM_ADDRESS + ); } EntityManager::Instance()->SerializeEntity(m_Parent); @@ -279,19 +278,20 @@ void RacingControlComponent::OnRequestDie(Entity* player) { // them. for (auto& racingPlayer : m_RacingPlayers) { - if (racingPlayer.playerID != player->GetObjectID()) { - continue; - } + if (racingPlayer.playerID != player->GetObjectID()) continue; - auto* vehicle = - EntityManager::Instance()->GetEntity(racingPlayer.vehicleID); + auto* vehicle = EntityManager::Instance()->GetEntity(racingPlayer.vehicleID); if (!vehicle) return; if (!racingPlayer.noSmashOnReload) { racingPlayer.smashedTimes++; - GameMessages::SendDie(vehicle, vehicle->GetObjectID(), LWOOBJID_EMPTY, true, - eKillType::VIOLENT, u"", 0, 0, 90.0f, false, true, 0); + GameMessages::SendDie( + vehicle, vehicle->GetObjectID(), + LWOOBJID_EMPTY, true, + eKillType::VIOLENT, u"", 0, 0, 90.0f, + false, true, 0 + ); auto* destroyableComponent = vehicle->GetComponent(); uint32_t respawnImagination = 0; @@ -306,8 +306,10 @@ void RacingControlComponent::OnRequestDie(Entity* player) { vehicle->AddCallbackTimer(2.0f, [=]() { if (!vehicle || !this->m_Parent) return; GameMessages::SendRacingResetPlayerToLastReset( - m_Parent->GetObjectID(), racingPlayer.playerID, - UNASSIGNED_SYSTEM_ADDRESS); + m_Parent->GetObjectID(), + racingPlayer.playerID, + UNASSIGNED_SYSTEM_ADDRESS + ); GameMessages::SendVehicleStopBoost(vehicle, player->GetSystemAddress(), true); @@ -315,7 +317,8 @@ void RacingControlComponent::OnRequestDie(Entity* player) { m_Parent->GetObjectID(), racingPlayer.lap, racingPlayer.respawnIndex, player->GetObjectID(), racingPlayer.respawnPosition, racingPlayer.respawnIndex + 1, - UNASSIGNED_SYSTEM_ADDRESS); + UNASSIGNED_SYSTEM_ADDRESS + ); GameMessages::SendResurrect(vehicle); auto* destroyableComponent = vehicle->GetComponent(); @@ -325,50 +328,37 @@ void RacingControlComponent::OnRequestDie(Entity* player) { }); auto* characterComponent = player->GetComponent(); - if (characterComponent != nullptr) { - characterComponent->UpdatePlayerStatistic(RacingTimesWrecked); - } + if (characterComponent) characterComponent->UpdatePlayerStatistic(RacingTimesWrecked); } else { GameMessages::SendRacingSetPlayerResetInfo( m_Parent->GetObjectID(), racingPlayer.lap, racingPlayer.respawnIndex, player->GetObjectID(), racingPlayer.respawnPosition, racingPlayer.respawnIndex + 1, - UNASSIGNED_SYSTEM_ADDRESS); + UNASSIGNED_SYSTEM_ADDRESS + ); GameMessages::SendRacingResetPlayerToLastReset( - m_Parent->GetObjectID(), racingPlayer.playerID, - UNASSIGNED_SYSTEM_ADDRESS); + m_Parent->GetObjectID(), + racingPlayer.playerID, + UNASSIGNED_SYSTEM_ADDRESS + ); } } } void RacingControlComponent::OnRacingPlayerInfoResetFinished(Entity* player) { // When the player has respawned. - for (auto& racingPlayer : m_RacingPlayers) { - if (racingPlayer.playerID != player->GetObjectID()) { - continue; - } - - auto* vehicle = - EntityManager::Instance()->GetEntity(racingPlayer.vehicleID); - - if (vehicle == nullptr) { - return; - } - + if (racingPlayer.playerID != player->GetObjectID()) continue; + auto* vehicle = EntityManager::Instance()->GetEntity(racingPlayer.vehicleID); + if (!vehicle) return; racingPlayer.noSmashOnReload = false; - return; } } -void RacingControlComponent::HandleMessageBoxResponse(Entity* player, - const std::string& id) { +void RacingControlComponent::HandleMessageBoxResponse(Entity* player, const std::string& id) { auto* data = GetPlayerData(player->GetObjectID()); - - if (data == nullptr) { - return; - } + if (!data) return; if (id == "rewardButton") { if (data->collectedRewards) { @@ -384,13 +374,15 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, // Giving rewards GameMessages::SendNotifyRacingClient( - m_Parent->GetObjectID(), 2, 0, LWOOBJID_EMPTY, u"", - player->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS); + m_Parent->GetObjectID(), 2, 0, + LWOOBJID_EMPTY, u"", + player->GetObjectID(), + UNASSIGNED_SYSTEM_ADDRESS + ); auto* missionComponent = player->GetComponent(); - if (missionComponent == nullptr) return; - + if (!missionComponent) return; missionComponent->Progress(eMissionTaskType::RACING, 0, (LWOOBJID)eRacingTaskParam::COMPETED_IN_RACE); // Progress task for competing in a race missionComponent->Progress(eMissionTaskType::RACING, data->smashedTimes, (LWOOBJID)eRacingTaskParam::SAFE_DRIVER); // Finish a race without being smashed. @@ -406,87 +398,105 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, } } } else if (id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") { + Game::logger->Log("RacingControlComponent", "exiting race"); auto* vehicle = EntityManager::Instance()->GetEntity(data->vehicleID); - - if (vehicle == nullptr) { - return; - } + if (!vehicle) return; // Exiting race GameMessages::SendNotifyRacingClient( - m_Parent->GetObjectID(), 3, 0, LWOOBJID_EMPTY, u"", - player->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS); + m_Parent->GetObjectID(), 3, 0, + LWOOBJID_EMPTY, u"", + player->GetObjectID(), + UNASSIGNED_SYSTEM_ADDRESS + ); auto* playerInstance = dynamic_cast(player); - playerInstance->SendToZone(m_MainWorld); - vehicle->Kill(); } } -void RacingControlComponent::Serialize(RakNet::BitStream* outBitStream, - bool bIsInitialUpdate, - unsigned int& flags) { +void RacingControlComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { // BEGIN Scripted Activity outBitStream->Write1(); - outBitStream->Write(static_cast(m_RacingPlayers.size())); for (const auto& player : m_RacingPlayers) { outBitStream->Write(player.playerID); - for (int i = 0; i < 10; i++) { outBitStream->Write(player.data[i]); } } // END Scripted Activity + // BEGIN Base Race Control - outBitStream->Write1(); // Dirty? - outBitStream->Write(static_cast(m_RacingPlayers.size())); + outBitStream->Write(m_DirtyLobby || bIsInitialUpdate); + if (m_DirtyLobby || bIsInitialUpdate) { + outBitStream->Write(static_cast(m_LobbyPlayers.size())); + m_DirtyLobby = false; + } - outBitStream->Write(!m_RacingPlayers.empty()); - if (!m_RacingPlayers.empty()) { + outBitStream->Write(m_DirtyLoadPlayer || bIsInitialUpdate); + if (m_DirtyLoadPlayer || bIsInitialUpdate) { for (const auto& player : m_RacingPlayers) { - outBitStream->Write1(); // Has more date - - outBitStream->Write(player.playerID); - outBitStream->Write(player.vehicleID); - outBitStream->Write(player.playerIndex); - outBitStream->Write(player.playerLoaded); + if (player.playerLoaded) { + outBitStream->Write1(); // Has more data + outBitStream->Write(player.playerID); + outBitStream->Write(player.vehicleID); + outBitStream->Write(player.rank); + outBitStream->Write(player.playerLoaded); + } } - outBitStream->Write0(); // No more data + m_DirtyLoadPlayer = false; } - outBitStream->Write(!m_RacingPlayers.empty()); - if (!m_RacingPlayers.empty()) { + outBitStream->Write(m_DirtyRank || bIsInitialUpdate); + if (m_DirtyRank || bIsInitialUpdate) { for (const auto& player : m_RacingPlayers) { - outBitStream->Write1(); // Has more date - + outBitStream->Write1(); // Has more data outBitStream->Write(player.playerID); - outBitStream->Write(0); + outBitStream->Write(player.rank); } - outBitStream->Write0(); // No more data + m_DirtyRank = false; } - outBitStream->Write1(); // Dirty? + // END Base Race Control + // BEGIN Race Control - outBitStream->Write(m_RemainingLaps); + outBitStream->Write(m_DirtyRaceInfo || bIsInitialUpdate); + if (m_DirtyRaceInfo || bIsInitialUpdate) { + outBitStream->Write(m_RemainingLaps); - outBitStream->Write(static_cast(m_PathName.size())); - for (const auto character : m_PathName) { - outBitStream->Write(character); + if (m_DirtyPathName){ + outBitStream->Write(static_cast(m_PathName.size())); + for (const auto character : m_PathName) { + outBitStream->Write(character); + } + m_DirtyPathName = false; + } else { + // once we set the path, we don't need to send it every time unless it changes + outBitStream->Write(0); + } + m_DirtyRaceInfo = false; } - outBitStream->Write1(); // ??? - outBitStream->Write1(); // ??? - - outBitStream->Write(m_LeadingPlayer); - outBitStream->Write(m_RaceBestLap); - outBitStream->Write(m_RaceBestTime); + outBitStream->Write(m_DirtyEndOfRaceInfo || bIsInitialUpdate); + if (m_DirtyEndOfRaceInfo || bIsInitialUpdate){ + for (const auto& player : m_RacingPlayers) { + if (player.finished > 0) { + outBitStream->Write1(); // Has more data + outBitStream->Write(player.playerID); + outBitStream->Write(player.bestLapTime); + outBitStream->Write(player.raceTime); + } + } + outBitStream->Write0(); // No more data + m_DirtyEndOfRaceInfo = false; + } + // END Race Control } RacingPlayerInfo* RacingControlComponent::GetPlayerData(LWOOBJID playerID) { @@ -506,71 +516,46 @@ void RacingControlComponent::Update(float deltaTime) { if (!m_Loaded) { // Check if any players has disconnected before loading in for (size_t i = 0; i < m_LobbyPlayers.size(); i++) { - auto* playerEntity = - EntityManager::Instance()->GetEntity(m_LobbyPlayers[i]); - - if (playerEntity == nullptr) { + auto* playerEntity = EntityManager::Instance()->GetEntity(m_LobbyPlayers[i]); + if (!playerEntity) { --m_LoadedPlayers; - m_LobbyPlayers.erase(m_LobbyPlayers.begin() + i); - + m_DirtyLoadPlayer = true; return; } } - if (m_LoadedPlayers >= 2 || (m_LoadedPlayers == 1 && m_SoloRacing)) { - m_LoadTimer += deltaTime; - } else { - m_EmptyTimer += deltaTime; - } + if (m_LoadedPlayers >= 2 || (m_LoadedPlayers == 1 && m_SoloRacing)) m_LoadTimer += deltaTime; + else m_EmptyTimer += deltaTime; // If a player happens to be left alone for more then 30 seconds without // anyone else loading in, send them back to the main world if (m_EmptyTimer >= 30) { for (const auto player : m_LobbyPlayers) { - auto* playerEntity = - EntityManager::Instance()->GetEntity(player); - - if (playerEntity == nullptr) { - continue; - } - + auto* playerEntity = EntityManager::Instance()->GetEntity(player); + if (playerEntity) continue; auto* playerInstance = dynamic_cast(playerEntity); - playerInstance->SendToZone(m_MainWorld); } - m_LobbyPlayers.clear(); } // From the first 2 players loading in the rest have a max of 15 seconds // to load in, can raise this if it's too low if (m_LoadTimer >= 15) { - Game::logger->Log("RacingControlComponent", - "Loading all players..."); - + Game::logger->Log("RacingControlComponent", "Loading all players..."); for (size_t positionNumber = 0; positionNumber < m_LobbyPlayers.size(); positionNumber++) { - Game::logger->Log("RacingControlComponent", - "Loading player now!"); + Game::logger->Log("RacingControlComponent", "Loading player now!"); - auto* player = - EntityManager::Instance()->GetEntity(m_LobbyPlayers[positionNumber]); - - if (player == nullptr) { - return; - } - - Game::logger->Log("RacingControlComponent", - "Loading player now NOW!"); + auto* player = EntityManager::Instance()->GetEntity(m_LobbyPlayers[positionNumber]); + if (!player) return; + Game::logger->Log("RacingControlComponent", "Loading player now NOW!"); LoadPlayerVehicle(player, positionNumber + 1, true); - m_Loaded = true; } - m_Loaded = true; } - return; } @@ -578,14 +563,11 @@ void RacingControlComponent::Update(float deltaTime) { if (!m_Started) { // Check if anyone has disconnected during this period for (size_t i = 0; i < m_RacingPlayers.size(); i++) { - auto* playerEntity = EntityManager::Instance()->GetEntity( - m_RacingPlayers[i].playerID); + auto* playerEntity = EntityManager::Instance()->GetEntity(m_RacingPlayers[i].playerID); - if (playerEntity == nullptr) { + if (!playerEntity) { m_RacingPlayers.erase(m_RacingPlayers.begin() + i); - --m_LoadedPlayers; - return; } } @@ -593,29 +575,18 @@ void RacingControlComponent::Update(float deltaTime) { // If less then 2 players are left, send the rest back to the main world if (m_LoadedPlayers < 2 && !(m_LoadedPlayers == 1 && m_SoloRacing)) { for (const auto player : m_LobbyPlayers) { - auto* playerEntity = - EntityManager::Instance()->GetEntity(player); - - if (playerEntity == nullptr) { - continue; - } - + auto* playerEntity = EntityManager::Instance()->GetEntity(player); + if (!playerEntity) continue; auto* playerInstance = dynamic_cast(playerEntity); - playerInstance->SendToZone(m_MainWorld); } - return; } // Check if all players have send a ready message - int32_t readyPlayers = 0; - for (const auto& player : m_RacingPlayers) { - if (player.playerLoaded) { - ++readyPlayers; - } + if (player.playerLoaded) ++readyPlayers; } if (readyPlayers >= m_LoadedPlayers) { @@ -623,67 +594,43 @@ void RacingControlComponent::Update(float deltaTime) { if (m_StartTimer == 0) { GameMessages::SendNotifyRacingClient( m_Parent->GetObjectID(), 1, 0, LWOOBJID_EMPTY, u"", - LWOOBJID_EMPTY, UNASSIGNED_SYSTEM_ADDRESS); + LWOOBJID_EMPTY, UNASSIGNED_SYSTEM_ADDRESS + ); for (const auto& player : m_RacingPlayers) { - auto* vehicle = - EntityManager::Instance()->GetEntity(player.vehicleID); - auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); - - if (vehicle != nullptr && playerEntity != nullptr) { + auto* vehicle = EntityManager::Instance()->GetEntity(player.vehicleID); + auto* playerEntity = EntityManager::Instance()->GetEntity(player.playerID); + if (vehicle && playerEntity) { GameMessages::SendTeleport( player.playerID, player.respawnPosition, player.respawnRotation, - playerEntity->GetSystemAddress(), true, true); + playerEntity->GetSystemAddress(), true, true + ); vehicle->SetPosition(player.respawnPosition); vehicle->SetRotation(player.respawnRotation); - auto* destroyableComponent = - vehicle->GetComponent(); - - if (destroyableComponent != nullptr) { - destroyableComponent->SetImagination(0); - } - + auto* destroyableComponent = vehicle->GetComponent(); + if (destroyableComponent)destroyableComponent->SetImagination(0); EntityManager::Instance()->SerializeEntity(vehicle); - EntityManager::Instance()->SerializeEntity( - playerEntity); + EntityManager::Instance()->SerializeEntity(playerEntity); } } // Spawn imagination pickups - auto* minSpawner = dZoneManager::Instance()->GetSpawnersByName( - "ImaginationSpawn_Min")[0]; - auto* medSpawner = dZoneManager::Instance()->GetSpawnersByName( - "ImaginationSpawn_Med")[0]; - auto* maxSpawner = dZoneManager::Instance()->GetSpawnersByName( - "ImaginationSpawn_Max")[0]; + auto* minSpawner = dZoneManager::Instance()->GetSpawnersByName("ImaginationSpawn_Min")[0]; + auto* medSpawner = dZoneManager::Instance()->GetSpawnersByName("ImaginationSpawn_Med")[0]; + auto* maxSpawner = dZoneManager::Instance()->GetSpawnersByName("ImaginationSpawn_Max")[0]; minSpawner->Activate(); - - if (m_LoadedPlayers > 2) { - medSpawner->Activate(); - } - - if (m_LoadedPlayers > 4) { - maxSpawner->Activate(); - } - + if (m_LoadedPlayers > 2) medSpawner->Activate(); + if (m_LoadedPlayers > 4) maxSpawner->Activate(); // Reset players to their start location, without smashing them for (auto& player : m_RacingPlayers) { - auto* vehicleEntity = - EntityManager::Instance()->GetEntity(player.vehicleID); - auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); - - if (vehicleEntity == nullptr || playerEntity == nullptr) { - continue; - } - + auto* vehicleEntity = EntityManager::Instance()->GetEntity(player.vehicleID); + auto* playerEntity = EntityManager::Instance()->GetEntity(player.playerID); + if (!vehicleEntity || !playerEntity) continue; player.noSmashOnReload = true; - OnRequestDie(playerEntity); } } @@ -692,64 +639,45 @@ void RacingControlComponent::Update(float deltaTime) { else if (m_StartTimer >= 6) { // Activate the players movement for (auto& player : m_RacingPlayers) { - auto* vehicleEntity = - EntityManager::Instance()->GetEntity(player.vehicleID); - auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); - - if (vehicleEntity == nullptr || playerEntity == nullptr) { - continue; - } - - GameMessages::SendVehicleUnlockInput( - player.vehicleID, false, UNASSIGNED_SYSTEM_ADDRESS); + auto* vehicleEntity = EntityManager::Instance()->GetEntity(player.vehicleID); + auto* playerEntity = EntityManager::Instance()->GetEntity(player.playerID); + if (!vehicleEntity || !playerEntity) continue; + GameMessages::SendVehicleUnlockInput(player.vehicleID, false, UNASSIGNED_SYSTEM_ADDRESS); } // Start the race - GameMessages::SendActivityStart(m_Parent->GetObjectID(), - UNASSIGNED_SYSTEM_ADDRESS); - + GameMessages::SendActivityStart(m_Parent->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS); m_Started = true; - Game::logger->Log("RacingControlComponent", "Starting race"); - EntityManager::Instance()->SerializeEntity(m_Parent); - m_StartTime = std::time(nullptr); } m_StartTimer += deltaTime; - } else { - m_StartTimer = 0; - } + } else m_StartTimer = 0; return; } // Race routines - auto* path = dZoneManager::Instance()->GetZone()->GetPath( - GeneralUtils::UTF16ToWTF8(m_PathName)); + auto* path = dZoneManager::Instance()->GetZone()->GetPath(GeneralUtils::UTF16ToWTF8(m_PathName)); for (auto& player : m_RacingPlayers) { auto* vehicle = EntityManager::Instance()->GetEntity(player.vehicleID); - auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); - - if (vehicle == nullptr || playerEntity == nullptr) { - continue; - } + auto* playerEntity = EntityManager::Instance()->GetEntity(player.playerID); + if (!vehicle || !playerEntity) continue; const auto vehiclePosition = vehicle->GetPosition(); // If the player is this far below the map, safe to assume they should // be smashed by death plane if (vehiclePosition.y < -500) { - GameMessages::SendDie(vehicle, m_Parent->GetObjectID(), - LWOOBJID_EMPTY, true, eKillType::VIOLENT, u"", 0, 0, 0, - true, false, 0); - + GameMessages::SendDie( + vehicle, m_Parent->GetObjectID(), + LWOOBJID_EMPTY, true, eKillType::VIOLENT, + u"", 0, 0, 0, true, false, 0 + ); OnRequestDie(playerEntity); - continue; } @@ -757,13 +685,10 @@ void RacingControlComponent::Update(float deltaTime) { // new checkpoint uint32_t respawnIndex = 0; for (const auto& waypoint : path->pathWaypoints) { - if (player.lap == 3) { - break; - } + if (player.lap == 3) break; if (player.respawnIndex == respawnIndex) { ++respawnIndex; - continue; } @@ -772,23 +697,19 @@ void RacingControlComponent::Update(float deltaTime) { if (std::abs((int)respawnIndex - (int)player.respawnIndex) > 10 && player.respawnIndex != path->pathWaypoints.size() - 1) { ++respawnIndex; - continue; } if (Vector3::DistanceSquared(position, vehiclePosition) > 50 * 50) { ++respawnIndex; - continue; } // Only go upwards, except if we've lapped // Not sure how we are supposed to check if they've reach a // checkpoint, within 50 units seems safe - if (!(respawnIndex > player.respawnIndex || - player.respawnIndex == path->pathWaypoints.size() - 1)) { + if (!(respawnIndex > player.respawnIndex || player.respawnIndex == path->pathWaypoints.size() - 1)) { ++respawnIndex; - continue; } @@ -801,28 +722,17 @@ void RacingControlComponent::Update(float deltaTime) { // Reached the start point, lapped if (respawnIndex == 0) { time_t lapTime = std::time(nullptr) - (player.lap == 0 ? m_StartTime : player.lapTime); - // Cheating check - if (lapTime < 40) { - continue; - } - + if (lapTime < 40) continue; player.lap++; - player.lapTime = std::time(nullptr); - if (player.bestLapTime == 0 || player.bestLapTime > lapTime) { player.bestLapTime = lapTime; - - Game::logger->Log("RacingControlComponent", - "Best lap time (%llu)", lapTime); + Game::logger->Log("RacingControlComponent", "Best lap time (%llu)", lapTime); } - auto* missionComponent = - playerEntity->GetComponent(); - - if (missionComponent != nullptr) { - + auto* missionComponent = playerEntity->GetComponent(); + if (missionComponent) { // Progress lap time tasks missionComponent->Progress(eMissionTaskType::RACING, (lapTime) * 1000, (LWOOBJID)eRacingTaskParam::LAP_TIME); @@ -830,36 +740,20 @@ void RacingControlComponent::Update(float deltaTime) { m_Finished++; player.finished = m_Finished; - const auto raceTime = - (std::time(nullptr) - m_StartTime); - - player.raceTime = raceTime; - - Game::logger->Log("RacingControlComponent", - "Completed time %llu, %llu", - raceTime, raceTime * 1000); - // Entire race time + const auto raceTime = (std::time(nullptr) - m_StartTime); + player.raceTime = raceTime; + Game::logger->Log("RacingControlComponent", "Completed time %llu, %llu", raceTime, raceTime * 1000); missionComponent->Progress(eMissionTaskType::RACING, (raceTime) * 1000, (LWOOBJID)eRacingTaskParam::TOTAL_TRACK_TIME); auto* characterComponent = playerEntity->GetComponent(); - if (characterComponent != nullptr) { - characterComponent->TrackRaceCompleted(m_Finished == 1); - } - - // TODO: Figure out how to update the GUI leaderboard. + if (characterComponent) characterComponent->TrackRaceCompleted(m_Finished == 1); + m_DirtyEndOfRaceInfo = true; } } - - Game::logger->Log("RacingControlComponent", - "Lapped (%i) in (%llu)", player.lap, - lapTime); + Game::logger->Log("RacingControlComponent", "Lapped (%i) in (%llu)", player.lap, lapTime); } - - Game::logger->Log("RacingControlComponent", - "Reached point (%i)/(%i)", player.respawnIndex, - path->pathWaypoints.size()); - + Game::logger->Log("RacingControlComponent", "Reached point (%i)/(%i)", player.respawnIndex, path->pathWaypoints.size()); break; } } @@ -873,19 +767,12 @@ std::string RacingControlComponent::FormatTimeString(time_t time) { std::string minText; std::string secText; - if (min <= 0) { - minText = "0"; - } else { - minText = std::to_string(min); - } + if (min <= 0) minText = "0"; + else minText = std::to_string(min); - if (sec <= 0) { - secText = "00"; - } else if (sec <= 9) { - secText = "0" + std::to_string(sec); - } else { - secText = std::to_string(sec); - } + if (sec <= 0) secText = "00"; + else if (sec <= 9) secText = "0" + std::to_string(sec); + else secText = std::to_string(sec); return minText + ":" + secText + ".00"; } diff --git a/dGame/dComponents/RacingControlComponent.h b/dGame/dComponents/RacingControlComponent.h index 91ab2fd4..990a3414 100644 --- a/dGame/dComponents/RacingControlComponent.h +++ b/dGame/dComponents/RacingControlComponent.h @@ -25,9 +25,9 @@ struct RacingPlayerInfo { LWOOBJID vehicleID; /** - * The index of this player in the list of players + * The rank of a player */ - uint32_t playerIndex; + uint32_t rank; /** * Whether the player has finished loading or not @@ -246,4 +246,11 @@ private: float m_EmptyTimer; bool m_SoloRacing; + + bool m_DirtyEndOfRaceInfo; + bool m_DirtyRaceInfo; + bool m_DirtyPathName; + bool m_DirtyRank; + bool m_DirtyLoadPlayer; + bool m_DirtyLobby; };