From 0f9be64904734c217792002c1b2636ff42aec0ea Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Tue, 4 Feb 2025 09:17:31 +0300 Subject: [PATCH] Use the final effect cost to calculate enchantment price (#8340) --- apps/openmw/mwmechanics/enchanting.cpp | 27 ++++++++++++++++++++------ apps/openmw/mwmechanics/enchanting.hpp | 2 ++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 7d0007f9e3..66bef89e2c 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -185,18 +185,18 @@ namespace MWMechanics * * Formula on UESPWiki is not entirely correct. */ - float Enchanting::getEnchantPoints(bool precise) const + std::vector Enchanting::getEffectCosts() const { + std::vector costs; if (mEffectList.mList.empty()) - // No effects added, cost = 0 - return 0; + return costs; + costs.reserve(mEffectList.mList.size()); const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore(); const float fEffectCostMult = store.get().find("fEffectCostMult")->mValue.getFloat(); const float fEnchantmentConstantDurationMult = store.get().find("fEnchantmentConstantDurationMult")->mValue.getFloat(); - float enchantmentCost = 0.f; float cost = 0.f; for (const ESM::IndexedENAMstruct& effect : mEffectList.mList) { @@ -215,9 +215,18 @@ namespace MWMechanics if (effect.mData.mRange == ESM::RT_Target) cost *= 1.5f; - enchantmentCost += precise ? cost : std::floor(cost); + costs.push_back(cost); } + return costs; + } + + float Enchanting::getEnchantPoints(bool precise) const + { + float enchantmentCost = 0.f; + for (float cost : getEffectCosts()) + enchantmentCost += precise ? cost : std::floor(cost); + return enchantmentCost; } @@ -278,13 +287,19 @@ namespace MWMechanics if (mEnchanter.isEmpty()) return 0; + // Use the final effect's accumulated cost + float finalEffectCost = 0.f; + std::vector effectCosts = getEffectCosts(); + if (!effectCosts.empty()) + finalEffectCost = effectCosts.back(); + float priceMultipler = MWBase::Environment::get() .getESMStore() ->get() .find("fEnchantmentValueMult") ->mValue.getFloat(); int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer( - mEnchanter, static_cast(getEnchantPoints() * priceMultipler), true); + mEnchanter, static_cast(finalEffectCost * priceMultipler), true); price *= count * getTypeMultiplier(); return std::max(1, price); } diff --git a/apps/openmw/mwmechanics/enchanting.hpp b/apps/openmw/mwmechanics/enchanting.hpp index 5db02b8cba..98e0982f7c 100644 --- a/apps/openmw/mwmechanics/enchanting.hpp +++ b/apps/openmw/mwmechanics/enchanting.hpp @@ -2,6 +2,7 @@ #define GAME_MWMECHANICS_ENCHANTING_H #include +#include #include #include @@ -32,6 +33,7 @@ namespace MWMechanics float getTypeMultiplier() const; void payForEnchantment(int count) const; int getEnchantPrice(int count) const; + std::vector getEffectCosts() const; public: Enchanting();