From 13980c4133a45e1d2c0c8a37e72970296caac11c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 2 Feb 2022 22:50:02 -0800 Subject: [PATCH] Added logic to Convert UScore to Coins for Level 45 Characters (#348) --- dCommon/dCommonVars.h | 3 +++ dGame/dComponents/CharacterComponent.cpp | 2 +- dGame/dGameMessages/GameMessages.cpp | 7 +++---- dGame/dGameMessages/GameMessages.h | 2 +- dGame/dMission/Mission.cpp | 22 ++++++++++++++-------- dGame/dUtilities/SlashCommandHandler.cpp | 4 ++-- dZoneManager/dZoneManager.cpp | 18 ++++++++++++++++++ dZoneManager/dZoneManager.h | 12 ++++++++++++ 8 files changed, 54 insertions(+), 16 deletions(-) diff --git a/dCommon/dCommonVars.h b/dCommon/dCommonVars.h index 4920249d..680c0c1e 100644 --- a/dCommon/dCommonVars.h +++ b/dCommon/dCommonVars.h @@ -469,6 +469,9 @@ enum eRebuildState : uint32_t { REBUILD_INCOMPLETE }; +/** + * The loot source's type. + */ enum eLootSourceType : int32_t { LOOT_SOURCE_NONE = 0, LOOT_SOURCE_CHEST, diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 9337c324..c7a216f3 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -42,7 +42,7 @@ CharacterComponent::CharacterComponent(Entity* parent, Character* character) : C if (character->GetZoneID() != Game::server->GetZoneID()) { m_IsLanding = true; } - + if (LandingAnimDisabled(character->GetZoneID()) || LandingAnimDisabled(Game::server->GetZoneID()) || m_LastRocketConfig.empty()) { m_IsLanding = false; //Don't make us land on VE/minigames lol } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 58a3d014..c327ab83 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -558,7 +558,7 @@ void GameMessages::SendNotifyMissionTask(Entity* entity, const SystemAddress& sy SEND_PACKET } -void GameMessages::SendModifyLEGOScore(Entity* entity, const SystemAddress& sysAddr, int64_t score, int sourceType) { +void GameMessages::SendModifyLEGOScore(Entity* entity, const SystemAddress& sysAddr, int64_t score, eLootSourceType sourceType) { CBITSTREAM CMSGHEADER @@ -566,9 +566,8 @@ void GameMessages::SendModifyLEGOScore(Entity* entity, const SystemAddress& sysA bitStream.Write((uint16_t)GAME_MSG_MODIFY_LEGO_SCORE); bitStream.Write(score); - //Stuff stolen from the old codebase, no idea why this works. The proper implementation didn't for some reason. - bitStream.Write((int32_t)129); - bitStream.Write((unsigned char)0); + bitStream.Write(sourceType != LOOT_SOURCE_NONE); + if (sourceType != LOOT_SOURCE_NONE) bitStream.Write(sourceType); SEND_PACKET } diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 579d4ec3..430d48d9 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -69,7 +69,7 @@ namespace GameMessages { void SendNotifyMission(Entity * entity, const SystemAddress& sysAddr, int missionID, int missionState, bool sendingRewards); void SendNotifyMissionTask(Entity * entity, const SystemAddress& sysAddr, int missionID, int taskMask, std::vector updates); - void SendModifyLEGOScore(Entity* entity, const SystemAddress& sysAddr, int64_t score, int sourceType); + void SendModifyLEGOScore(Entity* entity, const SystemAddress& sysAddr, int64_t score, eLootSourceType sourceType); void SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, NDGFxValue args); void SendUIMessageServerToAllClients(const std::string& message, NDGFxValue args); diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index f2f06e58..28f4b278 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -14,6 +14,7 @@ #include "dLocale.h" #include "dLogger.h" #include "dServer.h" +#include "dZoneManager.h" Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_MissionComponent = missionComponent; @@ -421,11 +422,15 @@ void Mission::YieldRewards() { } } + int32_t coinsToSend = 0; if (info->LegoScore > 0) { - characterComponent->SetUScore(characterComponent->GetUScore() + info->LegoScore); - - if (info->isMission) { - GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), info->LegoScore, 2); + eLootSourceType lootSource = info->isMission ? LOOT_SOURCE_MISSION : LOOT_SOURCE_ACHIEVEMENT; + if(characterComponent->GetLevel() >= dZoneManager::Instance()->GetMaxLevel()) { + // Since the character is at the level cap we reward them with coins instead of UScore. + coinsToSend += info->LegoScore * dZoneManager::Instance()->GetLevelCapCurrencyConversion(); + } else { + characterComponent->SetUScore(characterComponent->GetUScore() + info->LegoScore); + GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), info->LegoScore, lootSource); } } @@ -455,8 +460,9 @@ void Mission::YieldRewards() { inventoryComponent->AddItem(pair.first, count); } - if (info->reward_currency_repeatable > 0) { - character->SetCoins(character->GetCoins() + info->reward_currency_repeatable, LOOT_SOURCE_MISSION); + if (info->reward_currency_repeatable > 0 || coinsToSend > 0) { + eLootSourceType lootSource = info->isMission ? LOOT_SOURCE_MISSION : LOOT_SOURCE_ACHIEVEMENT; + character->SetCoins(character->GetCoins() + info->reward_currency_repeatable + coinsToSend, lootSource); } return; @@ -487,9 +493,9 @@ void Mission::YieldRewards() { inventoryComponent->AddItem(pair.first, count); } - if (info->reward_currency > 0) { + if (info->reward_currency > 0 || coinsToSend > 0) { eLootSourceType lootSource = info->isMission ? LOOT_SOURCE_MISSION : LOOT_SOURCE_ACHIEVEMENT; - character->SetCoins(character->GetCoins() + info->reward_currency, lootSource); + character->SetCoins(character->GetCoins() + info->reward_currency + coinsToSend, lootSource); } if (info->reward_maxinventory > 0) { diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 5779fe3f..66502645 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1304,8 +1304,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit CharacterComponent* character = entity->GetComponent(); if (character) character->SetUScore(character->GetUScore() + uscore); - - GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, LOOTTYPE_NONE); + // LOOT_SOURCE_MODERATION should work but it doesn't. Relog to see uscore changes + GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, LOOT_SOURCE_MODERATION); } if (chatCommand == "pos" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index d2188f4f..6f11e8e4 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -118,6 +118,24 @@ LWOZONEID dZoneManager::GetZoneID() const return m_ZoneID; } +uint32_t dZoneManager::GetMaxLevel() { + if (m_MaxLevel == 0) { + auto tableData = CDClientDatabase::ExecuteQuery("SELECT LevelCap FROM WorldConfig WHERE WorldConfigID = 1 LIMIT 1;"); + m_MaxLevel = tableData.getIntField(0, -1); + tableData.finalize(); + } + return m_MaxLevel; +} + +int32_t dZoneManager::GetLevelCapCurrencyConversion() { + if (m_CurrencyConversionRate == 0) { + auto tableData = CDClientDatabase::ExecuteQuery("SELECT LevelCapCurrencyConversion FROM WorldConfig WHERE WorldConfigID = 1 LIMIT 1;"); + m_CurrencyConversionRate = tableData.getIntField(0, -1); + tableData.finalize(); + } + return m_CurrencyConversionRate; +} + void dZoneManager::Update(float deltaTime) { for (auto spawner : m_Spawners) { spawner.second->Update(deltaTime); diff --git a/dZoneManager/dZoneManager.h b/dZoneManager/dZoneManager.h index f6da56cd..8eb04cca 100644 --- a/dZoneManager/dZoneManager.h +++ b/dZoneManager/dZoneManager.h @@ -33,6 +33,8 @@ public: void NotifyZone(const dZoneNotifier& notifier, const LWOOBJID& objectID); //Notifies the zone of a certain event or command. void AddSpawner(LWOOBJID id, Spawner* spawner); LWOZONEID GetZoneID() const; + uint32_t GetMaxLevel(); + int32_t GetLevelCapCurrencyConversion(); LWOOBJID MakeSpawner(SpawnerInfo info); Spawner* GetSpawner(LWOOBJID id); void RemoveSpawner(LWOOBJID id); @@ -42,6 +44,16 @@ public: Entity* GetZoneControlObject() { return m_ZoneControlObject; } private: + /** + * The maximum level of the world. + */ + uint32_t m_MaxLevel = 0; + + /** + * The ratio of LEGO Score to currency when the character has hit the max level. + */ + int32_t m_CurrencyConversionRate = 0; + static dZoneManager* m_Address; //Singleton Zone* m_pZone; LWOZONEID m_ZoneID;