TrinityCore
Loading...
Searching...
No Matches
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
254 }
255 };
256
257 CreatureAI* GetAI(Creature* creature) const override
258 {
259 return GetTrialOfTheChampionAI<boss_eadricAI>(creature);
260 }
261};
262
264{
265public:
266 boss_paletress() : CreatureScript("boss_paletress") { }
267
269 {
270 boss_paletressAI(Creature* creature) : ScriptedAI(creature)
271 {
272 Initialize();
273 instance = creature->GetInstanceScript();
274
275 creature->SetReactState(REACT_PASSIVE);
277 creature->RestoreFaction();
278 }
279
281 {
282 uiHolyFireTimer = urand(9000, 12000);
283 uiHolySmiteTimer = urand(5000, 7000);
284 uiRenewTimer = urand(2000, 5000);
285
286 uiResetTimer = 7000;
287
288 bHealth = false;
289 bDone = false;
290 }
291
294
296 bool bDone;
297
302
303 void Reset() override
304 {
306
307 Initialize();
308
310 if (pMemory->IsAlive())
311 pMemory->RemoveFromWorld();
312 }
313
314 void SetData(uint32 uiId, uint32 /*uiValue*/) override
315 {
316 if (uiId == 1)
318 }
319
320 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
321 {
322 if (damage >= me->GetHealth())
323 {
324 damage = 0;
327 bDone = true;
328 }
329 }
330
331 void MovementInform(uint32 MovementType, uint32 Point) override
332 {
333 if (MovementType != POINT_MOTION_TYPE || Point != 0)
334 return;
335
337
339 }
340
341 void UpdateAI(uint32 uiDiff) override
342 {
343 if (bDone && uiResetTimer <= uiDiff)
344 {
345 me->GetMotionMaster()->MovePoint(0, 746.87f, 665.87f, 411.75f);
346 bDone = false;
347 } else uiResetTimer -= uiDiff;
348
349 if (!UpdateVictim())
350 return;
351
352 if (uiHolyFireTimer <= uiDiff)
353 {
354 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
355 {
356 if (target->IsAlive())
357 DoCast(target, SPELL_HOLY_FIRE);
358 }
359 if (me->HasAura(SPELL_SHIELD))
360 uiHolyFireTimer = 13000;
361 else
362 uiHolyFireTimer = urand(9000, 12000);
363 } else uiHolyFireTimer -= uiDiff;
364
365 if (uiHolySmiteTimer <= uiDiff)
366 {
367 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
368 {
369 if (target->IsAlive())
370 DoCast(target, SPELL_SMITE);
371 }
372 if (me->HasAura(SPELL_SHIELD))
373 uiHolySmiteTimer = 9000;
374 else
375 uiHolySmiteTimer = urand(5000, 7000);
376 } else uiHolySmiteTimer -= uiDiff;
377
378 if (me->HasAura(SPELL_SHIELD))
379 {
380 if (uiRenewTimer <= uiDiff)
381 {
383 uint8 uiTarget = urand(0, 1);
384 switch (uiTarget)
385 {
386 case 0:
388 break;
389 case 1:
391 if (pMemory->IsAlive())
392 DoCast(pMemory, SPELL_RENEW);
393 break;
394 }
395 uiRenewTimer = urand(15000, 17000);
396 } else uiRenewTimer -= uiDiff;
397 }
398
399 if (!bHealth && !HealthAbovePct(25))
400 {
405 DoCastAOE(SPELL_CONFESS, false);
406
407 bHealth = true;
408 }
409
411 }
412
413 void JustSummoned(Creature* summon) override
414 {
415 MemoryGUID = summon->GetGUID();
416 }
417 };
418
419 CreatureAI* GetAI(Creature* creature) const override
420 {
421 return GetTrialOfTheChampionAI<boss_paletressAI>(creature);
422 }
423};
424
426{
427public:
428 npc_memory() : CreatureScript("npc_memory") { }
429
430 struct npc_memoryAI : public ScriptedAI
431 {
432 npc_memoryAI(Creature* creature) : ScriptedAI(creature)
433 {
434 Initialize();
435 }
436
438 {
439 uiOldWoundsTimer = 12000;
440 uiShadowPastTimer = 5000;
441 uiWakingNightmare = 7000;
442 }
443
447
448 void Reset() override
449 {
450 Initialize();
451 }
452
453 void UpdateAI(uint32 uiDiff) override
454 {
455 if (!UpdateVictim())
456 return;
457
458 if (uiOldWoundsTimer <= uiDiff)
459 {
460 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
461 {
462 if (target->IsAlive())
463 DoCast(target, SPELL_OLD_WOUNDS);
464 }
465 uiOldWoundsTimer = 12000;
466 }else uiOldWoundsTimer -= uiDiff;
467
468 if (uiWakingNightmare <= uiDiff)
469 {
471 uiWakingNightmare = 7000;
472 }else uiWakingNightmare -= uiDiff;
473
474 if (uiShadowPastTimer <= uiDiff)
475 {
476 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
477 {
478 if (target->IsAlive())
479 DoCast(target, SPELL_SHADOWS_PAST);
480 }
481 uiShadowPastTimer = 5000;
482 }else uiShadowPastTimer -= uiDiff;
483
485 }
486
487 void JustDied(Unit* /*killer*/) override
488 {
489 if (TempSummon* summ = me->ToTempSummon())
490 if (Unit* summoner = summ->GetSummonerUnit())
491 if (summoner->IsAlive())
492 summoner->GetAI()->SetData(1, 0);
493 }
494 };
495
496 CreatureAI* GetAI(Creature* creature) const override
497 {
498 return GetTrialOfTheChampionAI<npc_memoryAI>(creature);
499 }
500};
501
503{
504public:
505 npc_argent_soldier() : CreatureScript("npc_argent_soldier") { }
506
507 // THIS AI NEEDS MORE IMPROVEMENTS
509 {
511 {
512 instance = creature->GetInstanceScript();
514 SetDespawnAtEnd(false);
515 uiWaypoint = 0;
516 }
517
519
521
522 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
523 {
524 if (waypointId == 0)
525 {
526 switch (uiWaypoint)
527 {
528 case 0:
529 me->SetFacingTo(5.81f);
530 break;
531 case 1:
532 me->SetFacingTo(4.60f);
533 break;
534 case 2:
535 me->SetFacingTo(2.79f);
536 break;
537 }
538 }
539 }
540
541 void SetData(uint32 uiType, uint32 /*uiData*/) override
542 {
543 switch (me->GetEntry())
544 {
546 switch (uiType)
547 {
548 case 0:
549 AddWaypoint(0, 712.14f, 628.42f, 411.88f, true);
550 break;
551 case 1:
552 AddWaypoint(0, 742.44f, 650.29f, 411.79f, true);
553 break;
554 case 2:
555 AddWaypoint(0, 783.33f, 615.29f, 411.84f, true);
556 break;
557 }
558 break;
559 case NPC_ARGENT_MONK:
560 switch (uiType)
561 {
562 case 0:
563 AddWaypoint(0, 713.12f, 632.97f, 411.90f, true);
564 break;
565 case 1:
566 AddWaypoint(0, 746.73f, 650.24f, 411.56f, true);
567 break;
568 case 2:
569 AddWaypoint(0, 781.32f, 610.54f, 411.82f, true);
570 break;
571 }
572 break;
573 case NPC_PRIESTESS:
574 switch (uiType)
575 {
576 case 0:
577 AddWaypoint(0, 715.06f, 637.07f, 411.91f, true);
578 break;
579 case 1:
580 AddWaypoint(0, 750.72f, 650.20f, 411.77f, true);
581 break;
582 case 2:
583 AddWaypoint(0, 779.77f, 607.03f, 411.81f, true);
584 break;
585 }
586 break;
587 }
588
589 Start(false);
590 uiWaypoint = uiType;
591 }
592
593 void UpdateAI(uint32 uiDiff) override
594 {
595 EscortAI::UpdateAI(uiDiff);
596
597 if (!UpdateVictim())
598 return;
599
601 }
602
603 void JustDied(Unit* /*killer*/) override
604 {
606 }
607 };
608
609 CreatureAI* GetAI(Creature* creature) const override
610 {
611 return GetTrialOfTheChampionAI<npc_argent_soldierAI>(creature);
612 }
613};
614
615uint32 constexpr memorySpellId[25] =
616{
642};
643
644// 66545 - Summon Memory
646{
647 public:
648 spell_paletress_summon_memory() : SpellScriptLoader("spell_paletress_summon_memory") { }
649
651 {
652 bool Validate(SpellInfo const* /*spellInfo*/) override
653 {
655 }
656
657 void FilterTargets(std::list<WorldObject*>& targets)
658 {
659 if (targets.empty())
660 return;
661
663 targets.clear();
664 targets.push_back(target);
665 }
666
667 void HandleScript(SpellEffIndex /*effIndex*/)
668 {
670 .SetOriginalCaster(GetCaster()->GetGUID()));
671 }
672
673 void Register() override
674 {
677 }
678 };
679
680 SpellScript* GetSpellScript() const override
681 {
683 }
684};
685
687{
688 new boss_eadric();
690 new boss_paletress();
691 new npc_memory();
692 new npc_argent_soldier();
694}
uint8_t uint8
Definition: Define.h:145
uint32_t uint32
Definition: Define.h:143
@ 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:499
@ REACT_PASSIVE
Definition: UnitDefines.h:498
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:137
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:160
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:158
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
void DoMeleeAttackIfReady()
Definition: UnitAI.cpp:61
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:114
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:124
Definition: Unit.h:747
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3594
void RestoreFaction()
Definition: Unit.cpp:11497
void SetFaction(uint32 faction) override
Definition: Unit.h:979
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3019
MotionMaster * GetMotionMaster()
Definition: Unit.h:1757
TempSummon * ToTempSummon()
Definition: Unit.h:1863
uint64 GetHealth() const
Definition: Unit.h:896
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12729
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4573
void RemoveAllAuras()
Definition: Unit.cpp:4151
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:953
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1033
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2883
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)
void UpdateAI(uint32 diff) override
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