Merge branch 'enchantmentprice' into 'master'

Use the final effect cost to calculate enchantment price (#8340)

Closes #8340

See merge request OpenMW/openmw!4530
This commit is contained in:
psi29a 2025-07-01 21:23:58 +00:00
commit a29f4b3ba0
2 changed files with 23 additions and 6 deletions

View File

@ -185,18 +185,18 @@ namespace MWMechanics
* *
* Formula on UESPWiki is not entirely correct. * Formula on UESPWiki is not entirely correct.
*/ */
float Enchanting::getEnchantPoints(bool precise) const std::vector<float> Enchanting::getEffectCosts() const
{ {
std::vector<float> costs;
if (mEffectList.mList.empty()) if (mEffectList.mList.empty())
// No effects added, cost = 0 return costs;
return 0;
costs.reserve(mEffectList.mList.size());
const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore(); const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore();
const float fEffectCostMult = store.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat(); const float fEffectCostMult = store.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat();
const float fEnchantmentConstantDurationMult const float fEnchantmentConstantDurationMult
= store.get<ESM::GameSetting>().find("fEnchantmentConstantDurationMult")->mValue.getFloat(); = store.get<ESM::GameSetting>().find("fEnchantmentConstantDurationMult")->mValue.getFloat();
float enchantmentCost = 0.f;
float cost = 0.f; float cost = 0.f;
for (const ESM::IndexedENAMstruct& effect : mEffectList.mList) for (const ESM::IndexedENAMstruct& effect : mEffectList.mList)
{ {
@ -215,9 +215,18 @@ namespace MWMechanics
if (effect.mData.mRange == ESM::RT_Target) if (effect.mData.mRange == ESM::RT_Target)
cost *= 1.5f; 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; return enchantmentCost;
} }
@ -278,13 +287,19 @@ namespace MWMechanics
if (mEnchanter.isEmpty()) if (mEnchanter.isEmpty())
return 0; return 0;
// Use the final effect's accumulated cost
float finalEffectCost = 0.f;
std::vector<float> effectCosts = getEffectCosts();
if (!effectCosts.empty())
finalEffectCost = effectCosts.back();
float priceMultipler = MWBase::Environment::get() float priceMultipler = MWBase::Environment::get()
.getESMStore() .getESMStore()
->get<ESM::GameSetting>() ->get<ESM::GameSetting>()
.find("fEnchantmentValueMult") .find("fEnchantmentValueMult")
->mValue.getFloat(); ->mValue.getFloat();
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer( int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(
mEnchanter, static_cast<int>(getEnchantPoints() * priceMultipler), true); mEnchanter, static_cast<int>(finalEffectCost * priceMultipler), true);
price *= count * getTypeMultiplier(); price *= count * getTypeMultiplier();
return std::max(1, price); return std::max(1, price);
} }

View File

@ -2,6 +2,7 @@
#define GAME_MWMECHANICS_ENCHANTING_H #define GAME_MWMECHANICS_ENCHANTING_H
#include <string> #include <string>
#include <vector>
#include <components/esm3/effectlist.hpp> #include <components/esm3/effectlist.hpp>
#include <components/esm3/loadench.hpp> #include <components/esm3/loadench.hpp>
@ -32,6 +33,7 @@ namespace MWMechanics
float getTypeMultiplier() const; float getTypeMultiplier() const;
void payForEnchantment(int count) const; void payForEnchantment(int count) const;
int getEnchantPrice(int count) const; int getEnchantPrice(int count) const;
std::vector<float> getEffectCosts() const;
public: public:
Enchanting(); Enchanting();