Planeshift
buffable.h
Go to the documentation of this file.
1 /*
2  * buffable.h by Kenneth Graunke <kenneth@whitecape.org>
3  *
4  * Copyright (C) 2008 Atomic Blue (info@planeshift.it, http://www.atomicblue.org)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation (version 2 of the License)
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16  *
17  */
18 
19 #ifndef BUFFABLE_HEADER
20 #define BUFFABLE_HEADER
21 
22 //=============================================================================
23 // Crystal Space Includes
24 //=============================================================================
25 #include <cstypes.h>
26 #include <csutil/list.h>
27 #include <csutil/tuple.h>
28 
29 class ActiveSpell;
30 
38 {
39 public:
40  virtual ~iSpellModifier() { }
41  virtual void Cancel(const ActiveSpell* owner) = 0;
42 };
43 
44 //-----------------------------------------------------------------------------
45 
69 template <typename T>
71 {
72 public:
73 
75  {
76  values.PushBack(csTuple2<const ActiveSpell*,T>(NULL, x));
77  }
78 
79  virtual ~Overridable() { }
80 
81  T Current() const
82  {
83  return values.Front().second;
84  }
85 
86  T Base() const
87  {
88  CS_ASSERT(values.Last().first == NULL);
89  return values.Last().second;
90  }
91 
92  void SetBase(T x)
93  {
94  CS_ASSERT(values.Last().first == NULL);
95 
96  const T &old = Current();
97 
98  values.PopBack();
99  values.PushBack(csTuple2<const ActiveSpell*,T>(NULL, x));
100 
101  if(Current() != old)
102  OnChange();
103  }
104 
105  void Override(const ActiveSpell* owner, T x)
106  {
107  const T &old = Current();
108 
109  values.PushFront(csTuple2<const ActiveSpell*,T>(owner, x));
110 
111  if(x != old)
112  OnChange();
113  }
114 
115  virtual void Cancel(const ActiveSpell* owner)
116  {
117  const T &old = Current();
118 
119  typename csList< csTuple2<const ActiveSpell*, T> >::Iterator it(values);
120  while(it.HasNext())
121  {
122  csTuple2<const ActiveSpell*, T> &curr = it.Next();
123  if(curr.first == owner)
124  {
125  values.Delete(it);
126  }
127  }
128 
129  if(Current() != old)
130  OnChange();
131  }
132 
133 protected:
135  virtual void OnChange()
136  {
137  }
138 
139  csList< csTuple2<const ActiveSpell*, T> > values;
140 };
141 
142 //-----------------------------------------------------------------------------
143 
149 template <typename T>
150 class Buffable : public iSpellModifier
151 {
152 public:
154  {
155  base = cached = 0;
156  }
157  Buffable(T x)
158  {
159  base = cached = x;
160  }
161  virtual ~Buffable() { }
162 
163  T Current() const
164  {
165  return cached;
166  }
167  T Base() const
168  {
169  return base;
170  }
171 
172  void SetBase(T x)
173  {
174  if(x == base)
175  return;
176 
177  cached += x - base;
178  base = x;
179 
180  OnChange();
181  }
182 
183  void Buff(const ActiveSpell* owner, T x)
184  {
185  cached += x;
186  buffs.Push(csTuple2<const ActiveSpell*,T>(owner, x));
187 
188  OnChange();
189  }
190 
191  virtual void Cancel(const ActiveSpell* owner)
192  {
193  bool changed = false;
194 
195  // Count backwards since we're deleting and things may shift on the right
196  for(size_t i = buffs.GetSize() - 1; i != (size_t) -1; i--)
197  {
198  if(buffs[i].first == owner)
199  {
200  cached -= buffs[i].second;
201  buffs.DeleteIndexFast(i);
202  changed = true;
203  }
204  }
205 
206  if(changed)
207  OnChange();
208  }
209 
210 protected:
212  virtual void OnChange()
213  {
214  }
215 
216  T base;
218  csArray< csTuple2<const ActiveSpell*, T> > buffs;
219 };
220 
221 //-----------------------------------------------------------------------------
222 
230 {
231 public:
233  {
234  cached = 1;
235  }
236  virtual ~Multiplier() { }
237 
238  float Value()
239  {
240  return cached;
241  }
242 
243  void Buff(const ActiveSpell* owner, float x)
244  {
245  cached *= x;
246  buffs.PushBack(csTuple2<const ActiveSpell*, float>(owner, x));
247  }
248 
249  virtual void Cancel(const ActiveSpell* owner)
250  {
251  // Recompute the cache...avoid rounding errors.
252  cached = 1;
253 
254  csList< csTuple2<const ActiveSpell*, float> >::Iterator it(buffs);
255  while(it.HasNext())
256  {
257  csTuple2<const ActiveSpell*, float> &curr = it.Next();
258  if(curr.first == owner)
259  {
260  buffs.Delete(it);
261  }
262  else
263  {
264  cached *= curr.second;
265  }
266  }
267  }
268 
269 protected:
270  float cached;
271  csList< csTuple2<const ActiveSpell*, float> > buffs;
272 };
273 
274 //-----------------------------------------------------------------------------
275 
277 template <typename T>
279 {
280 public:
281  using Buffable<T>::cached;
282  int Current()
283  {
284  // Clamp to avoid underflow problems with negative buffs.
285  return cached > 0 ? cached : 0;
286  }
287 };
288 
289 #endif
T cached
Definition: buffable.h:217
csList< csTuple2< const ActiveSpell *, float > > buffs
Definition: buffable.h:271
csList< csTuple2< const ActiveSpell *, T > > values
Definition: buffable.h:139
virtual void Cancel(const ActiveSpell *owner)
Definition: buffable.h:191
T Current() const
Definition: buffable.h:81
Overridables.
Definition: buffable.h:70
virtual void OnChange()
Called whenever the current value changes; implemented in derived classes.
Definition: buffable.h:135
Buffables.
Definition: buffable.h:150
A special form of buffable that is clamped to always return a positive number.
Definition: buffable.h:278
Buffable()
Definition: buffable.h:153
void Buff(const ActiveSpell *owner, T x)
Definition: buffable.h:183
Multiplier()
Definition: buffable.h:232
void SetBase(T x)
Definition: buffable.h:92
virtual void OnChange()
Called whenever the value changes; implemented in derived classes.
Definition: buffable.h:212
float cached
Definition: buffable.h:270
virtual ~Buffable()
Definition: buffable.h:161
iSpellModifiers
Definition: buffable.h:37
virtual ~Overridable()
Definition: buffable.h:79
virtual ~Multiplier()
Definition: buffable.h:236
void SetBase(T x)
Definition: buffable.h:172
Overridable(T x)
Definition: buffable.h:74
virtual void Cancel(const ActiveSpell *owner)=0
Buffable(T x)
Definition: buffable.h:157
virtual ~iSpellModifier()
Definition: buffable.h:40
Multipliers.
Definition: buffable.h:229
void Buff(const ActiveSpell *owner, float x)
Definition: buffable.h:243
ActiveSpells.
Definition: activespell.h:68
T Base() const
Definition: buffable.h:167
csArray< csTuple2< const ActiveSpell *, T > > buffs
Definition: buffable.h:218
T Current() const
Definition: buffable.h:163
float Value()
Definition: buffable.h:238
void Override(const ActiveSpell *owner, T x)
Definition: buffable.h:105
virtual void Cancel(const ActiveSpell *owner)
Definition: buffable.h:115
virtual void Cancel(const ActiveSpell *owner)
Definition: buffable.h:249
T Base() const
Definition: buffable.h:86