TrinityCore
npc_guard.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "GuardAI.h"
19#include "ObjectAccessor.h"
20#include "Player.h"
21#include "Random.h"
22#include "ScriptMgr.h"
23#include "SpellInfo.h"
24#include "CreatureAIImpl.h"
25
27{
29
35
39 SPELL_EXILE = 39533,
40};
41
43{
44 npc_guard_generic(Creature* creature) : GuardAI(creature)
45 {
47 {
49 });
51 {
53 });
54 }
55
56 void Reset() override
57 {
60 _scheduler.Schedule(Seconds(1), [this](TaskContext context)
61 {
62 // Find a spell that targets friendly and applies an aura (these are generally buffs)
63 if (SpellInfo const* spellInfo = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, SELECT_EFFECT_AURA))
64 DoCast(me, spellInfo->Id);
65
66 context.Repeat(Minutes(10));
67 });
68 }
69
71 {
72 switch (emote)
73 {
74 case TEXT_EMOTE_KISS:
76 break;
77 case TEXT_EMOTE_WAVE:
79 break;
82 break;
83 case TEXT_EMOTE_SHY:
85 break;
86 case TEXT_EMOTE_RUDE:
89 break;
90 default:
91 break;
92 }
93 }
94
95 void ReceiveEmote(Player* player, uint32 textEmote) override
96 {
97 switch (me->GetEntry())
98 {
102 break;
103 default:
104 return;
105 }
106
107 if (!me->IsFriendlyTo(player))
108 return;
109
110 DoReplyToTextEmote(textEmote);
111 }
112
113 void JustEngagedWith(Unit* who) override
114 {
117
118 _combatScheduler.Schedule(Seconds(1), [this](TaskContext meleeContext)
119 {
120 Unit* victim = me->GetVictim();
121 if (!me->isAttackReady() || !me->IsWithinMeleeRange(victim))
122 {
123 meleeContext.Repeat();
124 return;
125 }
126 if (roll_chance_i(20))
127 {
129 {
130 me->resetAttackTimer();
131 DoCastVictim(spellInfo->Id);
132 }
133 }
134 meleeContext.Repeat();
135 }).Schedule(Seconds(5), [this](TaskContext spellContext)
136 {
137 bool healing = false;
138 SpellInfo const* spellInfo = nullptr;
139
140 // Select a healing spell if less than 30% hp and ONLY 33% of the time
141 if (me->HealthBelowPct(30) && roll_chance_i(33))
143
144 // No healing spell available, check if we can cast a ranged spell
145 if (spellInfo)
146 healing = true;
147 else
149
150 // Found a spell
151 if (spellInfo)
152 {
153 if (healing)
154 DoCast(me, spellInfo->Id);
155 else
156 DoCastVictim(spellInfo->Id);
157 spellContext.Repeat(Seconds(5));
158 }
159 else
160 spellContext.Repeat(Seconds(1));
161 });
162 }
163
164 void UpdateAI(uint32 diff) override
165 {
166 _scheduler.Update(diff);
167
168 if (!UpdateVictim())
169 return;
170
172 }
173
174private:
177};
178
180{
182 {
184 {
186 });
187 }
188
189 void Reset() override
190 {
192 }
193
194 void JustEngagedWith(Unit* /*who*/) override
195 {
197 }
198
199 void UpdateAI(uint32 diff) override
200 {
201 if (!UpdateVictim())
202 return;
203
204 _scheduler.Update(diff);
205 }
206
208 {
209 _scheduler.Schedule(Seconds(5), [this](TaskContext banishContext)
210 {
211 Unit* temp = me->GetVictim();
212 if (temp && temp->GetTypeId() == TYPEID_PLAYER)
213 {
214 DoCast(temp, me->GetEntry() == NPC_ALDOR_VINDICATOR ? SPELL_BANISHED_SHATTRATH_S : SPELL_BANISHED_SHATTRATH_A);
215 ObjectGuid playerGUID = temp->GetGUID();
216 banishContext.Schedule(Seconds(9), [this, playerGUID](TaskContext /*exileContext*/)
217 {
218 if (Unit* temp = ObjectAccessor::GetUnit(*me, playerGUID))
219 {
220 temp->CastSpell(temp, SPELL_EXILE, true);
221 temp->CastSpell(temp, SPELL_BANISH_TELEPORT, true);
222 }
223 ScheduleVanish();
224 });
225 }
226 else
227 banishContext.Repeat();
228 });
229 }
230
231private:
233};
234
236{
239}
@ SELECT_EFFECT_DONTCARE
@ SELECT_EFFECT_AURA
@ SELECT_EFFECT_HEALING
@ SELECT_TARGET_ANY_FRIEND
@ SELECT_TARGET_ANY_ENEMY
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
std::chrono::minutes Minutes
Minutes shorthand typedef.
Definition: Duration.h:35
#define NOMINAL_MELEE_RANGE
Definition: ObjectDefines.h:44
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
bool roll_chance_i(int chance)
Definition: Random.h:59
if(posix_memalign(&__mallocedMemory, __align, __size)) return NULL
#define RegisterCreatureAI(ai_name)
Definition: ScriptMgr.h:1380
@ 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
@ UNIT_STATE_CASTING
Definition: Unit.h:270
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
bool IsInEvadeMode() const
Definition: Creature.h:203
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
uint32 const Id
Definition: SpellInfo.h:325
TaskContext & Repeat(std::chrono::duration< Rep, Period > duration)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(std::chrono::duration< Rep, Period > time, task_handler_t task)
TaskScheduler & Update(success_t const &callback=nullptr)
TaskScheduler & SetValidator(P &&predicate)
Sets a validator which is asked if tasks are allowed to be executed.
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
bool IsWithinMeleeRange(Unit const *obj) const
Definition: Unit.h:699
bool IsAlive() const
Definition: Unit.h:1164
bool HealthBelowPct(int32 pct) const
Definition: Unit.h:780
Unit * GetVictim() const
Definition: Unit.h:715
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition: Unit.cpp:1598
bool isAttackReady(WeaponAttackType type=BASE_ATTACK) const
Definition: Unit.h:690
bool IsFriendlyTo(WorldObject const *target) const
Definition: Object.cpp:2865
GuardMisc
Definition: npc_guard.cpp:27
@ NPC_STORMWIND_CITY_GUARD
Definition: npc_guard.cpp:31
@ NPC_CENARION_HOLD_INFANTRY
Definition: npc_guard.cpp:30
@ NPC_STORMWIND_CITY_PATROLLER
Definition: npc_guard.cpp:32
@ NPC_ORGRIMMAR_GRUNT
Definition: npc_guard.cpp:33
@ SPELL_EXILE
Definition: npc_guard.cpp:39
@ NPC_ALDOR_VINDICATOR
Definition: npc_guard.cpp:34
@ SPELL_BANISHED_SHATTRATH_S
Definition: npc_guard.cpp:37
@ SPELL_BANISH_TELEPORT
Definition: npc_guard.cpp:38
@ SPELL_BANISHED_SHATTRATH_A
Definition: npc_guard.cpp:36
@ SAY_GUARD_SIL_AGGRO
Definition: npc_guard.cpp:28
void AddSC_npc_guard()
Definition: npc_guard.cpp:235
SpellInfo const * SelectSpell(Unit *target, uint32 school, uint32 mechanic, SelectTargetType targets, float rangeMin, float rangeMax, SelectEffect effect)
void UpdateAI(uint32 diff) override
Definition: npc_guard.cpp:164
void DoReplyToTextEmote(uint32 emote)
Definition: npc_guard.cpp:70
TaskScheduler _scheduler
Definition: npc_guard.cpp:175
npc_guard_generic(Creature *creature)
Definition: npc_guard.cpp:44
TaskScheduler _combatScheduler
Definition: npc_guard.cpp:176
void ReceiveEmote(Player *player, uint32 textEmote) override
Definition: npc_guard.cpp:95
void JustEngagedWith(Unit *who) override
Definition: npc_guard.cpp:113
void Reset() override
Definition: npc_guard.cpp:56
void UpdateAI(uint32 diff) override
Definition: npc_guard.cpp:199
void JustEngagedWith(Unit *) override
Definition: npc_guard.cpp:194
npc_guard_shattrath_faction(Creature *creature)
Definition: npc_guard.cpp:181