TrinityCore
boss_lockmaw.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 "ScriptMgr.h"
19#include "Containers.h"
20#include "InstanceScript.h"
22#include "MotionMaster.h"
23#include "ObjectAccessor.h"
24#include "ScriptedCreature.h"
25#include "SpellScript.h"
26
28{
29 // Lockmaw
35
36 // Add Stalker
38 SPELL_AUGH_1 = 84809, // Casts Paralytic Blow Dart
39 SPELL_AUGH_2 = 84808, // Casts Whirlwind
40
41 // Adds
43
44 // Dust Flail
46
47 // Augh (Add)
52
53 // Augh (Boss)
54 SPELL_FRENZY = 91415,
57};
58
60{
61 // Lockmaw
69
70 // Augh (Add)
79
80 // Augh (Boss)
88};
89
91{
92 // Augh (Boss)
94 PHASE_COMBAT = 2
95};
96
98{
99 // Augh (Adds)
102
103 // Augh (Boss)
109 SAY_INTRO_5 = 5
111
113{
115 Whirlwind = 1
116};
117
119{
123
124// Instead of using a fixate or taunt aura, the Crocolisks use a flat threat amount instead
125static constexpr float SCENT_OF_BLOOD_THREAT_AMOUNT = 500000.f;
126static Position const AughRespawnPosition = { -11062.5f, -1662.39f, 0.7606202f, 0.8028514f };
127
128struct boss_lockmaw : public BossAI
129{
131
132 void JustEngagedWith(Unit* who) override
133 {
136
141 }
142
143 void EnterEvadeMode(EvadeReason /*why*/) override
144 {
149 }
150
151 void JustDied(Unit* killer) override
152 {
153 BossAI::JustDied(killer);
157 }
158
159 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
160 {
161 if (damage >= me->GetHealth())
162 return;
163
164 if (!_enraged && me->HealthBelowPctDamaged(30, damage))
165 {
167 _enraged = true;
168 }
169 }
170
171 bool CanAIAttack(Unit const* victim) const override
172 {
173 // Patch 4.0.6 (2011-02-08): Lockmaw no longer tolerates fighting in his treasure room.
174 return victim && victim->IsOutdoors();
175 }
176
177 void JustSummoned(Creature* summon) override
178 {
179 summons.Summon(summon);
180
181 switch (summon->GetEntry())
182 {
184 summon->CastSpell(nullptr, SPELL_DUST_FLAIL_PERIODIC);
185 break;
186 default:
187 break;
188 }
189 }
190
191 void UpdateAI(uint32 diff) override
192 {
193 if (!UpdateVictim())
194 return;
195
196 events.Update(diff);
197
199 return;
200
201 while (uint32 eventId = events.ExecuteEvent())
202 {
203 switch (eventId)
204 {
206 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 45.f, true, 0.f))
208 else
210
211 events.Repeat(30s);
212 break;
214 // just a occasional cleanup of despawned summons to keep the container slim
217 events.Repeat(30s);
218 break;
221 break;
222 case EVENT_DUST_FLAIL:
223 me->AttackStop();
227 events.Repeat(30s);
228 break;
230 if (Creature const* dustFlail = instance->GetCreature(DATA_DUST_FLAIL))
231 {
232 // because splines need one update tick to update the position, we have to set the orientation manually because we need it NOW.
233 me->SetOrientation(me->GetAbsoluteAngle(dustFlail));
234 me->SetFacingToObject(dustFlail);
237 }
238 else
240 break;
243 break;
247 {
251 }
252 break;
253 default:
254 break;
255 }
257 return;
258 }
259 }
260private:
263};
264
266{
268
269 void JustAppeared() override
270 {
273 me->SetCorpseDelay(5); // Frenzied Crocolisks despawn 5 seconds after death
274
275 if (Unit* victim = SelectTarget(SelectTargetMethod::Random, 0, 500.f, true, true, SPELL_SCENT_OF_BLOOD))
277 }
278};
279
280static constexpr float AUGH_DISTANCE_TO_BOSS = 20.f;
281
283{
284 npc_lockmaw_augh_add(Creature* creature) : ScriptedAI(creature), _instance(nullptr) { }
285
286 void InitializeAI() override
287 {
289
290 if (me->GetEntry() == NPC_AUGH_ADD_1)
292 }
293
294 void JustAppeared() override
295 {
296 if (me->GetEntry() == NPC_AUGH_ADD_1)
297 {
301 }
302 else
303 {
307 }
308 }
309
310 void MovementInform(uint32 motionType, uint32 pointId) override
311 {
312 if (motionType != POINT_MOTION_TYPE && pointId != POINT_PARALYTIC_BLOW_DART)
313 return;
314
317 }
318
319 void UpdateAI(uint32 diff) override
320 {
321 // Augh does perform events even if he is not engaged, so we do not return here
322 UpdateVictim();
323
324 _events.Update(diff);
325 while (uint32 eventId = _events.ExecuteEvent())
326 {
327 switch (eventId)
328 {
330 {
333 if (!lockmaw)
334 {
335 // This should never happen at this stage, but just to be sure....
337 return;
338 }
340 break;
341 }
344 break;
348 break;
349 case EVENT_SCREAM:
352 break;
353 case EVENT_SMOKE_BOMB:
355 me->DespawnOrUnsummon(3s + 500ms);
356 break;
357 case EVENT_WHIRLWIND:
362 break;
363 case EVENT_STEALTHED:
365 break;
367 me->AttackStop();
369 if (Creature* addStalker = me->FindNearestCreature(NPC_ADD_STALKER, 200.f))
370 me->GetMotionMaster()->MovePoint(0, addStalker->GetPosition());
372 break;
373 default:
374 break;
375 }
376 }
377 }
378
379private:
382};
383
385{
386 npc_lockmaw_augh_boss(Creature* creature) : ScriptedAI(creature), _instance(nullptr) { }
387
388 void InitializeAI() override
389 {
393 else
395
397 }
398
399 void JustAppeared() override
400 {
402 {
405 }
406 }
407
408 void JustEngagedWith(Unit* /*who*/) override
409 {
417 }
418
419 void EnterEvadeMode(EvadeReason /*why*/) override
420 {
422 me->DespawnOrUnsummon(0s, 30s);
423 }
424
425 void MovementInform(uint32 motionType, uint32 pointId) override
426 {
427 if (motionType != POINT_MOTION_TYPE && pointId != POINT_AUGH_HOME_POSITION)
428 return;
429
432
435 }
436
437 void UpdateAI(uint32 diff) override
438 {
440 return;
441
442 _events.Update(diff);
443
445 return;
446
447 while (uint32 eventId = _events.ExecuteEvent())
448 {
449 switch (eventId)
450 {
454 break;
458 break;
462 break;
466 break;
470 break;
474 break;
477 _events.Repeat(10s, 15s);
478 break;
479 case EVENT_WHIRLWIND:
482 _events.Repeat(29s);
483 break;
486 _events.Repeat(28s);
487 break;
488 default:
489 break;
490 }
491
493 return;
494 }
495 }
496
497private:
500};
501
503{
504 bool Validate(SpellInfo const* /*spellInfo*/) override
505 {
507 }
508
509 void SelectTarget(std::list<WorldObject*>& targets)
510 {
511 if (targets.size() <= 1)
512 return;
513
514 std::list<WorldObject*> targetsCopy = targets;
515 targetsCopy.remove_if([caster = GetCaster()](WorldObject const* target)
516 {
517 return caster->GetVictim() != target;
518 });
519
520 if (!targetsCopy.empty())
521 {
522 Trinity::Containers::RandomResize(targetsCopy, 1);
523 targets = targetsCopy;
524 }
525 else
527 }
528
530 {
531 Unit* caster = GetCaster();
532 if (!caster)
533 return;
534
535 InstanceScript* instance = caster->GetInstanceScript();
536 if (!instance)
537 return;
538
539 // Shuffle the stored add stalkers so that we will get four random add stalkers in the next step below
541
542 for (uint32 i = DATA_ADD_STALKER_1; i <= DATA_ADD_STALKER_4; ++i)
543 if (Creature* addStalker = ObjectAccessor::GetCreature(*caster, instance->GetGuidData(i)))
544 addStalker->CastSpell(nullptr, SPELL_SUMMON_CROCOLISK);
545 }
546
547 void Register() override
548 {
551 }
552};
553
555{
561}
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_ENGAGE
@ POINT_MOTION_TYPE
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_SRC_AREA_ENEMY
@ EMOTE_STATE_SPELL_CHANNEL_OMNI
@ EMOTE_ONESHOT_NONE
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:230
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
#define SpellCastFn(F)
Definition: SpellScript.h:825
EvadeReason
Definition: UnitAICommon.h:30
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_FLAG_UNINTERACTIBLE
Definition: UnitDefines.h:169
@ UNIT_STATE_CASTING
Definition: Unit.h:270
static constexpr float AUGH_DISTANCE_TO_BOSS
LockmawAughAddType
LockmawTexts
@ SAY_HARASS_PLAYER
@ SAY_SCREAM
@ SAY_INTRO_2
@ SAY_ANNOUNCE_APPEARANCE
@ SAY_INTRO_1
@ SAY_INTRO_3
@ SAY_INTRO_4
@ SAY_INTRO_5
static constexpr float SCENT_OF_BLOOD_THREAT_AMOUNT
void AddSC_boss_lockmaw()
LockmawMovemPoints
@ POINT_AUGH_HOME_POSITION
@ POINT_PARALYTIC_BLOW_DART
LockmawEvents
@ EVENT_DRAGONS_BREATH
@ EVENT_SAY_INTRO_4
@ EVENT_SUMMON_AUGH_ADD
@ EVENT_VENOMOUS_RAGE
@ EVENT_SAY_INTRO_5
@ EVENT_SAY_INTRO_3
@ EVENT_WHIRLWIND
@ EVENT_MOVE_TOWARDS_BOSS
@ EVENT_VISCOUS_POISON
@ EVENT_CHANNEL_DUST_FLAIL
@ EVENT_TURN_AGGRESSIVE
@ EVENT_TURN_ATTACKABLE
@ EVENT_LEAVE_ARENA
@ EVENT_DUST_FLAIL
@ EVENT_STEALTHED
@ EVENT_SET_EMOTE_STATE
@ EVENT_SCREAM
@ EVENT_HARASS_PLAYERS
@ EVENT_PARALYTIC_BLOW_DART
@ EVENT_SMOKE_BOMB
@ EVENT_SAY_INTRO_2
@ EVENT_SCENT_OF_BLOOD
LockmawPhases
@ PHASE_INTRO
@ PHASE_COMBAT
LockmawSpells
@ SPELL_DUST_FLAIL
@ SPELL_AUGH_2
@ SPELL_AUGH_1
@ SPELL_SMOKE_BOMB
@ SPELL_RANDOM_AGGRO_TAUNT
@ SPELL_DRAGONS_BREATH
@ SPELL_SUMMON_CROCOLISK
@ SPELL_STEALTHED
@ SPELL_VISCOUS_POISON
@ SPELL_PARALYTIC_BLOW_DART
@ SPELL_DUST_FLAIL_PERIODIC
@ SPELL_FRENZY
@ SPELL_VENOMOUS_RAGE
@ SPELL_WHIRLWIND_BOSS
@ SPELL_DUST_FLAIL_CHANNELED
@ SPELL_WHIRLWIND
@ SPELL_SCENT_OF_BLOOD
static Position const AughRespawnPosition
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
void JustDied(Unit *) override
void _DespawnAtEvade(Seconds delayToRespawn=30s, Creature *who=nullptr)
SummonList summons
EventMap events
void DoZoneInCombat()
Definition: CreatureAI.h:161
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool _EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:299
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
void SetCorpseDelay(uint32 delay, bool ignoreCorpseDecayRatio=false)
Definition: Creature.h:104
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void Repeat(Milliseconds time)
Definition: EventMap.cpp:63
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
bool IsInPhase(uint8 phase) const
Definition: EventMap.h:217
void SetPhase(uint8 phase)
Definition: EventMap.cpp:28
void DoRemoveAurasDueToSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
Creature * GetCreature(uint32 type)
virtual ObjectGuid GetGuidData(uint32 type) const override
void SendEncounterUnit(EncounterFrameType type, Unit const *unit, Optional< int32 > param1={}, Optional< int32 > param2={})
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
uint32 GetEntry() const
Definition: Object.h:161
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
HookList< CastHandler > AfterCast
Definition: SpellScript.h:824
Unit * GetCaster() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
void RemoveNotExisting()
void Summon(Creature const *summon)
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:12671
void SetEmoteState(Emote emote)
Definition: Unit.h:852
uint64 GetHealth() const
Definition: Unit.h:776
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition: Unit.h:781
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
bool AttackStop()
Definition: Unit.cpp:5781
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:834
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
bool IsOutdoors() const
Definition: Object.h:549
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
virtual uint32 GetData(uint32) const
Definition: ZoneScript.h:91
virtual void SetData(uint32, uint32)
Definition: ZoneScript.h:92
void SelectTarget(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
@ NPC_ADD_STALKER
@ NPC_AUGH_ADD_1
@ NPC_DUST_FLAIL_CASTER
@ DATA_DUST_FLAIL
@ DATA_HEROIC_AUGH_DESPAWNED
@ DATA_ADD_STALKER_1
@ DATA_SHUFFLE_ADD_STALKERS
@ DATA_ADD_STALKER_4
#define RegisterLostCityOfTheTolvirAI(ai_name)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:67
constexpr void SetOrientation(float orientation)
Definition: Position.h:71
float GetAbsoluteAngle(float x, float y) const
Definition: Position.h:125
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr void Relocate(float x, float y)
Definition: Position.h:63
constexpr float GetOrientation() const
Definition: Position.h:79
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
LockmawAughAddType _aughAddType
void EnterEvadeMode(EvadeReason) override
void JustEngagedWith(Unit *who) override
bool CanAIAttack(Unit const *victim) const override
void JustDied(Unit *killer) override
void JustSummoned(Creature *summon) override
boss_lockmaw(Creature *creature)
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void UpdateAI(uint32 diff) override
InstanceScript * _instance
void UpdateAI(uint32 diff) override
npc_lockmaw_augh_add(Creature *creature)
void MovementInform(uint32 motionType, uint32 pointId) override
void JustAppeared() override
void InitializeAI() override
InstanceScript * _instance
void EnterEvadeMode(EvadeReason) override
void JustAppeared() override
npc_lockmaw_augh_boss(Creature *creature)
void JustEngagedWith(Unit *) override
void UpdateAI(uint32 diff) override
void InitializeAI() override
void MovementInform(uint32 motionType, uint32 pointId) override
npc_lockmaw_frenzied_crocolisk(Creature *creature)