Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
guards.cpp
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/* ScriptData
7SDName: Guards
8SD%Complete: 100
9SDComment:
10SDCategory: Guards
11EndScriptData */
12
13/* ContentData
14guard_generic
15guard_shattrath_aldor
16guard_shattrath_scryer
17EndContentData */
18
19#include "ScriptMgr.h"
20#include "ScriptedCreature.h"
21#include "GuardAI.h"
22#include "Player.h"
23#include "SpellInfo.h"
24
36
38{
39public:
40 guard_generic() : CreatureScript("guard_generic") { }
41
42 struct guard_genericAI : public GuardAI
43 {
44 guard_genericAI(Creature* creature) : GuardAI(creature) { }
45
47 {
49 buffTimer = 0;
50 }
51
53 {
54 if (me->GetEntry() == NPC_CENARION_HOLD_INFANTRY)
56 if (SpellInfo const* spell = me->reachWithSpellAttack(who))
57 DoCast(who, spell->Id);
58 }
59
61 {
62 //Always decrease our global cooldown first
63 if (globalCooldown > diff)
64 globalCooldown -= diff;
65 else
67
68 //Buff timer (only buff when we are alive and not in combat
69 if (me->IsAlive() && !me->IsInCombat())
70 {
71 if (buffTimer <= diff)
72 {
73 //Find a spell that targets friendly and applies an aura (these are generally buffs)
74 SpellInfo const* info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_AURA);
75
76 if (info && !globalCooldown)
77 {
78 //Cast the buff spell
79 DoCast(me, info->Id);
80
81 //Set our global cooldown
83
84 //Set our timer to 10 minutes before rebuff
85 buffTimer = 600000;
86 } //Try again in 30 seconds
87 else buffTimer = 30000;
88 } else buffTimer -= diff;
89 }
90
91 //Return since we have no target
92 if (!UpdateVictim())
93 return;
94
95 // Make sure our attack is ready and we arn't currently casting
96 if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false))
97 {
98 //If we are within range melee the target
99 if (me->IsWithinMeleeRange(me->GetVictim()))
100 {
101 bool healing = false;
102 SpellInfo const* info = NULL;
103
104 //Select a healing spell if less than 30% hp
105 if (me->HealthBelowPct(30))
107
108 //No healing spell available, select a hostile spell
109 if (info)
110 healing = true;
111 else
112 info = SelectSpell(me->GetVictim(), 0, 0, SELECT_TARGET_ANY_ENEMY, 0, 0, 0, 0, SELECT_EFFECT_DONTCARE);
113
114 //20% chance to replace our white hit with a spell
115 if (info && (std::rand() % 99) < 20 && !globalCooldown)
116 {
117 //Cast the spell
118 if (healing)
119 DoCast(me, info->Id);
120 else
121 DoCastVictim(info->Id);
122
123 //Set our global cooldown
125 }
126 else
127 me->AttackerStateUpdate(me->GetVictim());
128
129 me->resetAttackTimer();
130 }
131 }
132 else
133 {
134 //Only run this code if we arn't already casting
135 if (!me->IsNonMeleeSpellCasted(false))
136 {
137 bool healing = false;
138 SpellInfo const* info = NULL;
139
140 //Select a healing spell if less than 30% hp ONLY 33% of the time
141 if (me->HealthBelowPct(30) && 33 > (std::rand() % 99))
143
144 //No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE)
145 if (info)
146 healing = true;
147 else
149
150 //Found a spell, check if we arn't on cooldown
151 if (info && !globalCooldown)
152 {
153 //If we are currently moving stop us and set the movement generator
154 if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
155 {
156 me->GetMotionMaster()->Clear(false);
157 me->GetMotionMaster()->MoveIdle();
158 }
159
160 //Cast spell
161 if (healing)
162 DoCast(me, info->Id);
163 else
164 DoCastVictim(info->Id);
165
166 //Set our global cooldown
168 } //If no spells available and we arn't moving run to target
169 else if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
170 {
171 //Cancel our current spell and then mutate new movement generator
172 me->InterruptNonMeleeSpells(false);
173 me->GetMotionMaster()->Clear(false);
174 me->GetMotionMaster()->MoveChase(me->GetVictim());
175 }
176 }
177 }
178
180 }
181
183 {
184 switch (emote)
185 {
186 case TEXT_EMOTE_KISS:
187 me->HandleEmoteCommand(EMOTE_ONESHOT_BOW);
188 break;
189
190 case TEXT_EMOTE_WAVE:
191 me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
192 break;
193
195 me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
196 break;
197
198 case TEXT_EMOTE_SHY:
199 me->HandleEmoteCommand(EMOTE_ONESHOT_FLEX);
200 break;
201
202 case TEXT_EMOTE_RUDE:
204 me->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
205 break;
206 }
207 }
208
209 void ReceiveEmote(Player* player, uint32 textEmote) OVERRIDE
210 {
211 switch (me->GetEntry())
212 {
216 break;
217 default:
218 return;
219 }
220
221 if (!me->IsFriendlyTo(player))
222 return;
223
224 DoReplyToTextEmote(textEmote);
225 }
226
227 private:
230 };
231
233 {
234 return new guard_genericAI(creature);
235 }
236};
237
245
247{
248public:
249 guard_shattrath_scryer() : CreatureScript("guard_shattrath_scryer") { }
250
252 {
253 guard_shattrath_scryerAI(Creature* creature) : GuardAI(creature) { }
254
256 {
257 banishTimer = 5000;
258 exileTimer = 8500;
259 playerGUID = 0;
260 canTeleport = false;
261 }
262
264 {
265 if (!UpdateVictim())
266 return;
267
268 if (canTeleport)
269 {
270 if (exileTimer <= diff)
271 {
272 if (Unit* temp = Unit::GetUnit(*me, playerGUID))
273 {
274 temp->CastSpell(temp, SPELL_EXILE, true);
275 temp->CastSpell(temp, SPELL_BANISH_TELEPORT, true);
276 }
277 playerGUID = 0;
278 exileTimer = 8500;
279 canTeleport = false;
280 } else exileTimer -= diff;
281 }
282 else if (banishTimer <= diff)
283 {
284 Unit* temp = me->GetVictim();
285 if (temp && temp->GetTypeId() == TypeID::TYPEID_PLAYER)
286 {
288 banishTimer = 9000;
289 playerGUID = temp->GetGUID();
290 if (playerGUID)
291 canTeleport = true;
292 }
293 } else banishTimer -= diff;
294
296 }
297
298 private:
303 };
304
306 {
307 return new guard_shattrath_scryerAI(creature);
308 }
309};
310
312{
313public:
314 guard_shattrath_aldor() : CreatureScript("guard_shattrath_aldor") { }
315
317 {
318 guard_shattrath_aldorAI(Creature* creature) : GuardAI(creature) { }
319
321 {
322 banishTimer = 5000;
323 exileTimer = 8500;
324 playerGUID = 0;
325 canTeleport = false;
326 }
327
329 {
330 if (!UpdateVictim())
331 return;
332
333 if (canTeleport)
334 {
335 if (exileTimer <= diff)
336 {
337 if (Unit* temp = Unit::GetUnit(*me, playerGUID))
338 {
339 temp->CastSpell(temp, SPELL_EXILE, true);
340 temp->CastSpell(temp, SPELL_BANISH_TELEPORT, true);
341 }
342 playerGUID = 0;
343 exileTimer = 8500;
344 canTeleport = false;
345 } else exileTimer -= diff;
346 }
347 else if (banishTimer <= diff)
348 {
349 Unit* temp = me->GetVictim();
350 if (temp && temp->GetTypeId() == TypeID::TYPEID_PLAYER)
351 {
353 banishTimer = 9000;
354 playerGUID = temp->GetGUID();
355 if (playerGUID)
356 canTeleport = true;
357 }
358 } else banishTimer -= diff;
359
361 }
362 private:
367 };
368
370 {
371 return new guard_shattrath_aldorAI(creature);
372 }
373};
374
376{
377 new guard_generic;
380}
@ SELECT_TARGET_ANY_FRIEND
Definition CreatureAI.h:35
@ SELECT_TARGET_ANY_ENEMY
Definition CreatureAI.h:31
@ SELECT_EFFECT_DONTCARE
Definition CreatureAI.h:41
@ SELECT_EFFECT_AURA
Definition CreatureAI.h:44
@ SELECT_EFFECT_HEALING
Definition CreatureAI.h:43
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ IDLE_MOTION_TYPE
@ CHASE_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
#define NOMINAL_MELEE_RANGE
Definition Object.h:32
@ EMOTE_ONESHOT_POINT
@ EMOTE_ONESHOT_FLEX
@ EMOTE_ONESHOT_BOW
@ EMOTE_ONESHOT_SALUTE
@ EMOTE_ONESHOT_WAVE
@ TEXT_EMOTE_CHICKEN
@ TEXT_EMOTE_SHY
@ TEXT_EMOTE_SALUTE
@ TEXT_EMOTE_RUDE
@ TEXT_EMOTE_KISS
@ TEXT_EMOTE_WAVE
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureScript(const char *name)
GuardAI(Creature *creature)
Definition GuardAI.cpp:21
uint64 GetGUID() const
Definition Object.h:119
TypeID GetTypeId() const
Definition Object.h:131
uint32 Id
Definition SpellInfo.h:160
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
CreatureAI * GetAI(Creature *creature) const OVERRIDE
Definition guards.cpp:232
CreatureAI * GetAI(Creature *creature) const OVERRIDE
Definition guards.cpp:369
CreatureAI * GetAI(Creature *creature) const OVERRIDE
Definition guards.cpp:305
GuardShattrath
Definition guards.cpp:239
@ SPELL_EXILE
Definition guards.cpp:243
@ SPELL_BANISHED_SHATTRATH_S
Definition guards.cpp:241
@ SPELL_BANISH_TELEPORT
Definition guards.cpp:242
@ SPELL_BANISHED_SHATTRATH_A
Definition guards.cpp:240
GuardGeneric
Definition guards.cpp:26
@ NPC_STORMWIND_CITY_GUARD
Definition guards.cpp:32
@ NPC_CENARION_HOLD_INFANTRY
Definition guards.cpp:31
@ NPC_STORMWIND_CITY_PATROLLER
Definition guards.cpp:33
@ NPC_ORGRIMMAR_GRUNT
Definition guards.cpp:34
@ SAY_GUARD_SIL_AGGRO
Definition guards.cpp:29
@ GENERIC_CREATURE_COOLDOWN
Definition guards.cpp:27
void AddSC_guards()
Definition guards.cpp:375
#define GENERIC_CREATURE_COOLDOWN
Creature * me
SpellInfo const * SelectSpell(Unit *target, uint32 school, uint32 mechanic, SelectTargetType targets, uint32 powerCostMin, uint32 powerCostMax, float rangeMin, float rangeMax, SelectEffect effect)
void EnterCombat(Unit *who) OVERRIDE
Definition guards.cpp:52
void DoReplyToTextEmote(uint32 emote)
Definition guards.cpp:182
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
Definition guards.cpp:60
guard_genericAI(Creature *creature)
Definition guards.cpp:44
void ReceiveEmote(Player *player, uint32 textEmote) OVERRIDE
Definition guards.cpp:209
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
Definition guards.cpp:328
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
Definition guards.cpp:263