diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index bd362bf2..2fd48dc3 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -151,12 +151,13 @@ const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardTyp return "primaryScore ASC, secondaryScore ASC, tertiaryScore ASC"; case Type::Survival: return Game::config->GetValue("classic_survival_scoring") == "1" ? - "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC" : - "secondaryScore DESC, primaryScore DESC, tertiaryScore DESC"; + "secondaryScore DESC, primaryScore DESC, tertiaryScore DESC" : + "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC"; + case Type::SurvivalNS: + return "primaryScore DESC, secondaryScore ASC, tertiaryScore DESC"; case Type::ShootingGallery: case Type::FootRace: case Type::UnusedLeaderboard4: - case Type::SurvivalNS: case Type::Donations: case Type::None: default: @@ -217,7 +218,7 @@ void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t r ) )QUERY"; - std::string weeklyFilter = " AND date >= curdate() - INTERVAL DAYOFWEEK(curdate()) - 7 DAY"; + std::string weeklyFilter = " AND UNIX_TIMESTAMP(last_played) BETWEEN UNIX_TIMESTAMP(date_sub(now(),INTERVAL 1 WEEK)) AND UNIX_TIMESTAMP(now()) "; std::string filter; // Setup our filter based on the query type @@ -247,7 +248,7 @@ void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t r // Create and execute the actual save here. Using a heap allocated buffer to avoid stack overflow constexpr uint16_t STRING_LENGTH = 4096; std::unique_ptr lookupBuffer = std::make_unique(STRING_LENGTH); - [[maybe_unused]] int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), filter.c_str(), resultStart, resultEnd); + int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), filter.c_str(), resultStart, resultEnd); DluAssert(res != -1); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer.get())); @@ -292,7 +293,7 @@ std::string FormatInsert(const Leaderboard::Type& type, const Score& score, cons constexpr uint16_t STRING_LENGTH = 400; // Then fill in our score char finishedQuery[STRING_LENGTH]; - [[maybe_unused]] int32_t res = snprintf(finishedQuery, STRING_LENGTH, insertStatement.c_str(), score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); + int32_t res = snprintf(finishedQuery, STRING_LENGTH, insertStatement.c_str(), score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); DluAssert(res != -1); return finishedQuery; } @@ -324,7 +325,6 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi break; } case Leaderboard::Type::Survival: { - // Config option may reverse these oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); break; @@ -357,6 +357,15 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi return; } bool newHighScore = lowerScoreBetter ? newScore < oldScore : newScore > oldScore; + // Nimbus station has a weird leaderboard where we need a custom scoring system + if (leaderboardType == Leaderboard::Type::SurvivalNS) { + newHighScore = newScore.GetPrimaryScore() > oldScore.GetPrimaryScore() || + (newScore.GetPrimaryScore() == oldScore.GetPrimaryScore() && newScore.GetSecondaryScore() < oldScore.GetSecondaryScore()); + } else if (leaderboardType == Leaderboard::Type::Survival && Game::config->GetValue("classic_survival_scoring") == "1") { + Score oldScoreFlipped(oldScore.GetSecondaryScore(), oldScore.GetPrimaryScore()); + Score newScoreFlipped(newScore.GetSecondaryScore(), newScore.GetPrimaryScore()); + newHighScore = newScoreFlipped > oldScoreFlipped; + } if (newHighScore) { saveQuery = FormatInsert(leaderboardType, newScore, true); } else if (leaderboardType == Leaderboard::Type::Racing && tertiaryScore) { diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 9ccfe12a..dd7921db 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -50,7 +50,7 @@ RacingControlComponent::RacingControlComponent(Entity* parent) m_MainWorld = 1200; const auto worldID = Game::server->GetZoneID(); - if (dZoneManager::Instance()->CheckIfAccessibleZone((worldID/10)*10)) m_MainWorld = (worldID/10)*10; + if (dZoneManager::Instance()->CheckIfAccessibleZone((worldID / 10) * 10)) m_MainWorld = (worldID / 10) * 10; m_ActivityID = 42; CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); @@ -323,7 +323,7 @@ void RacingControlComponent::OnRequestDie(Entity* player) { // Reset imagination to half its current value, rounded up to the nearest value divisible by 10, as it was done in live. if (destroyableComponent) destroyableComponent->SetImagination(respawnImagination); EntityManager::Instance()->SerializeEntity(vehicle); - }); + }); auto* characterComponent = player->GetComponent(); if (characterComponent != nullptr) { @@ -379,7 +379,6 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu const auto score = m_LoadedPlayers * 10 + data->finished; LootGenerator::Instance().GiveActivityLoot(player, m_Parent, m_ActivityID, score); - LeaderboardManager::SaveScore(player->GetObjectID(), m_ActivityID, static_cast(data->bestLapTime), static_cast(data->raceTime), static_cast(data->finished == 1)); // Giving rewards GameMessages::SendNotifyRacingClient( @@ -838,6 +837,7 @@ void RacingControlComponent::Update(float deltaTime) { "Completed time %llu, %llu", raceTime, raceTime * 1000); + LeaderboardManager::SaveScore(playerEntity->GetObjectID(), m_ActivityID, static_cast(player.bestLapTime), static_cast(player.raceTime), static_cast(player.finished == 1)); // Entire race time missionComponent->Progress(eMissionTaskType::RACING, (raceTime) * 1000, (LWOOBJID)eRacingTaskParam::TOTAL_TRACK_TIME); diff --git a/dScripts/BaseSurvivalServer.cpp b/dScripts/BaseSurvivalServer.cpp index ac775787..7f522eb5 100644 --- a/dScripts/BaseSurvivalServer.cpp +++ b/dScripts/BaseSurvivalServer.cpp @@ -8,6 +8,8 @@ #include "eMissionState.h" #include "MissionComponent.h" #include "Character.h" +#include "Game.h" +#include "dConfig.h" void BaseSurvivalServer::SetGameVariables(Entity* self) { this->constants = std::move(GetConstants()); @@ -354,6 +356,7 @@ void BaseSurvivalServer::GameOver(Entity* self) { const auto score = GetActivityValue(self, playerID, 0); const auto time = GetActivityValue(self, playerID, 1); + SaveScore(self, playerID, score, time); GameMessages::SendNotifyClientZoneObject(self->GetObjectID(), u"Update_ScoreBoard", time, 0, playerID, std::to_string(score), UNASSIGNED_SYSTEM_ADDRESS); @@ -377,7 +380,6 @@ void BaseSurvivalServer::GameOver(Entity* self) { } StopActivity(self, playerID, score, time); - SaveScore(self, playerID, time, score); } state.waveNumber = 1; diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index 48144960..e240c7ca 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -378,7 +378,7 @@ void BaseWavesServer::GameOver(Entity* self, bool won) { } StopActivity(self, playerID, wave, time, score); - SaveScore(self, playerID, time, wave); + SaveScore(self, playerID, wave, time); } }