2012-07-06 13:50:26 +00:00
|
|
|
|
|
|
|
#include "npcstats.hpp"
|
|
|
|
|
2012-07-09 19:15:52 +00:00
|
|
|
#include <cmath>
|
2012-07-06 16:23:48 +00:00
|
|
|
#include <stdexcept>
|
|
|
|
|
2012-07-06 19:07:04 +00:00
|
|
|
#include <components/esm/loadskil.hpp>
|
|
|
|
#include <components/esm/loadclas.hpp>
|
|
|
|
#include <components/esm/loadgmst.hpp>
|
|
|
|
|
|
|
|
#include <components/esm_store/store.hpp>
|
|
|
|
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
#include "../mwbase/world.hpp"
|
|
|
|
|
2012-07-06 13:50:26 +00:00
|
|
|
MWMechanics::NpcStats::NpcStats()
|
2012-07-06 16:23:48 +00:00
|
|
|
: mMovementFlags (0), mDrawState (DrawState_Nothing)
|
2012-07-06 13:50:26 +00:00
|
|
|
{}
|
|
|
|
|
2012-07-07 18:53:19 +00:00
|
|
|
MWMechanics::DrawState_ MWMechanics::NpcStats::getDrawState() const
|
2012-07-06 13:50:26 +00:00
|
|
|
{
|
|
|
|
return mDrawState;
|
|
|
|
}
|
|
|
|
|
2012-07-07 18:53:19 +00:00
|
|
|
void MWMechanics::NpcStats::setDrawState (DrawState_ state)
|
2012-07-06 13:50:26 +00:00
|
|
|
{
|
|
|
|
mDrawState = state;
|
|
|
|
}
|
2012-07-06 16:23:48 +00:00
|
|
|
|
|
|
|
bool MWMechanics::NpcStats::getMovementFlag (Flag flag) const
|
|
|
|
{
|
|
|
|
return mMovementFlags & flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MWMechanics::NpcStats::setMovementFlag (Flag flag, bool state)
|
|
|
|
{
|
|
|
|
if (state)
|
|
|
|
mMovementFlags |= flag;
|
|
|
|
else
|
|
|
|
mMovementFlags &= ~flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
const MWMechanics::Stat<float>& MWMechanics::NpcStats::getSkill (int index) const
|
|
|
|
{
|
|
|
|
if (index<0 || index>=27)
|
|
|
|
throw std::runtime_error ("skill index out of range");
|
|
|
|
|
|
|
|
return mSkill[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
MWMechanics::Stat<float>& MWMechanics::NpcStats::getSkill (int index)
|
|
|
|
{
|
|
|
|
if (index<0 || index>=27)
|
|
|
|
throw std::runtime_error ("skill index out of range");
|
|
|
|
|
|
|
|
return mSkill[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
std::map<std::string, int>& MWMechanics::NpcStats::getFactionRanks()
|
|
|
|
{
|
|
|
|
return mFactionRank;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::map<std::string, int>& MWMechanics::NpcStats::getFactionRanks() const
|
|
|
|
{
|
|
|
|
return mFactionRank;
|
|
|
|
}
|
2012-07-06 19:07:04 +00:00
|
|
|
|
|
|
|
float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& class_, int usageType,
|
|
|
|
int level) const
|
|
|
|
{
|
|
|
|
if (level<0)
|
|
|
|
level = static_cast<int> (getSkill (skillIndex).getBase());
|
|
|
|
|
|
|
|
const ESM::Skill *skill = MWBase::Environment::get().getWorld()->getStore().skills.find (skillIndex);
|
|
|
|
|
|
|
|
float skillFactor = 1;
|
|
|
|
|
|
|
|
if (usageType>=4)
|
|
|
|
throw std::runtime_error ("skill usage type out of range");
|
|
|
|
|
|
|
|
if (usageType>0)
|
|
|
|
{
|
2012-09-17 07:37:50 +00:00
|
|
|
skillFactor = skill->mData.mUseValue[usageType];
|
2012-07-06 19:07:04 +00:00
|
|
|
|
|
|
|
if (skillFactor<=0)
|
|
|
|
throw std::runtime_error ("invalid skill gain factor");
|
|
|
|
}
|
|
|
|
|
|
|
|
float typeFactor =
|
2012-09-17 07:37:50 +00:00
|
|
|
MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMiscSkillBonus")->mF;
|
2012-07-06 19:07:04 +00:00
|
|
|
|
|
|
|
for (int i=0; i<5; ++i)
|
2012-09-17 07:37:50 +00:00
|
|
|
if (class_.mData.mSkills[i][0]==skillIndex)
|
2012-07-06 19:07:04 +00:00
|
|
|
{
|
|
|
|
typeFactor =
|
2012-09-17 07:37:50 +00:00
|
|
|
MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMinorSkillBonus")->mF;
|
2012-07-06 19:07:04 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i=0; i<5; ++i)
|
2012-09-17 07:37:50 +00:00
|
|
|
if (class_.mData.mSkills[i][1]==skillIndex)
|
2012-07-06 19:07:04 +00:00
|
|
|
{
|
|
|
|
typeFactor =
|
2012-09-17 07:37:50 +00:00
|
|
|
MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMajorSkillBonus")->mF;
|
2012-07-06 19:07:04 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeFactor<=0)
|
|
|
|
throw std::runtime_error ("invalid skill type factor");
|
|
|
|
|
|
|
|
float specialisationFactor = 1;
|
|
|
|
|
2012-09-17 07:37:50 +00:00
|
|
|
if (skill->mData.mSpecialization==class_.mData.mSpecialization)
|
2012-07-06 19:07:04 +00:00
|
|
|
{
|
|
|
|
specialisationFactor =
|
2012-09-17 07:37:50 +00:00
|
|
|
MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fSpecialSkillBonus")->mF;
|
2012-07-06 19:07:04 +00:00
|
|
|
|
|
|
|
if (specialisationFactor<=0)
|
|
|
|
throw std::runtime_error ("invalid skill specialisation factor");
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1.0 / (level +1) * (1.0 / skillFactor) * typeFactor * specialisationFactor;
|
|
|
|
}
|
2012-07-09 19:15:52 +00:00
|
|
|
|
|
|
|
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType)
|
|
|
|
{
|
|
|
|
float base = getSkill (skillIndex).getBase();
|
|
|
|
|
|
|
|
int level = static_cast<int> (base);
|
|
|
|
|
|
|
|
base += getSkillGain (skillIndex, class_, usageType);
|
|
|
|
|
|
|
|
if (static_cast<int> (base)!=level)
|
|
|
|
base = level+1;
|
|
|
|
|
|
|
|
getSkill (skillIndex).setBase (base);
|
|
|
|
}
|