TrinityCore
boss_nefarian.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 "blackwing_lair.h"
20#include "GameObject.h"
21#include "InstanceScript.h"
22#include "MotionMaster.h"
23#include "Player.h"
24#include "ScriptedCreature.h"
25#include "ScriptedGossip.h"
26#include "TemporarySummon.h"
27
29{
30 // Victor Nefarius
35 // Nefarian
41 // UBRS
49};
50
51enum Says
52{
53 // Nefarius
54 // UBRS
58 // BWL
61 // SAY_VAEL_INTRO = 14, Not used - when he corrupts Vaelastrasz
62
63 // Nefarian
68
79};
80
82{
83 GOSSIP_ID = 6045,
85};
86
88{
89 NEFARIUS_PATH_2 = 11037368,
90 NEFARIUS_PATH_3 = 11037376
91};
92
94{
97};
98
100{
108 // UBRS
109 NPC_GYTH = 10339
111
113{
114 // Victor Nefarius
115 // UBRS Spells
116 SPELL_CHROMATIC_CHAOS = 16337, // Self Cast hits 10339
117 SPELL_VAELASTRASZZ_SPAWN = 16354, // Self Cast Depawn one sec after
118 // BWL Spells
122 SPELL_FEAR = 22678,
123
125
126 // Nefarian
133
134 SPELL_MAGE = 23410, // wild magic
135 SPELL_WARRIOR = 23397, // beserk
136 SPELL_DRUID = 23398, // cat form
137 SPELL_PRIEST = 23401, // corrupted healing
138 SPELL_PALADIN = 23418, // syphon blessing
139 SPELL_SHAMAN = 23425, // totems
140 SPELL_WARLOCK = 23427, // infernals
141 SPELL_HUNTER = 23436, // bow broke
142 SPELL_ROGUE = 23414, // Paralise
143 SPELL_DEATH_KNIGHT = 49576 // Death Grip
144
145// 19484
146// 22664
147// 22674
148// 22666
150
151Position const DrakeSpawnLoc[2] = // drakonid
152{
153 {-7591.151855f, -1204.051880f, 476.800476f, 3.0f},
154 {-7514.598633f, -1150.448853f, 476.796570f, 3.0f}
155};
156
158{
159 {-7449.763672f, -1387.816040f, 526.783691f, 3.0f}, // nefarian spawn
160 {-7535.456543f, -1279.562500f, 476.798706f, 3.0f} // nefarian move
161};
162
164
166{
168 {
169 Initialize();
170 }
171
173 {
174 SpawnedAdds = 0;
175 }
176
177 void Reset() override
178 {
179 Initialize();
180
181 if (me->GetMapId() == 469)
182 {
183 if (!me->FindNearestCreature(NPC_NEFARIAN, 1000.0f, true))
184 _Reset();
185
186 me->SetVisible(true);
191 }
192 }
193
194 void JustReachedHome() override
195 {
196 Reset();
197 }
198
199 void BeginEvent(Player* target)
200 {
201 _JustEngagedWith(target);
202
204
209 me->SetImmuneToPC(false);
210 AttackStart(target);
213 //events.ScheduleEvent(EVENT_MIND_CONTROL, 30s, 35s);
215 }
216
217 void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
218 {
219 if (summon->GetEntry() != NPC_NEFARIAN)
220 {
222 summon->SetUninteractible(true);
225 }
226 }
227
228 void JustSummoned(Creature* /*summon*/) override { }
229
230 void SetData(uint32 type, uint32 data) override
231 {
232 if ( type == 1 && data == 1)
233 {
234 me->StopMoving();
236 }
237
238 if (type == 1 && data == 2)
240 }
241
242 void UpdateAI(uint32 diff) override
243 {
244 if (!UpdateVictim())
245 {
246 events.Update(diff);
247
248 while (uint32 eventId = events.ExecuteEvent())
249 {
250 switch (eventId)
251 {
252 case EVENT_PATH_2:
255 break;
256 case EVENT_CHAOS_1:
257 if (Creature* gyth = me->FindNearestCreature(NPC_GYTH, 75.0f, true))
258 {
259 me->SetFacingToObject(gyth);
261 }
263 break;
264 case EVENT_CHAOS_2:
266 me->SetFacingTo(1.570796f);
267 break;
268 case EVENT_SUCCESS_1:
269 if (Unit* player = me->SelectNearestPlayer(60.0f))
270 {
271 me->SetFacingToObject(player);
273 if (GameObject* portcullis1 = me->FindNearestGameObject(GO_PORTCULLIS_ACTIVE, 65.0f))
274 portcullis1->SetGoState(GO_STATE_ACTIVE);
276 portcullis2->SetGoState(GO_STATE_ACTIVE);
277 }
279 break;
280 case EVENT_SUCCESS_2:
283 break;
284 case EVENT_PATH_3:
286 break;
287 default:
288 break;
289 }
290 }
291 return;
292 }
293
294 // Only do this if we haven't spawned nefarian yet
295 if (UpdateVictim() && SpawnedAdds <= 42)
296 {
297 events.Update(diff);
298
300 return;
301
302 while (uint32 eventId = events.ExecuteEvent())
303 {
304 switch (eventId)
305 {
307 switch (urand(0, 1))
308 {
309 case 0:
311 break;
312 case 1:
313 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
314 DoCast(target, SPELL_SHADOWBOLT);
315 break;
316 }
319 break;
320 case EVENT_FEAR:
321 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
322 DoCast(target, SPELL_FEAR);
324 break;
326 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
329 break;
330 case EVENT_SPAWN_ADD:
331 for (uint8 i=0; i<2; ++i)
332 {
333 uint32 CreatureID;
334 if (urand(0, 2) == 0)
335 CreatureID = NPC_CHROMATIC_DRAKANOID;
336 else
337 CreatureID = Entry[urand(0, 4)];
338 if (Creature* dragon = me->SummonCreature(CreatureID, DrakeSpawnLoc[i]))
339 {
340 dragon->SetFaction(FACTION_DRAGONFLIGHT_BLACK);
341 dragon->AI()->AttackStart(me->GetVictim());
342 }
343
344 if (++SpawnedAdds >= 42)
345 {
346 if (Creature* nefarian = me->SummonCreature(NPC_NEFARIAN, NefarianLoc[0]))
347 {
348 nefarian->setActive(true);
349 nefarian->SetFarVisible(true);
350 nefarian->SetCanFly(true);
351 nefarian->SetDisableGravity(true);
352 nefarian->CastSpell(nullptr, SPELL_SHADOWFLAME_INITIAL);
353 nefarian->GetMotionMaster()->MovePoint(1, NefarianLoc[1]);
354 }
358 me->SetVisible(false);
359 return;
360 }
361 }
363 break;
364 }
365
367 return;
368 }
369 }
370 }
371
372 bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
373 {
374 if (menuId == GOSSIP_ID && gossipListId == GOSSIP_OPTION_ID)
375 {
376 CloseGossipMenuFor(player);
378 BeginEvent(player);
379 }
380 return false;
381 }
382
383 private:
385};
386
387struct boss_nefarian : public BossAI
388{
390 {
391 Initialize();
392 }
393
395 {
396 Phase3 = false;
397 canDespawn = false;
398 DespawnTimer = 30000;
399 }
400
401 void Reset() override
402 {
403 Initialize();
404 }
405
406 void JustReachedHome() override
407 {
408 canDespawn = true;
409 }
410
411 void JustEngagedWith(Unit* /*who*/) override
412 {
417 //events.ScheduleEvent(EVENT_TAILLASH, 10s);
420 }
421
422 void JustDied(Unit* /*killer*/) override
423 {
424 _JustDied();
426 }
427
428 void KilledUnit(Unit* victim) override
429 {
430 if (rand32() % 5)
431 return;
432
433 Talk(SAY_SLAY, victim);
434 }
435
436 void MovementInform(uint32 type, uint32 id) override
437 {
438 if (type != POINT_MOTION_TYPE)
439 return;
440
441 if (id == 1)
442 {
444 if (me->GetVictim())
446 }
447 }
448
449 void UpdateAI(uint32 diff) override
450 {
451 if (canDespawn && DespawnTimer <= diff)
452 {
454
455 std::list<Creature*> constructList;
457 for (std::list<Creature*>::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr)
458 (*itr)->DespawnOrUnsummon();
459
460 } else DespawnTimer -= diff;
461
462 if (!UpdateVictim())
463 return;
464
465 if (canDespawn)
466 canDespawn = false;
467
468 events.Update(diff);
469
471 return;
472
473 while (uint32 eventId = events.ExecuteEvent())
474 {
475 switch (eventId)
476 {
480 break;
481 case EVENT_FEAR:
484 break;
488 break;
489 case EVENT_CLEAVE:
492 break;
493 case EVENT_TAILLASH:
494 // Cast NYI since we need a better check for behind target
497 break;
498 case EVENT_CLASSCALL:
499 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
500 switch (target->GetClass())
501 {
502 case CLASS_MAGE:
503 Talk(SAY_MAGE);
505 break;
506 case CLASS_WARRIOR:
509 break;
510 case CLASS_DRUID:
512 DoCast(target, SPELL_DRUID);
513 break;
514 case CLASS_PRIEST:
517 break;
518 case CLASS_PALADIN:
521 break;
522 case CLASS_SHAMAN:
525 break;
526 case CLASS_WARLOCK:
529 break;
530 case CLASS_HUNTER:
533 break;
534 case CLASS_ROGUE:
537 break;
541 break;
542 default:
543 break;
544 }
546 break;
547 }
548
550 return;
551 }
552
553 // Phase3 begins when health below 20 pct
554 if (!Phase3 && HealthBelowPct(20))
555 {
556 std::list<Creature*> constructList;
558 for (std::list<Creature*>::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr)
559 if ((*itr) && !(*itr)->IsAlive())
560 {
561 (*itr)->Respawn();
562 DoZoneInCombat((*itr));
563 (*itr)->SetUninteractible(false);
564 (*itr)->SetReactState(REACT_AGGRESSIVE);
565 (*itr)->SetStandState(UNIT_STAND_STATE_STAND);
566 }
567
568 Phase3 = true;
570 }
571 }
572
573private:
576 bool Phase3;
577
578};
579
581{
584}
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
@ FAIL
@ POINT_MOTION_TYPE
Spells
Definition: PlayerAI.cpp:32
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
uint32 rand32()
Definition: Random.cpp:70
void CloseGossipMenuFor(Player *player)
@ CLASS_HUNTER
@ CLASS_DRUID
@ CLASS_SHAMAN
@ CLASS_PRIEST
@ CLASS_WARRIOR
@ CLASS_WARLOCK
@ CLASS_MAGE
@ CLASS_DEATH_KNIGHT
@ CLASS_PALADIN
@ CLASS_ROGUE
@ FACTION_FRIENDLY
@ FACTION_DRAGONFLIGHT_BLACK
@ GO_STATE_ACTIVE
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
@ UNIT_STAND_STATE_SIT_HIGH_CHAIR
Definition: UnitDefines.h:48
@ UNIT_STAND_STATE_DEAD
Definition: UnitDefines.h:49
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:42
@ UNIT_NPC_FLAG_GOSSIP
Definition: UnitDefines.h:297
@ UNIT_STATE_CASTING
Definition: Unit.h:270
@ NPC_NEFARIAN
#define RegisterBlackwingLairCreatureAI(ai_name)
@ DATA_NEFARIAN
Says
Position const NefarianLoc[2]
@ GO_PORTCULLIS_TOBOSSROOMS
@ GO_PORTCULLIS_ACTIVE
@ SAY_DEATH
@ SAY_PALADIN
@ SAY_CHAOS_SPELL
@ SAY_WARRIOR
@ SAY_SUCCESS
@ SAY_PRIEST
@ SAY_DRUID
@ SAY_SHAMAN
@ SAY_GAMESBEGIN_2
@ SAY_ROGUE
@ SAY_SLAY
@ SAY_MAGE
@ SAY_GAMESBEGIN_1
@ SAY_RAISE_SKELETONS
@ SAY_RANDOM
@ SAY_HUNTER
@ SAY_DEATH_KNIGHT
@ SAY_WARLOCK
@ SAY_FAILURE
@ NPC_BLACK_DRAKANOID
@ NPC_BONE_CONSTRUCT
@ NPC_BLUE_DRAKANOID
@ NPC_CHROMATIC_DRAKANOID
@ NPC_GREEN_DRAKANOID
@ NPC_GYTH
@ NPC_BRONZE_DRAKANOID
@ NPC_RED_DRAKANOID
uint32 const Entry[5]
@ SPELL_CLEAVE
@ SPELL_SHADOW_COMMAND
@ SPELL_VEILOFSHADOW
@ SPELL_DEATH_KNIGHT
@ SPELL_BELLOWINGROAR
@ SPELL_SHAMAN
@ SPELL_FEAR
@ SPELL_DRUID
@ SPELL_PRIEST
@ SPELL_SHADOWBOLT
@ SPELL_NEFARIANS_BARRIER
@ SPELL_CHROMATIC_CHAOS
@ SPELL_SHADOWBOLT_VOLLEY
@ SPELL_VAELASTRASZZ_SPAWN
@ SPELL_ROGUE
@ SPELL_SHADOWFLAME_INITIAL
@ SPELL_TAILLASH
@ SPELL_PALADIN
@ SPELL_SHADOWFLAME
@ SPELL_WARLOCK
@ SPELL_WARRIOR
@ SPELL_MAGE
@ SPELL_HUNTER
void AddSC_boss_nefarian()
Position const DrakeSpawnLoc[2]
@ NEFARIUS_PATH_2
@ NEFARIUS_PATH_3
Gossip
@ GOSSIP_OPTION_ID
@ GOSSIP_ID
@ EVENT_SUCCESS_3
@ EVENT_CHAOS_1
@ EVENT_SUCCESS_1
@ EVENT_VEILOFSHADOW
@ EVENT_CLASSCALL
@ EVENT_TAILLASH
@ EVENT_CHAOS_2
@ EVENT_SPAWN_ADD
@ EVENT_MIND_CONTROL
@ EVENT_PATH_2
@ EVENT_FEAR
@ EVENT_CLEAVE
@ EVENT_SHADOWFLAME
@ EVENT_PATH_3
@ EVENT_SUCCESS_2
@ EVENT_SHADOW_BOLT
InstanceScript *const instance
void _JustEngagedWith(Unit *who)
EventMap events
void _JustDied()
void DoZoneInCombat()
Definition: CreatureAI.h:161
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
void SetImmuneToPC(bool apply) override
Definition: Creature.h:170
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition: Creature.cpp:577
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
void CancelEvent(uint32 eventId)
Definition: EventMap.cpp:131
virtual bool SetBossState(uint32 id, EncounterState state)
void MovePath(uint32 pathId, bool repeatable, Optional< Milliseconds > duration={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< std::pair< Milliseconds, Milliseconds > > waitTimeRangeAtPathEnd={}, Optional< float > wanderDistanceAtPathEnds={}, Optional< bool > followPathBackwardsFromEndToStart={}, bool generatePath=true)
uint32 GetEntry() const
Definition: Object.h:161
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 DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void SetVisible(bool x)
Definition: Unit.cpp:8351
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3685
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition: Unit.cpp:10100
void SetFaction(uint32 faction) override
Definition: Unit.h:859
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:12671
void StopMoving()
Definition: Unit.cpp:10049
void RemoveNpcFlag(NPCFlags flags)
Definition: Unit.h:983
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
void SetNpcFlag(NPCFlags flags)
Definition: Unit.h:982
Unit * GetVictim() const
Definition: Unit.h:715
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
constexpr uint32 GetMapId() const
Definition: Position.h:201
Player * SelectNearestPlayer(float range) const
Definition: Object.cpp:2210
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition: Object.cpp:2170
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition: Object.cpp:3312
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition: Object.cpp:2025
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
bool HealthBelowPct(uint32 pct) const
void ResetThreatList(Unit *who=nullptr)
void MovementInform(uint32 type, uint32 id) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
void JustReachedHome() override
void Reset() override
void JustEngagedWith(Unit *) override
void KilledUnit(Unit *victim) override
boss_nefarian(Creature *creature)
void BeginEvent(Player *target)
bool OnGossipSelect(Player *player, uint32 menuId, uint32 gossipListId) override
void JustReachedHome() override
void UpdateAI(uint32 diff) override
void SummonedCreatureDies(Creature *summon, Unit *) override
boss_victor_nefarius(Creature *creature)
void Reset() override
void SetData(uint32 type, uint32 data) override
void JustSummoned(Creature *) override