diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e8daaf4ffd..dd879305d9 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1123,7 +1123,7 @@ namespace MWClass return cast.cast(id); } - void Npc::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const + void Npc::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const { MWMechanics::NpcStats& stats = getNpcStats (ptr); @@ -1137,7 +1137,7 @@ namespace MWClass ref->mBase->mClass ); - stats.useSkill (skill, *class_, usageType); + stats.useSkill (skill, *class_, usageType, extraFactor); } float Npc::getArmorRating (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 71e34e498f..05594a530d 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -136,7 +136,7 @@ namespace MWClass virtual void adjustScale (const MWWorld::Ptr &ptr, float &scale) const; - virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const; + virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor=1.f) const; ///< Inform actor \a ptr that a skill use has succeeded. virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const; diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 00f812c110..3d888e4684 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -324,12 +324,12 @@ namespace MWGui const MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr); const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player); - float a1 = std::min(player.getClass().getSkill(player, ESM::Skill::Mercantile), 100); - float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); - float c1 = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); - float d1 = std::min(mPtr.getClass().getSkill(mPtr, ESM::Skill::Mercantile), 100); - float e1 = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); - float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); + float a1 = player.getClass().getSkill(player, ESM::Skill::Mercantile); + float b1 = 0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(); + float c1 = 0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(); + float d1 = mPtr.getClass().getSkill(mPtr, ESM::Skill::Mercantile); + float e1 = 0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(); + float f1 = 0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(); float pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm(); float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm(); @@ -352,7 +352,15 @@ namespace MWGui } //skill use! - player.getClass().skillUsageSucceeded(player, ESM::Skill::Mercantile, 0); + float skillGain = 0.f; + int finalPrice = std::abs(mCurrentBalance); + int initialMerchantOffer = std::abs(mCurrentMerchantOffer); + if (!buying && (finalPrice > initialMerchantOffer) && finalPrice > 0) + skillGain = int(100 * (finalPrice - initialMerchantOffer) / float(finalPrice)); + else if (buying && (finalPrice < initialMerchantOffer) && initialMerchantOffer > 0) + skillGain = int(100 * (initialMerchantOffer - finalPrice) / float(initialMerchantOffer)); + + player.getClass().skillUsageSucceeded(player, ESM::Skill::Mercantile, 0, skillGain); } int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt(); diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 87fb835a77..370c47b1f9 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -107,7 +107,7 @@ bool MWMechanics::NpcStats::isSameFaction (const NpcStats& npcStats) const } float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& class_, int usageType, - int level) const + int level, float extraFactor) const { if (level<0) level = static_cast (getSkill (skillIndex).getBase()); @@ -131,6 +131,8 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla return 0; } + skillFactor *= extraFactor; + const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); @@ -167,7 +169,7 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla return 1.0 / ((level+1) * (1.0/skillFactor) * typeFactor * specialisationFactor); } -void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType) +void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType, float extraFactor) { // Don't increase skills as a werewolf if(mIsWerewolf) @@ -175,7 +177,7 @@ void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, MWMechanics::SkillValue& value = getSkill (skillIndex); - value.setProgress(value.getProgress() + getSkillGain (skillIndex, class_, usageType)); + value.setProgress(value.getProgress() + getSkillGain (skillIndex, class_, usageType, -1, extraFactor)); if (value.getProgress()>=1) { diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 406db7762c..4ea5d45786 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -81,12 +81,12 @@ namespace MWMechanics ///< Do *this and \a npcStats share a faction? float getSkillGain (int skillIndex, const ESM::Class& class_, int usageType = -1, - int level = -1) const; + int level = -1, float extraFactor=1.f) const; ///< \param usageType: Usage specific factor, specified in the respective skill record; /// -1: use a factor of 1.0 instead. /// \param level Level to base calculation on; -1: use current level. - void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1); + void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1, float extraFactor=1.f); ///< Increase skill by usage. void increaseSkill (int skillIndex, const ESM::Class& class_, bool preserveProgress); diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 59fc86d0d6..c0654a7f4e 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -52,7 +52,7 @@ namespace MWWorld return false; } - void Class::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const + void Class::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const { throw std::runtime_error ("class does not represent an actor"); } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 64e83179d4..5d9c0a0ead 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -231,7 +231,7 @@ namespace MWWorld /// /// (default implementation: ignore and return false) - virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const; + virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor=1.f) const; ///< Inform actor \a ptr that a skill use has succeeded. /// /// (default implementations: throws an exception)