Implement price-based mercantile skill progress (Fixes #1947), thanks Hrnchamd

Correct barter formula (removed erroneous clamping)
deque
scrawl 10 years ago
parent 1afcc7adb5
commit 40587f984d

@ -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

@ -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;

@ -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();

@ -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<int> (getSkill (skillIndex).getBase());
@ -131,6 +131,8 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla
return 0;
}
skillFactor *= extraFactor;
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
@ -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)
{

@ -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);

@ -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");
}

@ -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)

Loading…
Cancel
Save