1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRINITY_SMARTAI_H
#define TRINITY_SMARTAI_H
#include "Define.h"
#include "AreaTriggerAI.h"
#include "CreatureAI.h"
#include "GameObjectAI.h"
#include "SmartScript.h"
#include "WaypointDefines.h"
enum class AreaTriggerExitReason : uint8;
enum class MovementStopReason : uint8;
enum SmartEscortState : uint8
{
SMART_ESCORT_NONE = 0x00, // nothing in progress
SMART_ESCORT_ESCORTING = 0x01, // escort is in progress
SMART_ESCORT_RETURNING = 0x02, // escort is returning after being in combat
SMART_ESCORT_PAUSED = 0x04 // will not proceed with waypoints before state is removed
};
static float constexpr SMART_ESCORT_MAX_PLAYER_DIST = 60.f;
static float constexpr SMART_MAX_AID_DIST = SMART_ESCORT_MAX_PLAYER_DIST / 2.f;
class TC_GAME_API SmartAI : public CreatureAI
{
public:
~SmartAI() { }
explicit SmartAI(Creature* creature, uint32 scriptId = {});
// core related
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
// Check whether we are currently permitted to make the creature take action
bool IsAIControlled() const;
// Start moving to the desired MovePoint
void StartPath(uint32 pathId = 0, bool repeat = false, Unit* invoker = nullptr, uint32 nodeId = 0,
Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
WaypointPath const* LoadPath(uint32 entry);
void PausePath(uint32 delay, bool forced = false);
bool CanResumePath();
void StopPath(uint32 DespawnTime = 0, uint32 quest = 0, bool fail = false);
void EndPath(bool fail = false);
void ResumePath();
bool HasEscortState(uint32 escortState) const
{
return (_escortState & escortState) != 0;
}
void AddEscortState(uint32 escortState)
{
_escortState |= escortState;
}
void RemoveEscortState(uint32 escortState)
{
_escortState &= ~escortState;
}
void SetCombatMove(bool on, bool stopMoving = false);
bool CanCombatMove() const
{
return _canCombatMove;
}
void SetFollow(Unit* target, float dist = 0.0f, float angle = 0.0f, uint32 credit = 0, uint32 end = 0, uint32 creditType = 0);
void StopFollow(bool complete);
bool IsEscortInvokerInRange();
void WaypointReached(uint32 nodeId, uint32 pathId) override;
void WaypointPathEnded(uint32 nodeId, uint32 pathId) override;
void SetTimedActionList(SmartScriptHolder& e, uint32 entry, Unit* invoker, uint32 startFromEventId = 0);
SmartScript* GetScript()
{
return &_script;
}
// Called at reaching home after evade, InitializeAI(), EnterEvadeMode() for resetting variables
void JustReachedHome() override;
// Called for reaction at enter to combat if not in combat yet (enemy can be nullptr)
void JustEngagedWith(Unit* enemy) override;
// Called for reaction at stopping attack at no attackers or targets
void EnterEvadeMode(EvadeReason why) override;
// Called when the creature is killed
void JustDied(Unit* killer) override;
// Called when the creature kills a unit
void KilledUnit(Unit* victim) override;
// Called when the creature summon successfully other creature
void JustSummoned(Creature* creature) override;
// Called when a summoned unit dies
void SummonedCreatureDies(Creature* summon, Unit* killer) override;
// Tell creature to attack and follow the victim
void AttackStart(Unit* who) override;
// Called if IsVisible(Unit* who) is true at each *who move, reaction at visibility zone enter
void MoveInLineOfSight(Unit* who) override;
// Called when hit by a spell
void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override;
// Called when spell hits a target
void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override;
// Called when a spell finishes
void OnSpellCast(SpellInfo const* spellInfo) override;
// Called when a spell fails
void OnSpellFailed(SpellInfo const* spellInfo) override;
// Called when a spell starts
void OnSpellStart(SpellInfo const* spellInfo) override;
// Called at any Damage from any attacker (before damage apply)
void DamageTaken(Unit* doneBy, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override;
// Called when the creature receives heal
void HealReceived(Unit* doneBy, uint32& addhealth) override;
// Called at World update tick
void UpdateAI(uint32 diff) override;
// Called at text emote receive from player
void ReceiveEmote(Player* player, uint32 textEmote) override;
// Called at waypoint reached or point movement finished
void MovementInform(uint32 MovementType, uint32 Data) override;
// Called when creature is summoned by another unit
void IsSummonedBy(WorldObject* summoner) override;
// Called at any Damage to any victim (before damage apply)
void DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/) override;
// Called when a summoned creature dissapears (UnSommoned)
void SummonedCreatureDespawn(Creature* unit) override;
// called when the corpse of this creature gets removed
void CorpseRemoved(uint32& respawnDelay) override;
// Called when the unit is about to be removed from the world (despawn, grid unload, corpse disappearing)
void OnDespawn() override;
// Called when a Player/Creature enters the creature (vehicle)
void PassengerBoarded(Unit* who, int8 seatId, bool apply) override;
// Called when gets initialized
void InitializeAI() override;
// Called once creature is fully added to world
void JustAppeared() override;
// Called when creature gets charmed by another unit
void OnCharmed(bool isNew) override;
// Used in scripts to share variables
void DoAction(int32 param) override;
// Used in scripts to share variables
uint32 GetData(uint32 id) const override;
// Used in scripts to share variables
void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
void SetData(uint32 id, uint32 value, Unit* invoker);
// Used in scripts to share variables
void SetGUID(ObjectGuid const& guid, int32 id) override;
// Used in scripts to share variables
ObjectGuid GetGUID(int32 id) const override;
// Makes the creature run/walk
void SetRun(bool run = true);
void SetEvadeDisabled(bool disable = true);
void SetInvincibilityHpLevel(uint32 level)
{
_invincibilityHPLevel = level;
}
bool OnGossipHello(Player* player) override;
bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override;
bool OnGossipSelectCode(Player* player, uint32 menuId, uint32 gossipListId, char const* code) override;
void OnQuestAccept(Player* player, Quest const* quest) override;
void OnQuestReward(Player* player, Quest const* quest, LootItemType type, uint32 opt) override;
void OnGameEvent(bool start, uint16 eventId) override;
void SetDespawnTime (uint32 t)
{
_despawnTime = t;
_despawnState = t ? 1 : 0;
}
void StartDespawn()
{
_despawnState = 2;
}
void OnSpellClick(Unit* clicker, bool spellClickHandled) override;
void SetWPPauseTimer(uint32 time)
{
_waypointPauseTimer = time;
}
void SetGossipReturn(bool val)
{
_gossipReturn = val;
}
void SetEscortQuest(uint32 questID)
{
_escortQuestId = questID;
}
private:
bool AssistPlayerInCombatAgainst(Unit* who);
void ReturnToLastOOCPos();
void CheckConditions(uint32 diff);
void UpdatePath(uint32 diff);
void UpdateFollow(uint32 diff);
void UpdateDespawn(uint32 diff);
SmartScript _script;
bool _charmed;
uint32 _followCreditType;
uint32 _followArrivedTimer;
uint32 _followCredit;
uint32 _followArrivedEntry;
ObjectGuid _followGUID;
float _followDistance;
float _followAngle;
uint32 _escortState;
uint32 _escortNPCFlags;
uint32 _escortInvokerCheckTimer;
uint32 _currentWaypointNodeId;
bool _waypointReached;
uint32 _waypointPauseTimer;
bool _waypointPauseForced;
bool _repeatWaypointPath;
bool _OOCReached;
bool _waypointPathEnded;
bool _run;
bool _evadeDisabled;
bool _canCombatMove;
uint32 _invincibilityHPLevel;
uint32 _despawnTime;
uint32 _despawnState;
// Vehicle conditions
bool _vehicleConditions;
uint32 _vehicleConditionsTimer;
// Gossip
bool _gossipReturn;
uint32 _escortQuestId;
};
class TC_GAME_API SmartGameObjectAI : public GameObjectAI
{
public:
SmartGameObjectAI(GameObject* go, uint32 scriptId = {}) : GameObjectAI(go, scriptId), _gossipReturn(false) { }
~SmartGameObjectAI() { }
void UpdateAI(uint32 diff) override;
void InitializeAI() override;
void Reset() override;
SmartScript* GetScript()
{
return &_script;
}
static int32 Permissible(GameObject const* /*go*/)
{
return PERMIT_BASE_NO;
}
bool OnGossipHello(Player* player) override;
bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override;
bool OnGossipSelectCode(Player* player, uint32 menuId, uint32 gossipListId, char const* code) override;
void OnQuestAccept(Player* player, Quest const* quest) override;
void OnQuestReward(Player* player, Quest const* quest, LootItemType type, uint32 opt) override;
bool OnReportUse(Player* player) override;
void Destroyed(WorldObject* attacker, uint32 eventId) override;
void SetData(uint32 id, uint32 value, Unit* invoker);
void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
void SetTimedActionList(SmartScriptHolder& e, uint32 entry, Unit* invoker);
void OnGameEvent(bool start, uint16 eventId) override;
void OnLootStateChanged(uint32 state, Unit* unit) override;
void EventInform(uint32 eventId) override;
// Called when hit by a spell
void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override;
// Called when the gameobject summon successfully other creature
void JustSummoned(Creature* creature) override;
// Called when a summoned unit dies
void SummonedCreatureDies(Creature* summon, Unit* killer) override;
// Called when a summoned creature dissapears (UnSommoned)
void SummonedCreatureDespawn(Creature* unit) override;
void SetGossipReturn(bool val) { _gossipReturn = val; }
private:
SmartScript _script;
// Gossip
bool _gossipReturn;
};
class TC_GAME_API SmartAreaTriggerAI : public AreaTriggerAI
{
public:
using AreaTriggerAI::AreaTriggerAI;
void OnInitialize() override;
void OnUpdate(uint32 diff) override;
void OnUnitEnter(Unit* unit) override;
void OnUnitExit(Unit* unit, AreaTriggerExitReason reason) override;
SmartScript* GetScript() { return &mScript; }
void SetTimedActionList(SmartScriptHolder& e, uint32 entry, Unit* invoker);
private:
SmartScript mScript;
};
/// Registers scripts required by the SAI scripting system
void AddSC_SmartScripts();
#endif
|