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
155
157{
158public:
159 boss_eadric() : CreatureScript("boss_eadric") { }
160 struct boss_eadricAI : public ScriptedAI
161 {
162 boss_eadricAI(Creature* creature) : ScriptedAI(creature)
163 {
164 Initialize();
165 instance = creature->GetInstanceScript();
166 creature->SetReactState(REACT_PASSIVE);
168 }
169
171 {
172 uiVenganceTimer = 10000;
173 uiRadianceTimer = 16000;
174 uiHammerJusticeTimer = 25000;
175 uiResetTimer = 5000;
176
177 bDone = false;
178 }
179
181
186
187 bool bDone;
188
189 void Reset() override
190 {
191 Initialize();
192 }
193
194 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
195 {
196 if (damage >= me->GetHealth())
197 {
198 damage = 0;
201 bDone = true;
202 }
203 }
204
205 void MovementInform(uint32 MovementType, uint32 /*Data*/) override
206 {
207 if (MovementType != POINT_MOTION_TYPE)
208 return;
209
211
213 }
214
215 void UpdateAI(uint32 uiDiff) override
216 {
217 if (bDone && uiResetTimer <= uiDiff)
218 {
219 me->GetMotionMaster()->MovePoint(0, 746.87f, 665.87f, 411.75f);
220 bDone = false;
221 } else uiResetTimer -= uiDiff;
222
223 if (!UpdateVictim())
224 return;
225
226 if (uiHammerJusticeTimer <= uiDiff)
227 {
229
230 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
231 {
232 if (target->IsAlive())
233 {
236 }
237 }
238 uiHammerJusticeTimer = 25000;
239 } else uiHammerJusticeTimer -= uiDiff;
240
241 if (uiVenganceTimer <= uiDiff)
242 {
244
245 uiVenganceTimer = 10000;
246 } else uiVenganceTimer -= uiDiff;
247
248 if (uiRadianceTimer <= uiDiff)
249 {
251
252 uiRadianceTimer = 16000;
253 } else uiRadianceTimer -= uiDiff;
254
256 }
257 };
258
259 CreatureAI* GetAI(Creature* creature) const override
260 {
261 return GetTrialOfTheChampionAI<boss_eadricAI>(creature);
262 }
263};
264
266{
267public:
268 boss_paletress() : CreatureScript("boss_paletress") { }
269
271 {
272 boss_paletressAI(Creature* creature) : ScriptedAI(creature)
273 {
274 Initialize();
275 instance = creature->GetInstanceScript();
276
277 creature->SetReactState(REACT_PASSIVE);
279 creature->RestoreFaction();
280 }
281
283 {
284 uiHolyFireTimer = urand(9000, 12000);
285 uiHolySmiteTimer = urand(5000, 7000);
286 uiRenewTimer = urand(2000, 5000);
287
288 uiResetTimer = 7000;
289
290 bHealth = false;
291 bDone = false;
292 }
293
296
298 bool bDone;
299
304
305 void Reset() override
306 {
308
309 Initialize();
310
312 if (pMemory->IsAlive())
313 pMemory->RemoveFromWorld();
314 }
315
316 void SetData(uint32 uiId, uint32 /*uiValue*/) override
317 {
318 if (uiId == 1)
320 }
321
322 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
323 {
324 if (damage >= me->GetHealth())
325 {
326 damage = 0;
329 bDone = true;
330 }
331 }
332
333 void MovementInform(uint32 MovementType, uint32 Point) override
334 {
335 if (MovementType != POINT_MOTION_TYPE || Point != 0)
336 return;
337
339
341 }
342
343 void UpdateAI(uint32 uiDiff) override
344 {
345 if (bDone && uiResetTimer <= uiDiff)
346 {
347 me->GetMotionMaster()->MovePoint(0, 746.87f, 665.87f, 411.75f);
348 bDone = false;
349 } else uiResetTimer -= uiDiff;
350
351 if (!UpdateVictim())
352 return;
353
354 if (uiHolyFireTimer <= uiDiff)
355 {
356 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
357 {
358 if (target->IsAlive())
359 DoCast(target, SPELL_HOLY_FIRE);
360 }
361 if (me->HasAura(SPELL_SHIELD))
362 uiHolyFireTimer = 13000;
363 else
364 uiHolyFireTimer = urand(9000, 12000);
365 } else uiHolyFireTimer -= uiDiff;
366
367 if (uiHolySmiteTimer <= uiDiff)
368 {
369 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
370 {
371 if (target->IsAlive())
372 DoCast(target, SPELL_SMITE);
373 }
374 if (me->HasAura(SPELL_SHIELD))
375 uiHolySmiteTimer = 9000;
376 else
377 uiHolySmiteTimer = urand(5000, 7000);
378 } else uiHolySmiteTimer -= uiDiff;
379
380 if (me->HasAura(SPELL_SHIELD))
381 {
382 if (uiRenewTimer <= uiDiff)
383 {
385 uint8 uiTarget = urand(0, 1);
386 switch (uiTarget)
387 {
388 case 0:
390 break;
391 case 1:
393 if (pMemory->IsAlive())
394 DoCast(pMemory, SPELL_RENEW);
395 break;
396 }
397 uiRenewTimer = urand(15000, 17000);
398 } else uiRenewTimer -= uiDiff;
399 }
400
401 if (!bHealth && !HealthAbovePct(25))
402 {
407 DoCastAOE(SPELL_CONFESS, false);
408
409 bHealth = true;
410 }
411
413 }
414
415 void JustSummoned(Creature* summon) override
416 {
417 MemoryGUID = summon->GetGUID();
418 }
419 };
420
421 CreatureAI* GetAI(Creature* creature) const override
422 {
423 return GetTrialOfTheChampionAI<boss_paletressAI>(creature);
424 }
425};
426
428{
429public:
430 npc_memory() : CreatureScript("npc_memory") { }
431
432 struct npc_memoryAI : public ScriptedAI
433 {
434 npc_memoryAI(Creature* creature) : ScriptedAI(creature)
435 {
436 Initialize();
437 }
438
440 {
441 uiOldWoundsTimer = 12000;
442 uiShadowPastTimer = 5000;
443 uiWakingNightmare = 7000;
444 }
445
449
450 void Reset() override
451 {
452 Initialize();
453 }
454
455 void UpdateAI(uint32 uiDiff) override
456 {
457 if (!UpdateVictim())
458 return;
459
460 if (uiOldWoundsTimer <= uiDiff)
461 {
463 {
464 if (target->IsAlive())
465 DoCast(target, SPELL_OLD_WOUNDS);
466 }
467 uiOldWoundsTimer = 12000;
468 }else uiOldWoundsTimer -= uiDiff;
469
470 if (uiWakingNightmare <= uiDiff)
471 {
473 uiWakingNightmare = 7000;
474 }else uiWakingNightmare -= uiDiff;
475
476 if (uiShadowPastTimer <= uiDiff)
477 {
479 {
480 if (target->IsAlive())
481 DoCast(target, SPELL_SHADOWS_PAST);
482 }
483 uiShadowPastTimer = 5000;
484 }else uiShadowPastTimer -= uiDiff;
485
487 }
488
489 void JustDied(Unit* /*killer*/) override
490 {
491 if (TempSummon* summ = me->ToTempSummon())
492 if (Unit* summoner = summ->GetSummonerUnit())
493 if (summoner->IsAlive())
494 summoner->GetAI()->SetData(1, 0);
495 }
496 };
497
498 CreatureAI* GetAI(Creature* creature) const override
499 {
500 return GetTrialOfTheChampionAI<npc_memoryAI>(creature);
501 }
502};
503
505{
506public:
507 npc_argent_soldier() : CreatureScript("npc_argent_soldier") { }
508
509 // THIS AI NEEDS MORE IMPROVEMENTS
511 {
513 {
514 instance = creature->GetInstanceScript();
516 SetDespawnAtEnd(false);
517 uiWaypoint = 0;
518 }
519
521
523
524 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
525 {
526 if (waypointId == 0)
527 {
528 switch (uiWaypoint)
529 {
530 case 0:
531 me->SetFacingTo(5.81f);
532 break;
533 case 1:
534 me->SetFacingTo(4.60f);
535 break;
536 case 2:
537 me->SetFacingTo(2.79f);
538 break;
539 }
540 }
541 }
542
543 void SetData(uint32 uiType, uint32 /*uiData*/) override
544 {
545 switch (me->GetEntry())
546 {
548 switch (uiType)
549 {
550 case 0:
551 AddWaypoint(0, 712.14f, 628.42f, 411.88f, true);
552 break;
553 case 1:
554 AddWaypoint(0, 742.44f, 650.29f, 411.79f, true);
555 break;
556 case 2:
557 AddWaypoint(0, 783.33f, 615.29f, 411.84f, true);
558 break;
559 }
560 break;
561 case NPC_ARGENT_MONK:
562 switch (uiType)
563 {
564 case 0:
565 AddWaypoint(0, 713.12f, 632.97f, 411.90f, true);
566 break;
567 case 1:
568 AddWaypoint(0, 746.73f, 650.24f, 411.56f, true);
569 break;
570 case 2:
571 AddWaypoint(0, 781.32f, 610.54f, 411.82f, true);
572 break;
573 }
574 break;
575 case NPC_PRIESTESS:
576 switch (uiType)
577 {
578 case 0:
579 AddWaypoint(0, 715.06f, 637.07f, 411.91f, true);
580 break;
581 case 1:
582 AddWaypoint(0, 750.72f, 650.20f, 411.77f, true);
583 break;
584 case 2:
585 AddWaypoint(0, 779.77f, 607.03f, 411.81f, true);
586 break;
587 }
588 break;
589 }
590
591 Start(false);
592 uiWaypoint = uiType;
593 }
594
595 void UpdateAI(uint32 uiDiff) override
596 {
597 EscortAI::UpdateAI(uiDiff);
598
599 if (!UpdateVictim())
600 return;
601
603 }
604
609 };
610
611 CreatureAI* GetAI(Creature* creature) const override
612 {
613 return GetTrialOfTheChampionAI<npc_argent_soldierAI>(creature);
614 }
615};
616
645
646// 66545 - Summon Memory
648{
649 public:
650 spell_paletress_summon_memory() : SpellScriptLoader("spell_paletress_summon_memory") { }
651
653 {
655
656 bool Validate(SpellInfo const* /*spellInfo*/) override
657 {
659 }
660
661 void FilterTargets(std::list<WorldObject*>& targets)
662 {
663 if (targets.empty())
664 return;
665
667 targets.clear();
668 targets.push_back(target);
669 }
670
671 void HandleScript(SpellEffIndex /*effIndex*/)
672 {
673 GetHitUnit()->CastSpell(GetHitUnit(), memorySpellId[urand(0, 24)], GetCaster()->GetGUID());
674 }
675
681 };
682
683 SpellScript* GetSpellScript() const override
684 {
686 }
687};
688
690{
691 new boss_eadric();
693 new boss_paletress();
694 new npc_memory();
695 new npc_argent_soldier();
697}
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
@ DONE
@ POINT_MOTION_TYPE
Spells
Definition PlayerAI.cpp:32
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TARGET_UNIT_SRC_AREA_ENEMY
@ FACTION_FRIENDLY
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
@ REACT_DEFENSIVE
@ REACT_PASSIVE
@ UNIT_FLAG_NON_ATTACKABLE
DamageEffectType
Definition Unit.h:352
@ SPELL_SHADOWS_PAST_H
@ SPELL_MEMORY_GRUUL
@ SPELL_MEMORY_HEROD
@ SPELL_MEMORY_ENTROPIUS
@ SPELL_MEMORY_MUTANUS
@ SPELL_WAKING_NIGHTMARE_H
@ SPELL_EADRIC_ACHIEVEMENT
@ SPELL_HAMMER_JUSTICE
@ SPELL_MEMORY_IGNIS
@ SPELL_MEMORY_INGVAR
@ SPELL_MEMORY_KALITHRESH
@ SPELL_MEMORY_ONYXIA
@ SPELL_HOLY_FIRE_H
@ SPELL_MEMORY_THUNDERAAN
@ SPELL_MEMORY_CYANIGOSA
@ SPELL_MEMORY_LUCIFRON
@ SPELL_HAMMER_RIGHTEOUS
@ SPELL_MEMORY_VANCLEEF
@ SPELL_MEMORY_HOGGER
@ SPELL_MEMORY_ARCHIMONDE
@ SPELL_MEMORY_MALCHEZAAR
@ SPELL_MEMORY_ALGALON
@ SPELL_SUMMON_MEMORY
@ SPELL_MEMORY_HAKKAR
@ SPELL_MEMORY_DELRISSA
@ SPELL_MEMORY_HEIGAN
@ SPELL_WAKING_NIGHTMARE
@ SPELL_MEMORY_CHROMAGGUS
@ SPELL_MEMORY_ILLIDAN
@ SPELL_MEMORY_VEKNILASH
void AddSC_boss_argent_challenge()
uint32 const memorySpellId[25]
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
virtual void EnterEvadeMode(EvadeReason why=EVADE_REASON_OTHER)
void SetReactState(ReactStates st)
Definition Creature.h:119
void DisappearAndDie()
Definition Creature.h:73
virtual bool SetBossState(uint32 id, EncounterState state)
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
bool operator()(WorldObject *object)
OrientationCheck(Unit *_caster)
Unit * GetCaster() const
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3638
void RestoreFaction()
Definition Unit.cpp:11776
void SetFaction(uint32 faction) override
Definition Unit.h:974
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
TempSummon * ToTempSummon()
Definition Unit.h:1794
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
uint32 GetHealth() const
Definition Unit.h:913
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13250
void RemoveAllAuras()
Definition Unit.cpp:4157
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
virtual uint32 GetData(uint32) const
Definition ZoneScript.h:55
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:56
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
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)
PrepareSpellScript(spell_eadric_radiance_SpellScript)
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:108
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 UpdateAI(uint32 uiDiff) override
@ NPC_ARGENT_LIGHWIELDER
@ NPC_ARGENT_MONK
@ NPC_PRIESTESS
@ DATA_ARGENT_SOLDIER_DEFEATED
@ BOSS_ARGENT_CHALLENGE_P
@ BOSS_ARGENT_CHALLENGE_E