Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
CreatureAIImpl.h
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#ifndef CREATUREAIIMPL_H
7#define CREATUREAIIMPL_H
8
9#include "Common.h"
10#include "CreatureAI.h"
11#include "Define.h"
12#include "SpellMgr.h"
13#include "TemporarySummon.h"
14
15template<class T>
16inline
17const T& RAND(const T& v1, const T& v2)
18{
19 return (std::rand() % 1) ? v1 : v2;
20}
21
22template<class T>
23inline
24const T& RAND(const T& v1, const T& v2, const T& v3)
25{
26 switch (std::rand() % 2)
27 {
28 default:
29 case 0: return v1;
30 case 1: return v2;
31 case 2: return v3;
32 }
33}
34
35template<class T>
36inline
37const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4)
38{
39 switch (std::rand() % 3)
40 {
41 default:
42 case 0: return v1;
43 case 1: return v2;
44 case 2: return v3;
45 case 3: return v4;
46 }
47}
48
49template<class T>
50inline
51const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
52{
53 switch (std::rand() % 4)
54 {
55 default:
56 case 0: return v1;
57 case 1: return v2;
58 case 2: return v3;
59 case 3: return v4;
60 case 4: return v5;
61 }
62}
63
64template<class T>
65inline
66const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6)
67{
68 switch (std::rand() % 5)
69 {
70 default:
71 case 0: return v1;
72 case 1: return v2;
73 case 2: return v3;
74 case 3: return v4;
75 case 4: return v5;
76 case 5: return v6;
77 }
78}
79
80template<class T>
81inline
82const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7)
83{
84 switch (std::rand() % 6)
85 {
86 default:
87 case 0: return v1;
88 case 1: return v2;
89 case 2: return v3;
90 case 3: return v4;
91 case 4: return v5;
92 case 5: return v6;
93 case 6: return v7;
94 }
95}
96
97template<class T>
98inline
99const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8)
100{
101 switch (std::rand() % 7)
102 {
103 default:
104 case 0: return v1;
105 case 1: return v2;
106 case 2: return v3;
107 case 3: return v4;
108 case 4: return v5;
109 case 5: return v6;
110 case 6: return v7;
111 case 7: return v8;
112 }
113}
114
115template<class T>
116inline
117const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
118 const T& v9)
119{
120 switch (std::rand() % 8)
121 {
122 default:
123 case 0: return v1;
124 case 1: return v2;
125 case 2: return v3;
126 case 3: return v4;
127 case 4: return v5;
128 case 5: return v6;
129 case 6: return v7;
130 case 7: return v8;
131 case 8: return v9;
132 }
133}
134
135template<class T>
136inline
137const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
138 const T& v9, const T& v10)
139{
140 switch (std::rand() % 9)
141 {
142 default:
143 case 0: return v1;
144 case 1: return v2;
145 case 2: return v3;
146 case 3: return v4;
147 case 4: return v5;
148 case 5: return v6;
149 case 6: return v7;
150 case 7: return v8;
151 case 8: return v9;
152 case 9: return v10;
153 }
154}
155
156template<class T>
157inline
158const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
159 const T& v9, const T& v10, const T& v11)
160{
161 switch (std::rand() % 10)
162 {
163 default:
164 case 0: return v1;
165 case 1: return v2;
166 case 2: return v3;
167 case 3: return v4;
168 case 4: return v5;
169 case 5: return v6;
170 case 6: return v7;
171 case 7: return v8;
172 case 8: return v9;
173 case 9: return v10;
174 case 10: return v11;
175 }
176}
177
178template<class T>
179inline
180const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
181 const T& v9, const T& v10, const T& v11, const T& v12)
182{
183 switch (std::rand() % 11)
184 {
185 default:
186 case 0: return v1;
187 case 1: return v2;
188 case 2: return v3;
189 case 3: return v4;
190 case 4: return v5;
191 case 5: return v6;
192 case 6: return v7;
193 case 7: return v8;
194 case 8: return v9;
195 case 9: return v10;
196 case 10: return v11;
197 case 11: return v12;
198 }
199}
200
201template<class T>
202inline
203const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
204 const T& v9, const T& v10, const T& v11, const T& v12, const T& v13)
205{
206 switch (std::rand() % 12)
207 {
208 default:
209 case 0: return v1;
210 case 1: return v2;
211 case 2: return v3;
212 case 3: return v4;
213 case 4: return v5;
214 case 5: return v6;
215 case 6: return v7;
216 case 7: return v8;
217 case 8: return v9;
218 case 9: return v10;
219 case 10: return v11;
220 case 11: return v12;
221 case 12: return v13;
222 }
223}
224
225template<class T>
226inline
227const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
228 const T& v9, const T& v10, const T& v11, const T& v12, const T& v13, const T& v14)
229{
230 switch (std::rand() % 13)
231 {
232 default:
233 case 0: return v1;
234 case 1: return v2;
235 case 2: return v3;
236 case 3: return v4;
237 case 4: return v5;
238 case 5: return v6;
239 case 6: return v7;
240 case 7: return v8;
241 case 8: return v9;
242 case 9: return v10;
243 case 10: return v11;
244 case 11: return v12;
245 case 12: return v13;
246 case 13: return v14;
247 }
248}
249
250template<class T>
251inline
252const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
253 const T& v9, const T& v10, const T& v11, const T& v12, const T& v13, const T& v14, const T& v15)
254{
255 switch (std::rand() % 14)
256 {
257 default:
258 case 0: return v1;
259 case 1: return v2;
260 case 2: return v3;
261 case 3: return v4;
262 case 4: return v5;
263 case 5: return v6;
264 case 6: return v7;
265 case 7: return v8;
266 case 8: return v9;
267 case 9: return v10;
268 case 10: return v11;
269 case 11: return v12;
270 case 12: return v13;
271 case 13: return v14;
272 case 14: return v15;
273 }
274}
275
276template<class T>
277inline
278const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
279 const T& v9, const T& v10, const T& v11, const T& v12, const T& v13, const T& v14, const T& v15, const T& v16)
280{
281 switch (std::rand() % 15)
282 {
283 default:
284 case 0: return v1;
285 case 1: return v2;
286 case 2: return v3;
287 case 3: return v4;
288 case 4: return v5;
289 case 5: return v6;
290 case 6: return v7;
291 case 7: return v8;
292 case 8: return v9;
293 case 9: return v10;
294 case 10: return v11;
295 case 11: return v12;
296 case 12: return v13;
297 case 13: return v14;
298 case 14: return v15;
299 case 15: return v16;
300 }
301}
302
304{
316 typedef std::multimap<uint32, uint32> EventStore;
317
318public:
319 EventMap() : _time(0), _phase(0) { }
320
325 void Reset()
326 {
327 _eventMap.clear();
328 _time = 0;
329 _phase = 0;
330 }
331
337 void Update(uint32 time)
338 {
339 _time += time;
340 }
341
347 {
348 return _time;
349 }
350
356 {
357 return _phase;
358 }
359
364 bool Empty() const
365 {
366 return _eventMap.empty();
367 }
368
374 void SetPhase(uint8 phase)
375 {
376 if (!phase)
377 _phase = 0;
378 else if (phase <= 8)
379 _phase = (1 << (phase - 1));
380 }
381
387 void AddPhase(uint8 phase)
388 {
389 if (phase && phase <= 8)
390 _phase |= (1 << (phase - 1));
391 }
392
398 void RemovePhase(uint8 phase)
399 {
400 if (phase && phase <= 8)
401 _phase &= ~(1 << (phase - 1));
402 }
403
412 void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
413 {
414 if (group && group <= 8)
415 eventId |= (1 << (group + 15));
416
417 if (phase && phase <= 8)
418 eventId |= (1 << (phase + 23));
419
420 _eventMap.insert(EventStore::value_type(_time + time, eventId));
421 }
422
431 void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
432 {
433 CancelEvent(eventId);
434 ScheduleEvent(eventId, time, group, phase);
435 }
436
443 {
444 if (Empty())
445 return;
446
447 uint32 eventId = _eventMap.begin()->second;
448 _eventMap.erase(_eventMap.begin());
449 ScheduleEvent(eventId, time);
450 }
451
456 void PopEvent()
457 {
458 if (!Empty())
459 _eventMap.erase(_eventMap.begin());
460 }
461
468 {
469 while (!Empty())
470 {
471 EventStore::iterator itr = _eventMap.begin();
472
473 if (itr->first > _time)
474 return 0;
475 else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase))
476 _eventMap.erase(itr);
477 else
478 {
479 uint32 eventId = (itr->second & 0x0000FFFF);
480 _eventMap.erase(itr);
481 return eventId;
482 }
483 }
484
485 return 0;
486 }
487
494 {
495 while (!Empty())
496 {
497 EventStore::iterator itr = _eventMap.begin();
498
499 if (itr->first > _time)
500 return 0;
501 else if (_phase && (itr->second & 0xFF000000) && !(itr->second & (_phase << 24)))
502 _eventMap.erase(itr);
503 else
504 return (itr->second & 0x0000FFFF);
505 }
506
507 return 0;
508 }
509
515 void DelayEvents(uint32 delay)
516 {
517 _time = delay < _time ? _time - delay : 0;
518 }
519
526 void DelayEvents(uint32 delay, uint32 group)
527 {
528 if (!group || group > 8 || Empty())
529 return;
530
531 EventStore delayed;
532
533 for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
534 {
535 if (itr->second & (1 << (group + 15)))
536 {
537 delayed.insert(EventStore::value_type(itr->first + delay, itr->second));
538 _eventMap.erase(itr++);
539 }
540 else
541 ++itr;
542 }
543
544 _eventMap.insert(delayed.begin(), delayed.end());
545 }
546
552 void CancelEvent(uint32 eventId)
553 {
554 if (Empty())
555 return;
556
557 for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
558 {
559 if (eventId == (itr->second & 0x0000FFFF))
560 _eventMap.erase(itr++);
561 else
562 ++itr;
563 }
564 }
565
572 {
573 if (!group || group > 8 || Empty())
574 return;
575
576 for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
577 {
578 if (itr->second & (1 << (group + 15)))
579 _eventMap.erase(itr++);
580 else
581 ++itr;
582 }
583 }
584
592 {
593 if (Empty())
594 return 0;
595
596 for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
597 if (eventId == (itr->second & 0x0000FFFF))
598 return itr->first;
599
600 return 0;
601 }
602
608 {
609 return Empty() ? 0 : _eventMap.begin()->first;
610 }
611
618 bool IsInPhase(uint8 phase) const
619 {
620 return phase <= 8 && (!phase || _phase & (1 << (phase - 1)));
621 }
622
623private:
635
645
654};
655
665
672
673#define AI_DEFAULT_COOLDOWN 5000
674
685
687
688#endif
AITarget
@ AITARGET_ALLY
@ AITARGET_BUFF
@ AITARGET_SELF
@ AITARGET_VICTIM
@ AITARGET_ENEMY
@ AITARGET_DEBUFF
AISpellInfoType * GetAISpellInfo(uint32 i)
#define AI_DEFAULT_COOLDOWN
const T & RAND(const T &v1, const T &v2)
AICondition
@ AICOND_COMBAT
@ AICOND_AGGRO
@ AICOND_DIE
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
void AddPhase(uint8 phase)
void ScheduleEvent(uint32 eventId, uint32 time, uint32 group=0, uint8 phase=0)
uint32 ExecuteEvent()
void Update(uint32 time)
bool Empty() const
EventStore _eventMap
uint32 GetTimer() const
void DelayEvents(uint32 delay, uint32 group)
void CancelEventGroup(uint32 group)
void DelayEvents(uint32 delay)
uint32 GetNextEventTime() const
bool IsInPhase(uint8 phase) const
void RepeatEvent(uint32 time)
uint8 GetPhaseMask() const
void PopEvent()
void RemovePhase(uint8 phase)
void RescheduleEvent(uint32 eventId, uint32 time, uint32 group=0, uint8 phase=0)
std::multimap< uint32, uint32 > EventStore
void CancelEvent(uint32 eventId)
void SetPhase(uint8 phase)
uint32 GetNextEventTime(uint32 eventId) const
uint32 GetEvent()
AICondition condition