SimpleAI
 All Classes Namespaces Files Functions Variables Typedefs Macros Groups Pages
AggroMgr.h
Go to the documentation of this file.
1 
8 #pragma once
9 
10 #include <vector>
11 #include <memory>
12 #include "ICharacter.h"
13 #include <algorithm>
14 #include "aggro/Entry.h"
15 
16 namespace ai {
17 
21 class AggroMgr {
22 public:
23  typedef std::vector<Entry> Entries;
24  typedef Entries::iterator EntriesIter;
25 protected:
26  mutable Entries _entries;
27 
28  mutable bool _dirty;
29 
30  float _minAggro = 0.0f;
31  float _reduceRatioSecond = 0.0f;
32  float _reduceValueSecond = 0.0f;
33  ReductionType _reduceType = DISABLED;
34 
36  private:
37  const CharacterId& _id;
38  public:
39  explicit CharacterIdPredicate(const CharacterId& id) :
40  _id(id) {
41  }
42 
43  inline bool operator()(const Entry &n1) {
44  return n1.getCharacterId() == _id;
45  }
46  };
47 
48  static bool EntrySorter(const Entry& a, const Entry& b) {
49  if (a.getAggro() > b.getAggro()) {
50  return false;
51  }
52  if (::fabs(a.getAggro() - b.getAggro()) < 0.0000001f) {
53  return a.getCharacterId() < b.getCharacterId();
54  }
55  return true;
56  }
57 
62  void cleanupList() {
63  EntriesIter::difference_type remove = 0;
64  for (EntriesIter i = _entries.begin(); i != _entries.end(); ++i) {
65  const float aggroValue = i->getAggro();
66  if (aggroValue > 0.0f) {
67  break;
68  }
69 
70  ++remove;
71  }
72 
73  if (remove == 0) {
74  return;
75  }
76 
77  const int size = static_cast<int>(_entries.size());
78  if (size == remove) {
79  _entries.clear();
80  return;
81  }
82 
83  EntriesIter i = _entries.begin();
84  std::advance(i, remove);
85  _entries.erase(_entries.begin(), i);
86  }
87 
88  inline void sort() const {
89  if (!_dirty) {
90  return;
91  }
92  std::sort(_entries.begin(), _entries.end(), EntrySorter);
93  _dirty = false;
94  }
95 public:
96  explicit AggroMgr(std::size_t expectedEntrySize = 0u) :
97  _dirty(false) {
98  if (expectedEntrySize > 0) {
99  _entries.reserve(expectedEntrySize);
100  }
101  }
102 
103  virtual ~AggroMgr() {
104  }
105 
106  inline void setReduceByRatio(float reduceRatioSecond, float minAggro) {
107  _reduceType = RATIO;
108  _reduceValueSecond = 0.0f;
109  _reduceRatioSecond = reduceRatioSecond;
110  _minAggro = minAggro;
111  }
112 
113  inline void setReduceByValue(float reduceValueSecond) {
114  _reduceType = VALUE;
115  _reduceValueSecond = reduceValueSecond;
116  _reduceRatioSecond = 0.0f;
117  _minAggro = 0.0f;
118  }
119 
120  inline void resetReduceValue() {
121  _reduceType = DISABLED;
122  _reduceValueSecond = 0.0f;
123  _reduceRatioSecond = 0.0f;
124  _minAggro = 0.0f;
125  }
126 
131  void update(int64_t deltaMillis) {
132  for (EntriesIter i = _entries.begin(); i != _entries.end(); ++i) {
133  _dirty |= i->reduceByTime(deltaMillis);
134  }
135 
136  if (_dirty) {
137  sort();
138  cleanupList();
139  }
140  }
141 
148  EntryPtr addAggro(CharacterId id, float amount) {
149  const CharacterIdPredicate p(id);
150  EntriesIter i = std::find_if(_entries.begin(), _entries.end(), p);
151  if (i == _entries.end()) {
152  Entry newEntry(id, amount);
153  switch (_reduceType) {
154  case RATIO:
155  newEntry.setReduceByRatio(_reduceRatioSecond, _minAggro);
156  break;
157  case VALUE:
158  newEntry.setReduceByValue(_reduceValueSecond);
159  break;
160  default:
161  break;
162  }
163  _entries.push_back(newEntry);
164  _dirty = true;
165  return &_entries.back();
166  }
167 
168  i->addAggro(amount);
169  _dirty = true;
170  return &*i;
171  }
172 
176  const Entries& getEntries() const {
177  return _entries;
178  }
179 
186  if (_entries.empty()) {
187  return nullptr;
188  }
189 
190  sort();
191 
192  return &_entries.back();
193  }
194 };
195 
196 }
197 
Manages the aggro values for one AI instance. There are several ways to degrade the aggro values...
Definition: AggroMgr.h:21
Definition: AggroMgr.h:35
const Entries & getEntries() const
Definition: AggroMgr.h:176
EntryPtr addAggro(CharacterId id, float amount)
will increase the aggro
Definition: AggroMgr.h:148
EntryPtr getHighestEntry() const
Get the entry with the highest aggro value.
Definition: AggroMgr.h:185
One entry for the AggroMgr.
Definition: Entry.h:17
void cleanupList()
Remove the entries from the list that have no aggro left. This list is ordered, so we will only remov...
Definition: AggroMgr.h:62
void update(int64_t deltaMillis)
this will update the aggro list according to the reduction type of an entry.
Definition: AggroMgr.h:131