diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 799a89ab5a..3672c2aec7 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -70,7 +70,7 @@ namespace MWGui mPrice->setCaption(boost::lexical_cast(mEnchanting.getEnchantPrice())); - switch(mEnchanting.getEnchantType()) + switch(mEnchanting.getCastStyle()) { case 0: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce","Cast Once")); @@ -169,7 +169,7 @@ namespace MWGui image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem); mEnchanting.setOldItem(item); - mEnchanting.nextEnchantType(); + mEnchanting.nextCastStyle(); updateLabels(); } @@ -248,7 +248,7 @@ namespace MWGui void EnchantingDialog::onTypeButtonClicked(MyGUI::Widget* sender) { - mEnchanting.nextEnchantType(); + mEnchanting.nextCastStyle(); updateLabels(); } diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index e53a14120f..8efbf3c8c2 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -12,7 +12,7 @@ namespace MWMechanics { Enchanting::Enchanting(): - mEnchantType(0) + mCastStyle(ESM::CS_CastOnce) {} void Enchanting::setOldItem(MWWorld::Ptr oldItem) @@ -41,9 +41,9 @@ namespace MWMechanics mEffectList=effectList; } - int Enchanting::getEnchantType() const + int Enchanting::getCastStyle() const { - return mEnchantType; + return mCastStyle; } void Enchanting::setSoulGem(MWWorld::Ptr soulGem) @@ -74,11 +74,11 @@ namespace MWMechanics MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1); } - if(mEnchantType==3) + if(mCastStyle==3) { enchantment.mData.mCharge=0; } - enchantment.mData.mType = mEnchantType; + enchantment.mData.mType = mCastStyle; enchantment.mData.mCost = getEnchantCost(); enchantment.mEffects = mEffectList; @@ -98,78 +98,97 @@ namespace MWMechanics return true; } - void Enchanting::nextEnchantType() + void Enchanting::nextCastStyle() { - mEnchantType++; + mCastStyle++; if (itemEmpty()) { - mEnchantType = 0; + mCastStyle = 0; return; } if ((mObjectType == typeid(ESM::Armor).name())||(mObjectType == typeid(ESM::Clothing).name())) { int soulConstAmount = MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->getInt(); - switch(mEnchantType) + switch(mCastStyle) { case 1: - mEnchantType = 2; + mCastStyle = 2; case 3: if(getGemCharge() 2 or (2 + 0) == (1 + 2) => 3 + * + * Formula on UESPWiki is not entirely correct. + */ float Enchanting::getEnchantCost() const { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - float cost = 0; - std::vector mEffects = mEffectList.mList; - int i=mEffects.size(); - if(i<=0) - return 0; + if (mEffectList.mList.empty()) + // No effects added, cost = 0 + return 0; - /* - Formula from http://www.uesp.net/wiki/Morrowind:Enchant - */ + const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + std::vector mEffects = mEffectList.mList; + + float enchantmentCost = 0; + int effectsLeftCnt = mEffects.size(); + float baseCost, magnitudeCost, areaCost; + int magMin, magMax, area; for (std::vector::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it) { - const ESM::MagicEffect* effect = store.get().find(it->mEffectID); + baseCost = (store.get().find(it->mEffectID))->mData.mBaseCost; + // To reflect vanilla behavior + magMin = (it->mMagnMin == 0) ? 1 : it->mMagnMin; + magMax = (it->mMagnMax == 0) ? 1 : it->mMagnMax; + area = (it->mArea == 0) ? 1 : it->mArea; - float cost1 = ((it->mMagnMin + it->mMagnMax)*it->mDuration*effect->mData.mBaseCost*0.025); - - float cost2 = (std::max(1, it->mArea)*0.125*effect->mData.mBaseCost); - - if(mEnchantType==3) + if (mCastStyle == ESM::CS_ConstantEffect) { - int constDurationMultipler = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentConstantDurationMult")->getFloat(); - cost1 *= constDurationMultipler; - cost2 *= 2; + magnitudeCost = (magMin + magMax) * baseCost * 2.5; + } + else + { + magnitudeCost = (magMin + magMax) * it->mDuration * baseCost * 0.025; + if(it->mRange == ESM::RT_Target) + magnitudeCost *= 1.5; } - if(it->mRange == ESM::RT_Target) - cost1 *= 1.5; - float fullcost = cost1+cost2; - fullcost*= i; - i--; + areaCost = area * 0.025 * baseCost; + if (it->mRange == ESM::RT_Target) + areaCost *= 1.5; - cost+=fullcost; + enchantmentCost += (magnitudeCost + areaCost) * effectsLeftCnt; + --effectsLeftCnt; } - return cost; + + return enchantmentCost; } int Enchanting::getEnchantPrice() const @@ -236,7 +255,7 @@ namespace MWMechanics + (0.125 * creatureStats.getAttribute (ESM::Attribute::Luck).getModified())); float chance2 = 2.5 * getEnchantCost(); - if(mEnchantType==3) + if(mCastStyle==3) { float constantChance = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentConstantChanceMult")->getFloat(); chance2 /= constantChance; diff --git a/apps/openmw/mwmechanics/enchanting.hpp b/apps/openmw/mwmechanics/enchanting.hpp index d7acf60e77..a04bd86e98 100644 --- a/apps/openmw/mwmechanics/enchanting.hpp +++ b/apps/openmw/mwmechanics/enchanting.hpp @@ -14,7 +14,7 @@ namespace MWMechanics MWWorld::Ptr mSoulGemPtr; MWWorld::Ptr mEnchanter; - int mEnchantType; + int mCastStyle; bool mSelfEnchanting; @@ -34,8 +34,8 @@ namespace MWMechanics void setEffect(ESM::EffectList effectList); void setSoulGem(MWWorld::Ptr soulGem); bool create(); //Return true if created, false if failed. - void nextEnchantType(); //Set enchant type to next possible type (for mOldItemPtr object) - int getEnchantType() const; + void nextCastStyle(); //Set enchant type to next possible type (for mOldItemPtr object) + int getCastStyle() const; float getEnchantCost() const; int getEnchantPrice() const; float getMaxEnchantValue() const; diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index bd86f9ba03..f474638912 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -23,6 +23,15 @@ enum RangeType RT_Target = 2 }; +// Casting style (in enchanting) +enum Type +{ + CS_CastOnce = 0, + CS_WhenStrikes = 1, + CS_WhenUsed = 2, + CS_ConstantEffect = 3 +}; + #pragma pack(push) #pragma pack(1)