2014-02-16 15:06:34 +01:00
|
|
|
#include "stat.hpp"
|
|
|
|
|
2023-04-30 16:16:56 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
2022-01-22 15:58:41 +01:00
|
|
|
#include <components/esm3/statstate.hpp>
|
2014-02-16 15:06:34 +01:00
|
|
|
|
2015-07-09 14:41:37 +02:00
|
|
|
namespace MWMechanics
|
2014-02-16 15:06:34 +01:00
|
|
|
{
|
2015-07-09 14:41:37 +02:00
|
|
|
template <typename T>
|
2022-02-10 20:32:59 +01:00
|
|
|
Stat<T>::Stat()
|
|
|
|
: mBase(0)
|
|
|
|
, mModifier(0)
|
|
|
|
{
|
|
|
|
}
|
2015-07-09 14:41:37 +02:00
|
|
|
template <typename T>
|
2022-02-10 20:32:59 +01:00
|
|
|
Stat<T>::Stat(T base, T modified)
|
|
|
|
: mBase(base)
|
|
|
|
, mModifier(modified)
|
|
|
|
{
|
|
|
|
}
|
2014-02-16 15:06:34 +01:00
|
|
|
|
2015-07-09 14:41:37 +02:00
|
|
|
template <typename T>
|
2021-02-04 21:25:38 +01:00
|
|
|
T Stat<T>::getModified(bool capped) const
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
2022-02-10 20:32:59 +01:00
|
|
|
if (capped)
|
|
|
|
return std::max({}, mModifier + mBase);
|
|
|
|
return mModifier + mBase;
|
2016-11-24 00:58:30 +09:00
|
|
|
}
|
|
|
|
|
2015-07-09 14:41:37 +02:00
|
|
|
template <typename T>
|
|
|
|
void Stat<T>::writeState(ESM::StatState<T>& state) const
|
|
|
|
{
|
|
|
|
state.mBase = mBase;
|
2022-02-14 18:38:37 +01:00
|
|
|
state.mMod = mModifier;
|
2015-07-09 14:41:37 +02:00
|
|
|
}
|
|
|
|
template <typename T>
|
|
|
|
void Stat<T>::readState(const ESM::StatState<T>& state)
|
|
|
|
{
|
|
|
|
mBase = state.mBase;
|
2022-02-14 18:38:37 +01:00
|
|
|
mModifier = state.mMod;
|
2015-07-09 14:41:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2022-02-10 20:32:59 +01:00
|
|
|
DynamicStat<T>::DynamicStat()
|
|
|
|
: mStatic(0, 0)
|
|
|
|
, mCurrent(0)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
|
|
|
}
|
2016-11-24 00:58:30 +09:00
|
|
|
template <typename T>
|
2022-02-10 20:32:59 +01:00
|
|
|
DynamicStat<T>::DynamicStat(T base)
|
|
|
|
: mStatic(base, 0)
|
|
|
|
, mCurrent(base)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
|
|
|
}
|
2016-11-24 00:58:30 +09:00
|
|
|
template <typename T>
|
2015-07-09 14:41:37 +02:00
|
|
|
DynamicStat<T>::DynamicStat(T base, T modified, T current)
|
|
|
|
: mStatic(base, modified)
|
|
|
|
, mCurrent(current)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
|
|
|
}
|
2022-02-10 22:10:46 +01:00
|
|
|
template <typename T>
|
2015-07-09 14:41:37 +02:00
|
|
|
DynamicStat<T>::DynamicStat(const Stat<T>& stat, T current)
|
|
|
|
: mStatic(stat)
|
|
|
|
, mCurrent(current)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
|
|
|
}
|
2015-07-09 14:41:37 +02:00
|
|
|
|
|
|
|
template <typename T>
|
2016-11-24 00:58:30 +09:00
|
|
|
void DynamicStat<T>::setCurrent(const T& value, bool allowDecreaseBelowZero, bool allowIncreaseAboveModified)
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
|
|
|
if (value > mCurrent)
|
|
|
|
{
|
|
|
|
// increase
|
2016-11-24 00:58:30 +09:00
|
|
|
if (value <= getModified() || allowIncreaseAboveModified)
|
|
|
|
mCurrent = value;
|
|
|
|
else if (mCurrent > getModified())
|
|
|
|
return;
|
|
|
|
else
|
2015-07-09 14:41:37 +02:00
|
|
|
mCurrent = getModified();
|
|
|
|
}
|
|
|
|
else if (value > 0 || allowDecreaseBelowZero)
|
|
|
|
{
|
|
|
|
// allowed decrease
|
|
|
|
mCurrent = value;
|
|
|
|
}
|
|
|
|
else if (mCurrent > 0)
|
|
|
|
{
|
|
|
|
// capped decrease
|
|
|
|
mCurrent = 0;
|
|
|
|
}
|
|
|
|
}
|
2016-11-24 00:58:30 +09:00
|
|
|
|
2022-02-10 22:10:46 +01:00
|
|
|
template <typename T>
|
|
|
|
T DynamicStat<T>::getRatio(bool nanIsZero) const
|
|
|
|
{
|
|
|
|
T modified = getModified();
|
|
|
|
if (modified == T{})
|
|
|
|
{
|
|
|
|
if (nanIsZero)
|
|
|
|
return modified;
|
|
|
|
return { 1 };
|
|
|
|
}
|
|
|
|
return getCurrent() / modified;
|
|
|
|
}
|
|
|
|
|
2015-07-09 14:41:37 +02:00
|
|
|
template <typename T>
|
|
|
|
void DynamicStat<T>::writeState(ESM::StatState<T>& state) const
|
|
|
|
{
|
|
|
|
mStatic.writeState(state);
|
|
|
|
state.mCurrent = mCurrent;
|
|
|
|
}
|
|
|
|
template <typename T>
|
|
|
|
void DynamicStat<T>::readState(const ESM::StatState<T>& state)
|
|
|
|
{
|
|
|
|
mStatic.readState(state);
|
|
|
|
mCurrent = state.mCurrent;
|
|
|
|
}
|
|
|
|
|
|
|
|
AttributeValue::AttributeValue()
|
2018-12-23 15:18:33 +04:00
|
|
|
: mBase(0.f)
|
|
|
|
, mModifier(0.f)
|
|
|
|
, mDamage(0.f)
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-12-23 15:18:33 +04:00
|
|
|
float AttributeValue::getModified() const
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
2018-12-23 15:18:33 +04:00
|
|
|
return std::max(0.f, mBase - mDamage + mModifier);
|
2015-07-09 14:41:37 +02:00
|
|
|
}
|
2018-12-23 15:18:33 +04:00
|
|
|
float AttributeValue::getBase() const
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
|
|
|
return mBase;
|
|
|
|
}
|
2018-12-23 15:18:33 +04:00
|
|
|
float AttributeValue::getModifier() const
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
|
|
|
return mModifier;
|
|
|
|
}
|
|
|
|
|
2021-11-20 00:15:18 +01:00
|
|
|
void AttributeValue::setBase(float base, bool clearModifier)
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
2017-03-22 14:27:30 +09:00
|
|
|
mBase = base;
|
2021-11-20 00:15:18 +01:00
|
|
|
if (clearModifier)
|
|
|
|
{
|
|
|
|
mModifier = 0.f;
|
|
|
|
mDamage = 0.f;
|
|
|
|
}
|
2015-07-09 14:41:37 +02:00
|
|
|
}
|
|
|
|
|
2018-12-23 15:18:33 +04:00
|
|
|
void AttributeValue::setModifier(float mod)
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
2021-11-20 00:15:18 +01:00
|
|
|
if (mod < 0)
|
|
|
|
{
|
|
|
|
mModifier = 0.f;
|
|
|
|
mDamage -= mod;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
mModifier = mod;
|
2015-07-09 14:41:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void AttributeValue::damage(float damage)
|
|
|
|
{
|
2022-01-27 19:56:27 +01:00
|
|
|
mDamage += damage;
|
2015-07-09 14:41:37 +02:00
|
|
|
}
|
|
|
|
void AttributeValue::restore(float amount)
|
|
|
|
{
|
2019-09-30 20:27:42 +04:00
|
|
|
if (mDamage <= 0)
|
|
|
|
return;
|
|
|
|
|
2015-07-09 14:41:37 +02:00
|
|
|
mDamage -= std::min(mDamage, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
float AttributeValue::getDamage() const
|
|
|
|
{
|
|
|
|
return mDamage;
|
|
|
|
}
|
|
|
|
|
2018-12-23 15:18:33 +04:00
|
|
|
void AttributeValue::writeState(ESM::StatState<float>& state) const
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
|
|
|
state.mBase = mBase;
|
|
|
|
state.mMod = mModifier;
|
|
|
|
state.mDamage = mDamage;
|
|
|
|
}
|
|
|
|
|
2018-12-23 15:18:33 +04:00
|
|
|
void AttributeValue::readState(const ESM::StatState<float>& state)
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
|
|
|
mBase = state.mBase;
|
|
|
|
mModifier = state.mMod;
|
|
|
|
mDamage = state.mDamage;
|
|
|
|
}
|
|
|
|
|
|
|
|
SkillValue::SkillValue()
|
|
|
|
: mProgress(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
float SkillValue::getProgress() const
|
|
|
|
{
|
|
|
|
return mProgress;
|
|
|
|
}
|
|
|
|
void SkillValue::setProgress(float progress)
|
|
|
|
{
|
|
|
|
mProgress = progress;
|
|
|
|
}
|
|
|
|
|
2018-12-23 15:18:33 +04:00
|
|
|
void SkillValue::writeState(ESM::StatState<float>& state) const
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
|
|
|
AttributeValue::writeState(state);
|
|
|
|
state.mProgress = mProgress;
|
|
|
|
}
|
|
|
|
|
2018-12-23 15:18:33 +04:00
|
|
|
void SkillValue::readState(const ESM::StatState<float>& state)
|
2015-07-09 14:41:37 +02:00
|
|
|
{
|
|
|
|
AttributeValue::readState(state);
|
|
|
|
mProgress = state.mProgress;
|
|
|
|
}
|
2015-03-07 16:23:02 +01:00
|
|
|
}
|
2015-07-09 14:41:37 +02:00
|
|
|
|
|
|
|
template class MWMechanics::Stat<int>;
|
|
|
|
template class MWMechanics::Stat<float>;
|
|
|
|
template class MWMechanics::DynamicStat<int>;
|
|
|
|
template class MWMechanics::DynamicStat<float>;
|