From 06958cb9cdba6baa1c44afb827aaa2294217b7fd Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 4 Oct 2025 17:25:23 -0700 Subject: [PATCH] feat: hardcore limit % coins dropped on death (#1898) * feat: hardcore limit % coins dropped on death Update EntityManager.cpp * fix log msg --- dGame/EntityManager.cpp | 2 ++ dGame/EntityManager.h | 2 ++ dGame/dComponents/DestroyableComponent.cpp | 18 ++++++++++++++---- resources/worldconfig.ini | 3 +++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 026fc02a..12be2e06 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -87,6 +87,8 @@ void EntityManager::ReloadConfig() { auto hcXpReduction = Game::config->GetValue("hardcore_uscore_reduction"); m_HardcoreUscoreReduction = hcXpReduction.empty() ? 1.0f : GeneralUtils::TryParse(hcXpReduction).value_or(1.0f); m_HardcoreMode = GetHardcoreDisabledWorlds().contains(Game::zoneManager->GetZoneID().GetMapID()) ? false : m_HardcoreMode; + auto hcCoinKeep = Game::config->GetValue("hardcore_coin_keep"); + m_HardcoreCoinKeep = hcCoinKeep.empty() ? false : GeneralUtils::TryParse(hcCoinKeep).value_or(0.0f); } void EntityManager::Initialize() { diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 549c922e..26daf750 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -81,6 +81,7 @@ public: const std::set& GetHardcoreUscoreReducedLots() const { return m_HardcoreUscoreReducedLots; }; const std::set& GetHardcoreUscoreExcludedEnemies() const { return m_HardcoreUscoreExcludedEnemies; }; const std::set& GetHardcoreDisabledWorlds() const { return m_HardcoreDisabledWorlds; }; + float GetHardcoreCoinKeep() const { return m_HardcoreCoinKeep; } // Messaging bool SendMessage(GameMessages::GameMsg& msg) const; @@ -125,6 +126,7 @@ private: std::set m_HardcoreUscoreReducedLots{}; std::set m_HardcoreUscoreExcludedEnemies{}; std::set m_HardcoreDisabledWorlds{}; + float m_HardcoreCoinKeep{}; }; #endif // ENTITYMANAGER_H diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index f86cd8e4..e03efd43 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -786,7 +786,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType } } else { //Check if this zone allows coin drops - if (Game::zoneManager->GetPlayerLoseCoinOnDeath()) { + if (Game::zoneManager->GetPlayerLoseCoinOnDeath() && !Game::entityManager->GetHardcoreMode()) { auto* character = m_Parent->GetCharacter(); uint64_t coinsTotal = character->GetCoins(); const uint64_t minCoinsToLose = Game::zoneManager->GetWorldConfig().coinsLostOnDeathMin; @@ -1012,13 +1012,23 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) { //get character: auto* chars = m_Parent->GetCharacter(); if (chars) { - auto coins = chars->GetCoins(); + auto oldCoins = chars->GetCoins(); + // Floor this so there arent coins generated from rounding + auto coins = static_cast(oldCoins * Game::entityManager->GetHardcoreCoinKeep()); + auto coinsToDrop = oldCoins - coins; + LOG("Player had %llu coins, will lose %i coins to have %i", oldCoins, coinsToDrop, coins); //lose all coins: - chars->SetCoins(0, eLootSourceType::NONE); + chars->SetCoins(coins, eLootSourceType::NONE); //drop all coins: - GameMessages::SendDropClientLoot(m_Parent, source, LOT_NULL, coins, m_Parent->GetPosition()); + constexpr auto MAX_TO_DROP_PER_GM = 100'000; + while (coinsToDrop > MAX_TO_DROP_PER_GM) { + LOG("Dropping 100,000, %llu left", coinsToDrop); + GameMessages::SendDropClientLoot(m_Parent, source, LOT_NULL, MAX_TO_DROP_PER_GM, m_Parent->GetPosition()); + coinsToDrop -= MAX_TO_DROP_PER_GM; + } + GameMessages::SendDropClientLoot(m_Parent, source, LOT_NULL, coinsToDrop, m_Parent->GetPosition()); } return; } diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index 9631183a..38350086 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -99,3 +99,6 @@ hardcore_uscore_excluded_enemies= # Disables hardcore mode for specific worlds, if hardcore is enabled hardcore_disabled_worlds= + +# Keeps this percentage of a players' coins on death in hardcore +hardcore_coin_keep=