mirror of
https://github.com/OpenMW/openmw.git
synced 2025-12-13 01:43:08 +00:00
Merge branch 'stats' into 'master'
Remove weirdness surrounding AI- and Dynamic stats Closes #6599 See merge request OpenMW/openmw!1645
This commit is contained in:
commit
2a7d28712f
13 changed files with 63 additions and 252 deletions
|
|
@ -257,11 +257,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
||||||
case SelectWrapper::Function_PcHealthPercent:
|
case SelectWrapper::Function_PcHealthPercent:
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||||
|
return select.selectCompare(static_cast<int>(player.getClass().getCreatureStats(player).getHealth().getRatio() * 100));
|
||||||
float ratio = player.getClass().getCreatureStats (player).getHealth().getCurrent() /
|
|
||||||
player.getClass().getCreatureStats (player).getHealth().getModified();
|
|
||||||
|
|
||||||
return select.selectCompare (static_cast<int>(ratio*100));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case SelectWrapper::Function_PcDynamicStat:
|
case SelectWrapper::Function_PcDynamicStat:
|
||||||
|
|
@ -276,10 +272,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
||||||
|
|
||||||
case SelectWrapper::Function_HealthPercent:
|
case SelectWrapper::Function_HealthPercent:
|
||||||
{
|
{
|
||||||
float ratio = mActor.getClass().getCreatureStats (mActor).getHealth().getCurrent() /
|
return select.selectCompare(static_cast<int>(mActor.getClass().getCreatureStats(mActor).getHealth().getRatio() * 100));
|
||||||
mActor.getClass().getCreatureStats (mActor).getHealth().getModified();
|
|
||||||
|
|
||||||
return select.selectCompare (static_cast<int>(ratio*100));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -608,7 +608,7 @@ namespace MWGui
|
||||||
mEnemyHealth->setProgressRange(100);
|
mEnemyHealth->setProgressRange(100);
|
||||||
// Health is usually cast to int before displaying. Actors die whenever they are < 1 health.
|
// Health is usually cast to int before displaying. Actors die whenever they are < 1 health.
|
||||||
// Therefore any value < 1 should show as an empty health bar. We do the same in statswindow :)
|
// Therefore any value < 1 should show as an empty health bar. We do the same in statswindow :)
|
||||||
mEnemyHealth->setProgressPosition(static_cast<size_t>(stats.getHealth().getCurrent() / stats.getHealth().getModified() * 100));
|
mEnemyHealth->setProgressPosition(static_cast<size_t>(stats.getHealth().getRatio() * 100));
|
||||||
|
|
||||||
static const float fNPCHealthBarFade = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fNPCHealthBarFade")->mValue.getFloat();
|
static const float fNPCHealthBarFade = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fNPCHealthBarFade")->mValue.getFloat();
|
||||||
if (fNPCHealthBarFade > 0.f)
|
if (fNPCHealthBarFade > 0.f)
|
||||||
|
|
|
||||||
|
|
@ -399,7 +399,7 @@ namespace MWGui
|
||||||
skillWidget = mSkillList->createWidget<Widgets::MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default,
|
skillWidget = mSkillList->createWidget<Widgets::MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default,
|
||||||
std::string("Skill") + MyGUI::utility::toString(i));
|
std::string("Skill") + MyGUI::utility::toString(i));
|
||||||
skillWidget->setSkillNumber(skillId);
|
skillWidget->setSkillNumber(skillId);
|
||||||
skillWidget->setSkillValue(Widgets::MWSkill::SkillValue(static_cast<float>(race->mData.mBonus[i].mBonus)));
|
skillWidget->setSkillValue(Widgets::MWSkill::SkillValue(static_cast<float>(race->mData.mBonus[i].mBonus), 0.f));
|
||||||
ToolTips::createSkillToolTip(skillWidget, skillId);
|
ToolTips::createSkillToolTip(skillWidget, skillId);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ namespace MWGui
|
||||||
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
int current = static_cast<int>(value.getCurrent());
|
int current = static_cast<int>(value.getCurrent());
|
||||||
int modified = static_cast<int>(value.getModified());
|
int modified = static_cast<int>(value.getModified(false));
|
||||||
|
|
||||||
// Fatigue can be negative
|
// Fatigue can be negative
|
||||||
if (id != "FBar")
|
if (id != "FBar")
|
||||||
|
|
|
||||||
|
|
@ -181,8 +181,6 @@ namespace MWGui
|
||||||
public:
|
public:
|
||||||
MWSpell();
|
MWSpell();
|
||||||
|
|
||||||
typedef MWMechanics::Stat<int> SpellValue;
|
|
||||||
|
|
||||||
void setSpellId(const std::string &id);
|
void setSpellId(const std::string &id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -215,8 +213,6 @@ namespace MWGui
|
||||||
public:
|
public:
|
||||||
MWEffectList();
|
MWEffectList();
|
||||||
|
|
||||||
typedef MWMechanics::Stat<int> EnchantmentValue;
|
|
||||||
|
|
||||||
enum EffectFlags
|
enum EffectFlags
|
||||||
{
|
{
|
||||||
EF_NoTarget = 0x01, // potions have no target (target is always the player)
|
EF_NoTarget = 0x01, // potions have no target (target is always the player)
|
||||||
|
|
|
||||||
|
|
@ -476,8 +476,7 @@ namespace MWMechanics
|
||||||
static const float fAIFleeHealthMult = gmst.find("fAIFleeHealthMult")->mValue.getFloat();
|
static const float fAIFleeHealthMult = gmst.find("fAIFleeHealthMult")->mValue.getFloat();
|
||||||
static const float fAIFleeFleeMult = gmst.find("fAIFleeFleeMult")->mValue.getFloat();
|
static const float fAIFleeFleeMult = gmst.find("fAIFleeFleeMult")->mValue.getFloat();
|
||||||
|
|
||||||
float healthPercentage = (stats.getHealth().getModified() == 0.0f)
|
float healthPercentage = stats.getHealth().getRatio(false);
|
||||||
? 1.0f : stats.getHealth().getCurrent() / stats.getHealth().getModified();
|
|
||||||
float rating = (1.0f - healthPercentage) * fAIFleeHealthMult + flee * fAIFleeFleeMult;
|
float rating = (1.0f - healthPercentage) * fAIFleeHealthMult + flee * fAIFleeFleeMult;
|
||||||
|
|
||||||
static const int iWereWolfLevelToAttack = gmst.find("iWereWolfLevelToAttack")->mValue.getInteger();
|
static const int iWereWolfLevelToAttack = gmst.find("iWereWolfLevelToAttack")->mValue.getInteger();
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,6 @@ namespace MWMechanics
|
||||||
mDeathAnimation(-1), mTimeOfDeath(), mSideMovementAngle(0), mLevel (0)
|
mDeathAnimation(-1), mTimeOfDeath(), mSideMovementAngle(0), mLevel (0)
|
||||||
, mAttackingOrSpell(false)
|
, mAttackingOrSpell(false)
|
||||||
{
|
{
|
||||||
for (int i=0; i<4; ++i)
|
|
||||||
mAiSettings[i] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const AiSequence& CreatureStats::getAiSequence() const
|
const AiSequence& CreatureStats::getAiSequence() const
|
||||||
|
|
@ -158,9 +156,8 @@ namespace MWMechanics
|
||||||
float agility = getAttribute(ESM::Attribute::Agility).getModified();
|
float agility = getAttribute(ESM::Attribute::Agility).getModified();
|
||||||
float endurance = getAttribute(ESM::Attribute::Endurance).getModified();
|
float endurance = getAttribute(ESM::Attribute::Endurance).getModified();
|
||||||
DynamicStat<float> fatigue = getFatigue();
|
DynamicStat<float> fatigue = getFatigue();
|
||||||
float diff = (strength+willpower+agility+endurance) - fatigue.getBase();
|
|
||||||
float currentToBaseRatio = fatigue.getBase() > 0 ? (fatigue.getCurrent() / fatigue.getBase()) : 0;
|
float currentToBaseRatio = fatigue.getBase() > 0 ? (fatigue.getCurrent() / fatigue.getBase()) : 0;
|
||||||
fatigue.setModified(fatigue.getModified() + diff, 0);
|
fatigue.setBase(std::max(0.f, strength + willpower + agility + endurance));
|
||||||
fatigue.setCurrent(fatigue.getBase() * currentToBaseRatio, false, true);
|
fatigue.setCurrent(fatigue.getBase() * currentToBaseRatio, false, true);
|
||||||
setFatigue(fatigue);
|
setFatigue(fatigue);
|
||||||
}
|
}
|
||||||
|
|
@ -196,8 +193,6 @@ namespace MWMechanics
|
||||||
|
|
||||||
mDead = true;
|
mDead = true;
|
||||||
|
|
||||||
mDynamic[index].setModifier(0);
|
|
||||||
mDynamic[index].setCurrentModifier(0);
|
|
||||||
mDynamic[index].setCurrent(0);
|
mDynamic[index].setCurrent(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -281,10 +276,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
if (mDead)
|
if (mDead)
|
||||||
{
|
{
|
||||||
if (mDynamic[0].getModified() < 1)
|
mDynamic[0].setCurrent(mDynamic[0].getBase());
|
||||||
mDynamic[0].setModified(1, 0);
|
|
||||||
|
|
||||||
mDynamic[0].setCurrent(mDynamic[0].getModified());
|
|
||||||
mDead = false;
|
mDead = false;
|
||||||
mDeathAnimationFinished = false;
|
mDeathAnimationFinished = false;
|
||||||
}
|
}
|
||||||
|
|
@ -415,9 +407,8 @@ namespace MWMechanics
|
||||||
double magickaFactor = base + mMagicEffects.get(EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1;
|
double magickaFactor = base + mMagicEffects.get(EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1;
|
||||||
|
|
||||||
DynamicStat<float> magicka = getMagicka();
|
DynamicStat<float> magicka = getMagicka();
|
||||||
float diff = (static_cast<int>(magickaFactor*intelligence)) - magicka.getBase();
|
|
||||||
float currentToBaseRatio = magicka.getBase() > 0 ? magicka.getCurrent() / magicka.getBase() : 0;
|
float currentToBaseRatio = magicka.getBase() > 0 ? magicka.getCurrent() / magicka.getBase() : 0;
|
||||||
magicka.setModified(magicka.getModified() + diff, 0);
|
magicka.setBase(magickaFactor * intelligence);
|
||||||
magicka.setCurrent(magicka.getBase() * currentToBaseRatio, false, true);
|
magicka.setCurrent(magicka.getBase() * currentToBaseRatio, false, true);
|
||||||
setMagicka(magicka);
|
setMagicka(magicka);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1450,7 +1450,7 @@ namespace MWMechanics
|
||||||
std::string script = target.getClass().getScript(target);
|
std::string script = target.getClass().getScript(target);
|
||||||
if (!script.empty() && target.getRefData().getLocals().hasVar(script, "onpchitme") && attacker == player)
|
if (!script.empty() && target.getRefData().getLocals().hasVar(script, "onpchitme") && attacker == player)
|
||||||
{
|
{
|
||||||
int fight = std::max(0, target.getClass().getCreatureStats(target).getAiSetting(CreatureStats::AI_Fight).getModified());
|
int fight = target.getClass().getCreatureStats(target).getAiSetting(CreatureStats::AI_Fight).getModified();
|
||||||
peaceful = (fight == 0);
|
peaceful = (fight == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,7 @@ namespace
|
||||||
auto& creatureStats = target.getClass().getCreatureStats(target);
|
auto& creatureStats = target.getClass().getCreatureStats(target);
|
||||||
auto stat = creatureStats.getDynamic(index);
|
auto stat = creatureStats.getDynamic(index);
|
||||||
float current = stat.getCurrent();
|
float current = stat.getCurrent();
|
||||||
stat.setModified(stat.getModified() + magnitude, 0);
|
stat.setBase(std::max(0.f, stat.getBase() + magnitude));
|
||||||
stat.setCurrentModified(stat.getCurrentModified() + magnitude);
|
|
||||||
stat.setCurrent(current + magnitude);
|
stat.setCurrent(current + magnitude);
|
||||||
creatureStats.setDynamic(index, stat);
|
creatureStats.setDynamic(index, stat);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,174 +5,41 @@
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Stat<T>::Stat() : mBase (0), mModified (0), mCurrentModified (0) {}
|
Stat<T>::Stat() : mBase (0), mModifier (0) {}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Stat<T>::Stat(T base) : mBase (base), mModified (base), mCurrentModified (base) {}
|
Stat<T>::Stat(T base, T modified) : mBase (base), mModifier (modified) {}
|
||||||
template<typename T>
|
|
||||||
Stat<T>::Stat(T base, T modified) : mBase (base), mModified (modified), mCurrentModified (modified) {}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const T& Stat<T>::getBase() const
|
|
||||||
{
|
|
||||||
return mBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T Stat<T>::getModified(bool capped) const
|
T Stat<T>::getModified(bool capped) const
|
||||||
{
|
{
|
||||||
if(!capped)
|
if(capped)
|
||||||
return mModified;
|
return std::max({}, mModifier + mBase);
|
||||||
return std::max(static_cast<T>(0), mModified);
|
return mModifier + mBase;
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T Stat<T>::getCurrentModified() const
|
|
||||||
{
|
|
||||||
return mCurrentModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T Stat<T>::getModifier() const
|
|
||||||
{
|
|
||||||
return mModified-mBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T Stat<T>::getCurrentModifier() const
|
|
||||||
{
|
|
||||||
return mCurrentModified - mModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void Stat<T>::set (const T& value)
|
|
||||||
{
|
|
||||||
T diff = value - mBase;
|
|
||||||
mBase = mModified = value;
|
|
||||||
mCurrentModified += diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void Stat<T>::setBase (const T& value)
|
|
||||||
{
|
|
||||||
T diff = value - mBase;
|
|
||||||
mBase = value;
|
|
||||||
mModified += diff;
|
|
||||||
mCurrentModified += diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void Stat<T>::setModified (T value, const T& min, const T& max)
|
|
||||||
{
|
|
||||||
T diff = value - mModified;
|
|
||||||
|
|
||||||
if (mBase+diff<min)
|
|
||||||
{
|
|
||||||
value = min + (mModified - mBase);
|
|
||||||
diff = value - mModified;
|
|
||||||
}
|
|
||||||
else if (mBase+diff>max)
|
|
||||||
{
|
|
||||||
value = max + (mModified - mBase);
|
|
||||||
diff = value - mModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
mModified = value;
|
|
||||||
mBase += diff;
|
|
||||||
mCurrentModified += diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void Stat<T>::setCurrentModified(T value)
|
|
||||||
{
|
|
||||||
mCurrentModified = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void Stat<T>::setModifier (const T& modifier)
|
|
||||||
{
|
|
||||||
mModified = mBase + modifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void Stat<T>::setCurrentModifier(const T& modifier)
|
|
||||||
{
|
|
||||||
mCurrentModified = mModified + modifier;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void Stat<T>::writeState (ESM::StatState<T>& state) const
|
void Stat<T>::writeState (ESM::StatState<T>& state) const
|
||||||
{
|
{
|
||||||
state.mBase = mBase;
|
state.mBase = mBase;
|
||||||
state.mMod = mCurrentModified;
|
state.mMod = mModifier;
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void Stat<T>::readState (const ESM::StatState<T>& state)
|
void Stat<T>::readState (const ESM::StatState<T>& state)
|
||||||
{
|
{
|
||||||
mBase = state.mBase;
|
mBase = state.mBase;
|
||||||
mModified = state.mBase;
|
mModifier = state.mMod;
|
||||||
mCurrentModified = state.mMod;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
DynamicStat<T>::DynamicStat() : mStatic (0), mCurrent (0) {}
|
DynamicStat<T>::DynamicStat() : mStatic(0, 0), mCurrent(0) {}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
DynamicStat<T>::DynamicStat(T base) : mStatic (base), mCurrent (base) {}
|
DynamicStat<T>::DynamicStat(T base) : mStatic(base, 0), mCurrent(base) {}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
DynamicStat<T>::DynamicStat(T base, T modified, T current) : mStatic(base, modified), mCurrent (current) {}
|
DynamicStat<T>::DynamicStat(T base, T modified, T current) : mStatic(base, modified), mCurrent (current) {}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
DynamicStat<T>::DynamicStat(const Stat<T> &stat, T current) : mStatic(stat), mCurrent (current) {}
|
DynamicStat<T>::DynamicStat(const Stat<T> &stat, T current) : mStatic(stat), mCurrent (current) {}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const T& DynamicStat<T>::getBase() const
|
|
||||||
{
|
|
||||||
return mStatic.getBase();
|
|
||||||
}
|
|
||||||
template<typename T>
|
|
||||||
T DynamicStat<T>::getModified() const
|
|
||||||
{
|
|
||||||
return mStatic.getModified();
|
|
||||||
}
|
|
||||||
template<typename T>
|
|
||||||
T DynamicStat<T>::getCurrentModified() const
|
|
||||||
{
|
|
||||||
return mStatic.getCurrentModified();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const T& DynamicStat<T>::getCurrent() const
|
|
||||||
{
|
|
||||||
return mCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void DynamicStat<T>::set (const T& value)
|
|
||||||
{
|
|
||||||
mStatic.set (value);
|
|
||||||
mCurrent = value;
|
|
||||||
}
|
|
||||||
template<typename T>
|
|
||||||
void DynamicStat<T>::setBase (const T& value)
|
|
||||||
{
|
|
||||||
mStatic.setBase (value);
|
|
||||||
|
|
||||||
if (mCurrent>getModified())
|
|
||||||
mCurrent = getModified();
|
|
||||||
}
|
|
||||||
template<typename T>
|
|
||||||
void DynamicStat<T>::setModified (T value, const T& min, const T& max)
|
|
||||||
{
|
|
||||||
mStatic.setModified (value, min, max);
|
|
||||||
|
|
||||||
if (mCurrent>getModified())
|
|
||||||
mCurrent = getModified();
|
|
||||||
}
|
|
||||||
template<typename T>
|
|
||||||
void DynamicStat<T>::setCurrentModified(T value)
|
|
||||||
{
|
|
||||||
mStatic.setCurrentModified(value);
|
|
||||||
}
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void DynamicStat<T>::setCurrent (const T& value, bool allowDecreaseBelowZero, bool allowIncreaseAboveModified)
|
void DynamicStat<T>::setCurrent (const T& value, bool allowDecreaseBelowZero, bool allowIncreaseAboveModified)
|
||||||
{
|
{
|
||||||
|
|
@ -197,22 +64,18 @@ namespace MWMechanics
|
||||||
mCurrent = 0;
|
mCurrent = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T>
|
|
||||||
void DynamicStat<T>::setModifier (const T& modifier, bool allowCurrentDecreaseBelowZero)
|
|
||||||
{
|
|
||||||
T diff = modifier - mStatic.getModifier();
|
|
||||||
mStatic.setModifier (modifier);
|
|
||||||
setCurrent (getCurrent()+diff, allowCurrentDecreaseBelowZero);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void DynamicStat<T>::setCurrentModifier(const T& modifier, bool allowCurrentDecreaseBelowZero)
|
T DynamicStat<T>::getRatio(bool nanIsZero) const
|
||||||
{
|
{
|
||||||
T diff = modifier - mStatic.getCurrentModifier();
|
T modified = getModified();
|
||||||
mStatic.setCurrentModifier(modifier);
|
if(modified == T{})
|
||||||
|
{
|
||||||
// The (modifier > 0) check here allows increase over modified only if the modifier is positive (a fortify effect is active).
|
if(nanIsZero)
|
||||||
setCurrent (getCurrent() + diff, allowCurrentDecreaseBelowZero, (modifier > 0));
|
return modified;
|
||||||
|
return {1};
|
||||||
|
}
|
||||||
|
return getCurrent() / modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
||||||
|
|
@ -16,38 +16,22 @@ namespace MWMechanics
|
||||||
class Stat
|
class Stat
|
||||||
{
|
{
|
||||||
T mBase;
|
T mBase;
|
||||||
T mModified;
|
T mModifier;
|
||||||
T mCurrentModified;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef T Type;
|
typedef T Type;
|
||||||
|
|
||||||
Stat();
|
Stat();
|
||||||
Stat(T base);
|
|
||||||
Stat(T base, T modified);
|
Stat(T base, T modified);
|
||||||
|
|
||||||
const T& getBase() const;
|
const T& getBase() const { return mBase; };
|
||||||
|
|
||||||
T getModified(bool capped = true) const;
|
T getModified(bool capped = true) const;
|
||||||
T getCurrentModified() const;
|
T getModifier() const { return mModifier; };
|
||||||
T getModifier() const;
|
|
||||||
T getCurrentModifier() const;
|
|
||||||
|
|
||||||
/// Set base and modified to \a value.
|
void setBase(const T& value) { mBase = value; };
|
||||||
void set (const T& value);
|
|
||||||
|
|
||||||
/// Set base and adjust modified accordingly.
|
void setModifier(const T& modifier) { mModifier = modifier; };
|
||||||
void setBase (const T& value);
|
|
||||||
|
|
||||||
/// Set modified value and adjust base accordingly.
|
|
||||||
void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max());
|
|
||||||
|
|
||||||
/// Set "current modified," used for drain and fortify. Unlike the regular modifier
|
|
||||||
/// this just adds and subtracts from the current value without changing the maximum.
|
|
||||||
void setCurrentModified(T value);
|
|
||||||
|
|
||||||
void setModifier (const T& modifier);
|
|
||||||
void setCurrentModifier (const T& modifier);
|
|
||||||
|
|
||||||
void writeState (ESM::StatState<T>& state) const;
|
void writeState (ESM::StatState<T>& state) const;
|
||||||
void readState (const ESM::StatState<T>& state);
|
void readState (const ESM::StatState<T>& state);
|
||||||
|
|
@ -57,7 +41,7 @@ namespace MWMechanics
|
||||||
inline bool operator== (const Stat<T>& left, const Stat<T>& right)
|
inline bool operator== (const Stat<T>& left, const Stat<T>& right)
|
||||||
{
|
{
|
||||||
return left.getBase()==right.getBase() &&
|
return left.getBase()==right.getBase() &&
|
||||||
left.getModified()==right.getModified();
|
left.getModifier()==right.getModifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
@ -80,27 +64,18 @@ namespace MWMechanics
|
||||||
DynamicStat(T base, T modified, T current);
|
DynamicStat(T base, T modified, T current);
|
||||||
DynamicStat(const Stat<T> &stat, T current);
|
DynamicStat(const Stat<T> &stat, T current);
|
||||||
|
|
||||||
const T& getBase() const;
|
const T& getBase() const { return mStatic.getBase(); };
|
||||||
T getModified() const;
|
T getModified(bool capped = true) const { return mStatic.getModified(capped); };
|
||||||
T getCurrentModified() const;
|
const T& getCurrent() const { return mCurrent; };
|
||||||
const T& getCurrent() const;
|
T getRatio(bool nanIsZero = true) const;
|
||||||
|
|
||||||
/// Set base, modified and current to \a value.
|
/// Set base and adjust current accordingly.
|
||||||
void set (const T& value);
|
void setBase(const T& value) { mStatic.setBase(value); };
|
||||||
|
|
||||||
/// Set base and adjust modified accordingly.
|
|
||||||
void setBase (const T& value);
|
|
||||||
|
|
||||||
/// Set modified value and adjust base accordingly.
|
|
||||||
void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max());
|
|
||||||
|
|
||||||
/// Set "current modified," used for drain and fortify. Unlike the regular modifier
|
|
||||||
/// this just adds and subtracts from the current value without changing the maximum.
|
|
||||||
void setCurrentModified(T value);
|
|
||||||
|
|
||||||
void setCurrent (const T& value, bool allowDecreaseBelowZero = false, bool allowIncreaseAboveModified = false);
|
void setCurrent (const T& value, bool allowDecreaseBelowZero = false, bool allowIncreaseAboveModified = false);
|
||||||
void setModifier (const T& modifier, bool allowCurrentToDecreaseBelowZero=false);
|
|
||||||
void setCurrentModifier (const T& modifier, bool allowCurrentToDecreaseBelowZero = false);
|
T getModifier() const { return mStatic.getModifier(); }
|
||||||
|
void setModifier(T value) { mStatic.setModifier(value); }
|
||||||
|
|
||||||
void writeState (ESM::StatState<T>& state) const;
|
void writeState (ESM::StatState<T>& state) const;
|
||||||
void readState (const ESM::StatState<T>& state);
|
void readState (const ESM::StatState<T>& state);
|
||||||
|
|
@ -110,7 +85,7 @@ namespace MWMechanics
|
||||||
inline bool operator== (const DynamicStat<T>& left, const DynamicStat<T>& right)
|
inline bool operator== (const DynamicStat<T>& left, const DynamicStat<T>& right)
|
||||||
{
|
{
|
||||||
return left.getBase()==right.getBase() &&
|
return left.getBase()==right.getBase() &&
|
||||||
left.getModified()==right.getModified() &&
|
left.getModifier()==right.getModifier() &&
|
||||||
left.getCurrent()==right.getCurrent();
|
left.getCurrent()==right.getCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -218,8 +218,8 @@ namespace MWScript
|
||||||
MWMechanics::DynamicStat<float> stat (ptr.getClass().getCreatureStats (ptr)
|
MWMechanics::DynamicStat<float> stat (ptr.getClass().getCreatureStats (ptr)
|
||||||
.getDynamic (mIndex));
|
.getDynamic (mIndex));
|
||||||
|
|
||||||
stat.setModified (value, 0);
|
stat.setBase(value);
|
||||||
stat.setCurrent(value);
|
stat.setCurrent(stat.getModified(false), true, true);
|
||||||
|
|
||||||
ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat);
|
ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat);
|
||||||
}
|
}
|
||||||
|
|
@ -259,19 +259,18 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
|
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
|
|
||||||
Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent();
|
MWMechanics::DynamicStat<float> stat = stats.getDynamic(mIndex);
|
||||||
|
|
||||||
MWMechanics::DynamicStat<float> stat (ptr.getClass().getCreatureStats (ptr)
|
float current = stat.getCurrent();
|
||||||
.getDynamic (mIndex));
|
float base = diff + stat.getBase();
|
||||||
|
if(mIndex != 2)
|
||||||
|
base = std::max(base, 0.f);
|
||||||
|
stat.setBase(base);
|
||||||
|
stat.setCurrent(diff + current, true, true);
|
||||||
|
|
||||||
stat.setModified (diff + stat.getModified(), 0);
|
stats.setDynamic (mIndex, stat);
|
||||||
stat.setCurrentModified (diff + stat.getCurrentModified());
|
|
||||||
|
|
||||||
stat.setCurrent (diff + current);
|
|
||||||
|
|
||||||
ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -325,17 +324,9 @@ namespace MWScript
|
||||||
void execute (Interpreter::Runtime& runtime) override
|
void execute (Interpreter::Runtime& runtime) override
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
|
|
||||||
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
|
runtime.push(stats.getDynamic(mIndex).getRatio());
|
||||||
|
|
||||||
Interpreter::Type_Float value = 0;
|
|
||||||
|
|
||||||
Interpreter::Type_Float max = stats.getDynamic(mIndex).getModified();
|
|
||||||
|
|
||||||
if (max>0)
|
|
||||||
value = stats.getDynamic(mIndex).getCurrent() / max;
|
|
||||||
|
|
||||||
runtime.push (value);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,11 @@ namespace MWWorld
|
||||||
for(std::size_t i = 0; i < ESM::Attribute::Length; ++i)
|
for(std::size_t i = 0; i < ESM::Attribute::Length; ++i)
|
||||||
creatureStats.mAttributes[i].mMod = 0.f;
|
creatureStats.mAttributes[i].mMod = 0.f;
|
||||||
for(std::size_t i = 0; i < 3; ++i)
|
for(std::size_t i = 0; i < 3; ++i)
|
||||||
creatureStats.mDynamic[i].mMod = 0.f;
|
{
|
||||||
|
auto& dynamic = creatureStats.mDynamic[i];
|
||||||
|
dynamic.mCurrent -= dynamic.mMod - dynamic.mBase;
|
||||||
|
dynamic.mMod = 0.f;
|
||||||
|
}
|
||||||
for(std::size_t i = 0; i < 4; ++i)
|
for(std::size_t i = 0; i < 4; ++i)
|
||||||
creatureStats.mAiSettings[i].mMod = 0.f;
|
creatureStats.mAiSettings[i].mMod = 0.f;
|
||||||
if(npcStats)
|
if(npcStats)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue