OpenMW
apps/openmw/mwmechanics/stat.hpp
Go to the documentation of this file.
00001 #ifndef GAME_MWMECHANICS_STAT_H
00002 #define GAME_MWMECHANICS_STAT_H
00003 
00004 #undef min
00005 #undef max
00006 
00007 #include <limits>
00008 
00009 namespace MWMechanics
00010 {
00011     template<typename T>
00012     class Stat
00013     {
00014             T mBase;
00015             T mModified;
00016 
00017         public:
00018             typedef T Type;
00019 
00020             Stat() : mBase (0), mModified (0) {}
00021             Stat(T base) : mBase (base), mModified (base) {}
00022             Stat(T base, T modified) : mBase (base), mModified (modified) {}
00023 
00024             const T& getBase() const
00025             {
00026                 return mBase;
00027             }
00028 
00029             T getModified() const
00030             {
00031                 return std::max(static_cast<T>(0), mModified);
00032             }
00033 
00034             T getModifier() const
00035             {
00036                 return mModified-mBase;
00037             }
00038 
00040             void set (const T& value)
00041             {
00042                 mBase = mModified = value;
00043             }
00044 
00045             void modify(const T& diff)
00046             {
00047                 mBase += diff;
00048                 if(mBase >= static_cast<T>(0))
00049                     mModified += diff;
00050                 else
00051                 {
00052                     mModified += diff - mBase;
00053                     mBase = static_cast<T>(0);
00054                 }
00055             }
00056 
00058             void setBase (const T& value)
00059             {
00060                 T diff = value - mBase;
00061                 mBase = value;
00062                 mModified += diff;
00063             }
00064 
00066             void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max())
00067             {
00068                 T diff = value - mModified;
00069 
00070                 if (mBase+diff<min)
00071                 {
00072                     value = min + (mModified - mBase);
00073                     diff = value - mModified;
00074                 }
00075                 else if (mBase+diff>max)
00076                 {
00077                     value = max + (mModified - mBase);
00078                     diff = value - mModified;
00079                 }
00080 
00081                 mModified = value;
00082                 mBase += diff;
00083             }
00084 
00085             void setModifier (const T& modifier)
00086             {
00087                 mModified = mBase + modifier;
00088             }
00089     };
00090 
00091     template<typename T>
00092     inline bool operator== (const Stat<T>& left, const Stat<T>& right)
00093     {
00094         return left.getBase()==right.getBase() &&
00095             left.getModified()==right.getModified();
00096     }
00097 
00098     template<typename T>
00099     inline bool operator!= (const Stat<T>& left, const Stat<T>& right)
00100     {
00101         return !(left==right);
00102     }
00103 
00104     template<typename T>
00105     class DynamicStat
00106     {
00107             Stat<T> mStatic;
00108             T mCurrent;
00109 
00110         public:
00111             typedef T Type;
00112 
00113             DynamicStat() : mStatic (0), mCurrent (0) {}
00114             DynamicStat(T base) : mStatic (base), mCurrent (base) {}
00115             DynamicStat(T base, T modified, T current) : mStatic(base, modified), mCurrent (current) {}
00116             DynamicStat(const Stat<T> &stat, T current) : mStatic(stat), mCurrent (current) {}
00117 
00118             const T& getBase() const
00119             {
00120                 return mStatic.getBase();
00121             }
00122 
00123             T getModified() const
00124             {
00125                 return mStatic.getModified();
00126             }
00127 
00128             const T& getCurrent() const
00129             {
00130                 return mCurrent;
00131             }
00132 
00134             void set (const T& value)
00135             {
00136                 mStatic.set (value);
00137                 mCurrent = value;
00138             }
00139 
00141             void setBase (const T& value)
00142             {
00143                 mStatic.setBase (value);
00144 
00145                 if (mCurrent>getModified())
00146                     mCurrent = getModified();
00147             }
00148 
00150             void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max())
00151             {
00152                 mStatic.setModified (value, min, max);
00153 
00154                 if (mCurrent>getModified())
00155                     mCurrent = getModified();
00156             }
00157 
00159             void modify (const T& diff)
00160             {
00161                 mStatic.modify (diff);
00162                 setCurrent (getCurrent()+diff);
00163             }
00164 
00165             void setCurrent (const T& value, bool allowDecreaseBelowZero = false)
00166             {
00167                 if (value > mCurrent)
00168                 {
00169                     // increase
00170                     mCurrent = value;
00171 
00172                     if (mCurrent > getModified())
00173                         mCurrent = getModified();
00174                 }
00175                 else if (value > 0 || allowDecreaseBelowZero)
00176                 {
00177                     // allowed decrease
00178                     mCurrent = value;
00179                 }
00180                 else if (mCurrent > 0)
00181                 {
00182                     // capped decrease
00183                     mCurrent = 0;
00184                 }
00185             }
00186 
00187             void setModifier (const T& modifier)
00188             {
00189                 T diff =  modifier - mStatic.getModifier();
00190                 mStatic.setModifier (modifier);
00191                 setCurrent (getCurrent()+diff);
00192             }
00193     };
00194 
00195     template<typename T>
00196     inline bool operator== (const DynamicStat<T>& left, const DynamicStat<T>& right)
00197     {
00198         return left.getBase()==right.getBase() &&
00199             left.getModified()==right.getModified() &&
00200             left.getCurrent()==right.getCurrent();
00201     }
00202 
00203     template<typename T>
00204     inline bool operator!= (const DynamicStat<T>& left, const DynamicStat<T>& right)
00205     {
00206         return !(left==right);
00207     }
00208 }
00209 
00210 #endif