TrinityCore
boss_argent_challenge.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/* ScriptData
19SDName: Argent Challenge Encounter.
20SD%Complete: 50 %
21SDComment: AI for Argent Soldiers are not implemented. AI from bosses need more improvements.
22SDCategory: Trial of the Champion
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "Containers.h"
27#include "InstanceScript.h"
28#include "MotionMaster.h"
29#include "ObjectAccessor.h"
30#include "ScriptedEscortAI.h"
31#include "SpellScript.h"
32#include "TemporarySummon.h"
34/*
35enum Yells
36{
37 // Eadric the Pure
38 SAY_INTRO = 0,
39 SAY_AGGRO = 1,
40 EMOTE_RADIANCE = 2,
41 EMOTE_HAMMER_RIGHTEOUS = 3,
42 SAY_HAMMER_RIGHTEOUS = 4,
43 SAY_KILL_PLAYER = 5,
44 SAY_DEFEATED = 6,
45
46 // Argent Confessor Paletress
47 SAY_INTRO_1 = 0,
48 SAY_INTRO_2 = 1,
49 SAY_AGGRO = 2,
50 SAY_MEMORY_SUMMON = 3,
51 SAY_MEMORY_DEATH = 4,
52 SAY_KILL_PLAYER = 5,
53 SAY_DEFEATED = 6,
54
55 // Memory of X
56 EMOTE_WAKING_NIGHTMARE = 0
57};
58*/
60{
61 // Eadric the Pure
67
68 // Paletress
69 SPELL_SMITE = 66536,
73 SPELL_RENEW = 66537,
76 SPELL_SHIELD = 66515,
79
80 // Memory of X (Summon)
106
107 // Memory
115
117{
118 public:
119 explicit OrientationCheck(Unit* _caster) : caster(_caster) { }
121 {
122 return !object->isInFront(caster, 2.5f) || !object->IsWithinDist(caster, 40.0f);
123 }
124
125 private:
127};
128
129// 66862, 67681 - Radiance
131{
132 public:
133 spell_eadric_radiance() : SpellScriptLoader("spell_eadric_radiance") { }
135 {
136 void FilterTargets(std::list<WorldObject*>& unitList)
137 {
138 unitList.remove_if(OrientationCheck(GetCaster()));
139 }
140
141 void Register() override
142 {
145 }
146 };
147
148 SpellScript* GetSpellScript() const override
149 {
151 }
152};
153
155{
156public:
157 boss_eadric() : CreatureScript("boss_eadric") { }
158 struct boss_eadricAI : public ScriptedAI
159 {
160 boss_eadricAI(Creature* creature) : ScriptedAI(creature)
161 {
162 Initialize();
163 instance = creature->GetInstanceScript();
164 creature->SetReactState(REACT_PASSIVE);
166 }
167
169 {
170 uiVenganceTimer = 10000;
171 uiRadianceTimer = 16000;
172 uiHammerJusticeTimer = 25000;
173 uiResetTimer = 5000;
174
175 bDone = false;
176 }
177
179
184
185 bool bDone;
186
187 void Reset() override
188 {
189 Initialize();
190 }
191
192 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
193 {
194 if (damage >= me->GetHealth())
195 {
196 damage = 0;
199 bDone = true;
200 }
201 }
202
203 void MovementInform(uint32 MovementType, uint32 /*Data*/) override
204 {
205 if (MovementType != POINT_MOTION_TYPE)
206 return;
207
209
211 }
212
213 void UpdateAI(uint32 uiDiff) override
214 {
215 if (bDone && uiResetTimer <= uiDiff)
216 {
217 me->GetMotionMaster()->MovePoint(0, 746.87f, 665.87f, 411.75f);
218 bDone = false;
219 } else uiResetTimer -= uiDiff;
220
221 if (!UpdateVictim())
222 return;
223
224 if (uiHammerJusticeTimer <= uiDiff)
225 {
227
228 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
229 {
230 if (target->IsAlive())
231 {
234 }
235 }
236 uiHammerJusticeTimer = 25000;
237 } else uiHammerJusticeTimer -= uiDiff;
238
239 if (uiVenganceTimer <= uiDiff)
240 {
242
243 uiVenganceTimer = 10000;
244 } else uiVenganceTimer -= uiDiff;
245
246 if (uiRadianceTimer <= uiDiff)
247 {
249
250 uiRadianceTimer = 16000;
251 } else uiRadianceTimer -= uiDiff;
252 }
253 };
254
255 CreatureAI* GetAI(Creature* creature) const override
256 {
257 return GetTrialOfTheChampionAI<boss_eadricAI>(creature);
258 }
259};
260
262{
263public:
264 boss_paletress() : CreatureScript("boss_paletress") { }
265
267 {
268 boss_paletressAI(Creature* creature) : ScriptedAI(creature)
269 {
270 Initialize();
271 instance = creature->GetInstanceScript();
272
273 creature->SetReactState(REACT_PASSIVE);
275 creature->RestoreFaction();
276 }
277
279 {
280 uiHolyFireTimer = urand(9000, 12000);
281 uiHolySmiteTimer = urand(5000, 7000);
282 uiRenewTimer = urand(2000, 5000);
283
284 uiResetTimer = 7000;
285
286 bHealth = false;
287 bDone = false;
288 }
289
292
294 bool bDone;
295
300
301 void Reset() override
302 {
304
305 Initialize();
306
308 if (pMemory->IsAlive())
309 pMemory->RemoveFromWorld();
310 }
311
312 void SetData(uint32 uiId, uint32 /*uiValue*/) override
313 {
314 if (uiId == 1)
316 }
317
318 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
319 {
320 if (damage >= me->GetHealth())
321 {
322 damage = 0;
325 bDone = true;
326 }
327 }
328
329 void MovementInform(uint32 MovementType, uint32 Point) override
330 {
331 if (MovementType != POINT_MOTION_TYPE || Point != 0)
332 return;
333
335
337 }
338
339 void UpdateAI(uint32 uiDiff) override
340 {
341 if (bDone && uiResetTimer <= uiDiff)
342 {
343 me->GetMotionMaster()->MovePoint(0, 746.87f, 665.87f, 411.75f);
344 bDone = false;
345 } else uiResetTimer -= uiDiff;
346
347 if (!UpdateVictim())
348 return;
349
350 if (uiHolyFireTimer <= uiDiff)
351 {
352 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
353 {
354 if (target->IsAlive())
355 DoCast(target, SPELL_HOLY_FIRE);
356 }
357 if (me->HasAura(SPELL_SHIELD))
358 uiHolyFireTimer = 13000;
359 else
360 uiHolyFireTimer = urand(9000, 12000);
361 } else uiHolyFireTimer -= uiDiff;
362
363 if (uiHolySmiteTimer <= uiDiff)
364 {
365 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
366 {
367 if (target->IsAlive())
368 DoCast(target, SPELL_SMITE);
369 }
370 if (me->HasAura(SPELL_SHIELD))
371 uiHolySmiteTimer = 9000;
372 else
373 uiHolySmiteTimer = urand(5000, 7000);
374 } else uiHolySmiteTimer -= uiDiff;
375
376 if (me->HasAura(SPELL_SHIELD))
377 {
378 if (uiRenewTimer <= uiDiff)
379 {
381 uint8 uiTarget = urand(0, 1);
382 switch (uiTarget)
383 {
384 case 0:
386 break;
387 case 1:
389 if (pMemory->IsAlive())
390 DoCast(pMemory, SPELL_RENEW);
391 break;
392 }
393 uiRenewTimer = urand(15000, 17000);
394 } else uiRenewTimer -= uiDiff;
395 }
396
397 if (!bHealth && !HealthAbovePct(25))
398 {
403 DoCastAOE(SPELL_CONFESS, false);
404
405 bHealth = true;
406 }
407 }
408
409 void JustSummoned(Creature* summon) override
410 {
411 MemoryGUID = summon->GetGUID();
412 }
413 };
414
415 CreatureAI* GetAI(Creature* creature) const override
416 {
417 return GetTrialOfTheChampionAI<boss_paletressAI>(creature);
418 }
419};
420
422{
423public:
424 npc_memory() : CreatureScript("npc_memory") { }
425
426 struct npc_memoryAI : public ScriptedAI
427 {
428 npc_memoryAI(Creature* creature) : ScriptedAI(creature)
429 {
430 Initialize();
431 }
432
434 {
435 uiOldWoundsTimer = 12000;
436 uiShadowPastTimer = 5000;
437 uiWakingNightmare = 7000;
438 }
439
443
444 void Reset() override
445 {
446 Initialize();
447 }
448
449 void UpdateAI(uint32 uiDiff) override
450 {
451 if (!UpdateVictim())
452 return;
453
454 if (uiOldWoundsTimer <= uiDiff)
455 {
457 {
458 if (target->IsAlive())
459 DoCast(target, SPELL_OLD_WOUNDS);
460 }
461 uiOldWoundsTimer = 12000;
462 }else uiOldWoundsTimer -= uiDiff;
463
464 if (uiWakingNightmare <= uiDiff)
465 {
467 uiWakingNightmare = 7000;
468 }else uiWakingNightmare -= uiDiff;
469
470 if (uiShadowPastTimer <= uiDiff)
471 {
473 {
474 if (target->IsAlive())
475 DoCast(target, SPELL_SHADOWS_PAST);
476 }
477 uiShadowPastTimer = 5000;
478 }else uiShadowPastTimer -= uiDiff;
479 }
480
481 void JustDied(Unit* /*killer*/) override
482 {
483 if (TempSummon* summ = me->ToTempSummon())
484 if (Unit* summoner = summ->GetSummonerUnit())
485 if (summoner->IsAlive())
486 summoner->GetAI()->SetData(1, 0);
487 }
488 };
489
490 CreatureAI* GetAI(Creature* creature) const override
491 {
492 return GetTrialOfTheChampionAI<npc_memoryAI>(creature);
493 }
494};
495
497{
498public:
499 npc_argent_soldier() : CreatureScript("npc_argent_soldier") { }
500
501 // THIS AI NEEDS MORE IMPROVEMENTS
503 {
505 {
506 instance = creature->GetInstanceScript();
508 SetDespawnAtEnd(false);
509 uiWaypoint = 0;
510 }
511
513
515
516 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
517 {
518 if (waypointId == 0)
519 {
520 switch (uiWaypoint)
521 {
522 case 0:
523 me->SetFacingTo(5.81f);
524 break;
525 case 1:
526 me->SetFacingTo(4.60f);
527 break;
528 case 2:
529 me->SetFacingTo(2.79f);
530 break;
531 }
532 }
533 }
534
535 void SetData(uint32 uiType, uint32 /*uiData*/) override
536 {
537 switch (me->GetEntry())
538 {
540 switch (uiType)
541 {
542 case 0:
543 AddWaypoint(0, 712.14f, 628.42f, 411.88f, true);
544 break;
545 case 1:
546 AddWaypoint(0, 742.44f, 650.29f, 411.79f, true);
547 break;
548 case 2:
549 AddWaypoint(0, 783.33f, 615.29f, 411.84f, true);
550 break;
551 }
552 break;
553 case NPC_ARGENT_MONK:
554 switch (uiType)
555 {
556 case 0:
557 AddWaypoint(0, 713.12f, 632.97f, 411.90f, true);
558 break;
559 case 1:
560 AddWaypoint(0, 746.73f, 650.24f, 411.56f, true);
561 break;
562 case 2:
563 AddWaypoint(0, 781.32f, 610.54f, 411.82f, true);
564 break;
565 }
566 break;
567 case NPC_PRIESTESS:
568 switch (uiType)
569 {
570 case 0:
571 AddWaypoint(0, 715.06f, 637.07f, 411.91f, true);
572 break;
573 case 1:
574 AddWaypoint(0, 750.72f, 650.20f, 411.77f, true);
575 break;
576 case 2:
577 AddWaypoint(0, 779.77f, 607.03f, 411.81f, true);
578 break;
579 }
580 break;
581 }
582
583 Start(false);
584 uiWaypoint = uiType;
585 }
586
587 void JustDied(Unit* /*killer*/) override
588 {
590 }
591 };
592
593 CreatureAI* GetAI(Creature* creature) const override
594 {
595 return GetTrialOfTheChampionAI<npc_argent_soldierAI>(creature);
596 }
597};
598
599uint32 constexpr memorySpellId[25] =
600{
626};
627
628// 66545 - Summon Memory
630{
631 public:
632 spell_paletress_summon_memory() : SpellScriptLoader("spell_paletress_summon_memory") { }
633
635 {
636 bool Validate(SpellInfo const* /*spellInfo*/) override
637 {
639 }
640
641 void FilterTargets(std::list<WorldObject*>& targets)
642 {
643 if (targets.empty())
644 return;
645
647 targets.clear();
648 targets.push_back(target);
649 }
650
651 void HandleScript(SpellEffIndex /*effIndex*/)
652 {
654 .SetOriginalCaster(GetCaster()->GetGUID()));
655 }
656
657 void Register() override
658 {
661 }
662 };
663
664 SpellScript* GetSpellScript() const override
665 {
667 }
668};
669
671{
672 new boss_eadric();
674 new boss_paletress();
675 new npc_memory();
676 new npc_argent_soldier();
678}
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
@ DONE
@ POINT_MOTION_TYPE
Spells
Definition: PlayerAI.cpp:32
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ FACTION_FRIENDLY
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
@ REACT_DEFENSIVE
Definition: UnitDefines.h:507
@ REACT_PASSIVE
Definition: UnitDefines.h:506
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:145
@ SPELL_SHADOWS_PAST_H
@ SPELL_MEMORY_GRUUL
@ SPELL_MEMORY_HEROD
@ SPELL_VENGEANCE
@ SPELL_MEMORY_ENTROPIUS
@ SPELL_MEMORY_MUTANUS
@ SPELL_WAKING_NIGHTMARE_H
@ SPELL_EADRIC_ACHIEVEMENT
@ SPELL_HAMMER_JUSTICE
@ SPELL_MEMORY_IGNIS
@ SPELL_MEMORY_INGVAR
@ SPELL_HOLY_NOVA
@ SPELL_MEMORY_KALITHRESH
@ SPELL_MEMORY_ONYXIA
@ SPELL_HOLY_FIRE_H
@ SPELL_MEMORY_THUNDERAAN
@ SPELL_MEMORY_CYANIGOSA
@ SPELL_MEMORY_LUCIFRON
@ SPELL_HAMMER_RIGHTEOUS
@ SPELL_OLD_WOUNDS
@ SPELL_MEMORY_VASHJ
@ SPELL_RADIANCE
@ SPELL_MEMORY_VANCLEEF
@ SPELL_MEMORY_HOGGER
@ SPELL_HOLY_FIRE
@ SPELL_MEMORY_ARCHIMONDE
@ SPELL_MEMORY_MALCHEZAAR
@ SPELL_MEMORY_ALGALON
@ SPELL_MEMORY_VEZAX
@ SPELL_SUMMON_MEMORY
@ SPELL_MEMORY_HAKKAR
@ SPELL_MEMORY_DELRISSA
@ SPELL_MEMORY_HEIGAN
@ SPELL_MEMORY_ECK
@ SPELL_WAKING_NIGHTMARE
@ SPELL_MEMORY_CHROMAGGUS
@ SPELL_SHADOWS_PAST
@ SPELL_MEMORY_ILLIDAN
@ SPELL_MEMORY_VEKNILASH
@ SPELL_OLD_WOUNDS_H
uint32 constexpr memorySpellId[25]
void AddSC_boss_argent_challenge()
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:219
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DisappearAndDie()
Definition: Creature.h:83
virtual bool SetBossState(uint32 id, EncounterState state)
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 ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
bool operator()(WorldObject *object)
OrientationCheck(Unit *_caster)
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetCaster() const
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
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
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3685
void RestoreFaction()
Definition: Unit.cpp:11417
void SetFaction(uint32 faction) override
Definition: Unit.h:859
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3089
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
TempSummon * ToTempSummon()
Definition: Unit.h:1756
uint64 GetHealth() const
Definition: Unit.h:776
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
void RemoveAllAuras()
Definition: Unit.cpp:4242
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
virtual uint32 GetData(uint32) const
Definition: ZoneScript.h:91
virtual void SetData(uint32, uint32)
Definition: ZoneScript.h:92
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
void FilterTargets(std::list< WorldObject * > &unitList)
SpellScript * GetSpellScript() const override
SpellScript * GetSpellScript() const override
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
void Start(bool isActiveAttacker=true, ObjectGuid playerGUID=ObjectGuid::Empty, Quest const *quest=nullptr, bool instantRespawn=false, bool canLoopPath=false)
void AddWaypoint(uint32 id, float x, float y, float z, bool run)
void SetDespawnAtEnd(bool despawn)
bool HealthAbovePct(uint32 pct) const
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void MovementInform(uint32 MovementType, uint32) override
void UpdateAI(uint32 uiDiff) override
void MovementInform(uint32 MovementType, uint32 Point) override
void SetData(uint32 uiId, uint32) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void UpdateAI(uint32 uiDiff) override
void JustSummoned(Creature *summon) override
void SetData(uint32 uiType, uint32) override
void WaypointReached(uint32 waypointId, uint32) override
void JustDied(Unit *) override
void UpdateAI(uint32 uiDiff) override
@ NPC_ARGENT_LIGHWIELDER
@ NPC_ARGENT_MONK
@ NPC_PRIESTESS
@ DATA_ARGENT_SOLDIER_DEFEATED
@ BOSS_ARGENT_CHALLENGE_P
@ BOSS_ARGENT_CHALLENGE_E