mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-15 19:49:54 +00:00
ca8c8c6aa4
conversion from 'const float' to 'int', possible loss of data conversion from 'double' to 'int', possible loss of data conversion from 'float' to 'int', possible loss of data
301 lines
8.7 KiB
C++
301 lines
8.7 KiB
C++
#ifndef GAME_MWMECHANICS_STAT_H
|
|
#define GAME_MWMECHANICS_STAT_H
|
|
|
|
#undef min
|
|
#undef max
|
|
|
|
#include <limits>
|
|
|
|
#include <components/esm/statstate.hpp>
|
|
|
|
namespace MWMechanics
|
|
{
|
|
template<typename T>
|
|
class Stat
|
|
{
|
|
T mBase;
|
|
T mModified;
|
|
|
|
public:
|
|
typedef T Type;
|
|
|
|
Stat() : mBase (0), mModified (0) {}
|
|
Stat(T base) : mBase (base), mModified (base) {}
|
|
Stat(T base, T modified) : mBase (base), mModified (modified) {}
|
|
|
|
const T& getBase() const
|
|
{
|
|
return mBase;
|
|
}
|
|
|
|
T getModified() const
|
|
{
|
|
return std::max(static_cast<T>(0), mModified);
|
|
}
|
|
|
|
T getModifier() const
|
|
{
|
|
return mModified-mBase;
|
|
}
|
|
|
|
/// Set base and modified to \a value.
|
|
void set (const T& value)
|
|
{
|
|
mBase = mModified = value;
|
|
}
|
|
|
|
void modify(const T& diff)
|
|
{
|
|
mBase += diff;
|
|
if(mBase >= static_cast<T>(0))
|
|
mModified += diff;
|
|
else
|
|
{
|
|
mModified += diff - mBase;
|
|
mBase = static_cast<T>(0);
|
|
}
|
|
}
|
|
|
|
/// Set base and adjust modified accordingly.
|
|
void setBase (const T& value)
|
|
{
|
|
T diff = value - mBase;
|
|
mBase = value;
|
|
mModified += diff;
|
|
}
|
|
|
|
/// Set modified value an adjust base accordingly.
|
|
void setModified (T value, const T& min, const T& max = std::numeric_limits<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;
|
|
}
|
|
|
|
void setModifier (const T& modifier)
|
|
{
|
|
mModified = mBase + modifier;
|
|
}
|
|
|
|
void writeState (ESM::StatState<T>& state) const
|
|
{
|
|
state.mBase = mBase;
|
|
state.mMod = mModified;
|
|
}
|
|
|
|
void readState (const ESM::StatState<T>& state)
|
|
{
|
|
mBase = state.mBase;
|
|
mModified = state.mMod;
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
inline bool operator== (const Stat<T>& left, const Stat<T>& right)
|
|
{
|
|
return left.getBase()==right.getBase() &&
|
|
left.getModified()==right.getModified();
|
|
}
|
|
|
|
template<typename T>
|
|
inline bool operator!= (const Stat<T>& left, const Stat<T>& right)
|
|
{
|
|
return !(left==right);
|
|
}
|
|
|
|
template<typename T>
|
|
class DynamicStat
|
|
{
|
|
Stat<T> mStatic;
|
|
T mCurrent;
|
|
|
|
public:
|
|
typedef T Type;
|
|
|
|
DynamicStat() : mStatic (0), mCurrent (0) {}
|
|
DynamicStat(T base) : mStatic (base), mCurrent (base) {}
|
|
DynamicStat(T base, T modified, T current) : mStatic(base, modified), mCurrent (current) {}
|
|
DynamicStat(const Stat<T> &stat, T current) : mStatic(stat), mCurrent (current) {}
|
|
|
|
const T& getBase() const
|
|
{
|
|
return mStatic.getBase();
|
|
}
|
|
|
|
T getModified() const
|
|
{
|
|
return mStatic.getModified();
|
|
}
|
|
|
|
const T& getCurrent() const
|
|
{
|
|
return mCurrent;
|
|
}
|
|
|
|
/// Set base, modified and current to \a value.
|
|
void set (const T& value)
|
|
{
|
|
mStatic.set (value);
|
|
mCurrent = value;
|
|
}
|
|
|
|
/// Set base and adjust modified accordingly.
|
|
void setBase (const T& value)
|
|
{
|
|
mStatic.setBase (value);
|
|
|
|
if (mCurrent>getModified())
|
|
mCurrent = getModified();
|
|
}
|
|
|
|
/// Set modified value an adjust base accordingly.
|
|
void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max())
|
|
{
|
|
mStatic.setModified (value, min, max);
|
|
|
|
if (mCurrent>getModified())
|
|
mCurrent = getModified();
|
|
}
|
|
|
|
/// Change modified relatively.
|
|
void modify (const T& diff)
|
|
{
|
|
mStatic.modify (diff);
|
|
setCurrent (getCurrent()+diff);
|
|
}
|
|
|
|
void setCurrent (const T& value, bool allowDecreaseBelowZero = false)
|
|
{
|
|
if (value > mCurrent)
|
|
{
|
|
// increase
|
|
mCurrent = value;
|
|
|
|
if (mCurrent > getModified())
|
|
mCurrent = getModified();
|
|
}
|
|
else if (value > 0 || allowDecreaseBelowZero)
|
|
{
|
|
// allowed decrease
|
|
mCurrent = value;
|
|
}
|
|
else if (mCurrent > 0)
|
|
{
|
|
// capped decrease
|
|
mCurrent = 0;
|
|
}
|
|
}
|
|
|
|
void setModifier (const T& modifier)
|
|
{
|
|
T diff = modifier - mStatic.getModifier();
|
|
mStatic.setModifier (modifier);
|
|
setCurrent (getCurrent()+diff);
|
|
}
|
|
|
|
void writeState (ESM::StatState<T>& state) const
|
|
{
|
|
mStatic.writeState (state);
|
|
state.mCurrent = mCurrent;
|
|
}
|
|
|
|
void readState (const ESM::StatState<T>& state)
|
|
{
|
|
mStatic.readState (state);
|
|
mCurrent = state.mCurrent;
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
inline bool operator== (const DynamicStat<T>& left, const DynamicStat<T>& right)
|
|
{
|
|
return left.getBase()==right.getBase() &&
|
|
left.getModified()==right.getModified() &&
|
|
left.getCurrent()==right.getCurrent();
|
|
}
|
|
|
|
template<typename T>
|
|
inline bool operator!= (const DynamicStat<T>& left, const DynamicStat<T>& right)
|
|
{
|
|
return !(left==right);
|
|
}
|
|
|
|
class AttributeValue
|
|
{
|
|
int mBase;
|
|
int mFortified;
|
|
int mModifier; // net effect of Fortified, Drain & Absorb
|
|
float mDamage; // needs to be float to allow continuous damage
|
|
|
|
public:
|
|
AttributeValue() : mBase(0), mFortified(0), mModifier(0), mDamage(0) {}
|
|
|
|
int getModified() const { return std::max(0, mBase - (int) mDamage + mModifier); }
|
|
int getBase() const { return mBase; }
|
|
int getModifier() const { return mModifier; }
|
|
|
|
void setBase(int base) { mBase = std::max(0, base); }
|
|
void setModifiers(float fortify, float drain, float absorb);
|
|
|
|
void damage(float damage) { mDamage = std::min(mDamage + damage, (float)(mBase + mFortified)); }
|
|
void restore(float amount) { mDamage -= std::min(mDamage, amount); }
|
|
|
|
void writeState (ESM::StatState<int>& state) const;
|
|
|
|
void readState (const ESM::StatState<int>& state);
|
|
|
|
friend bool operator== (const AttributeValue& left, const AttributeValue& right);
|
|
};
|
|
|
|
class SkillValue : public AttributeValue
|
|
{
|
|
float mProgress;
|
|
public:
|
|
SkillValue() : mProgress(0) {}
|
|
float getProgress() const { return mProgress; }
|
|
void setProgress(float progress) { mProgress = progress; }
|
|
|
|
void writeState (ESM::StatState<int>& state) const;
|
|
|
|
void readState (const ESM::StatState<int>& state);
|
|
|
|
friend bool operator== (const SkillValue& left, const SkillValue& right);
|
|
};
|
|
|
|
inline bool operator== (const AttributeValue& left, const AttributeValue& right)
|
|
{
|
|
return left.getBase() == right.getBase()
|
|
&& left.mFortified == right.mFortified
|
|
&& left.getModifier() == right.getModifier()
|
|
&& left.mDamage == right.mDamage;
|
|
}
|
|
inline bool operator!= (const AttributeValue& left, const AttributeValue& right)
|
|
{
|
|
return !(left == right);
|
|
}
|
|
|
|
inline bool operator== (const SkillValue& left, const SkillValue& right)
|
|
{
|
|
// delegate to base class for most of the work
|
|
return (static_cast<const AttributeValue&>(left) == right)
|
|
&& left.getProgress() == right.getProgress();
|
|
}
|
|
inline bool operator!= (const SkillValue& left, const SkillValue& right)
|
|
{
|
|
return !(left == right);
|
|
}
|
|
}
|
|
|
|
#endif
|