OpenMW
|
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