TrinityCore
Loading...
Searching...
No Matches
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 "blackwing_lair.h"
19#include "GameObject.h"
20#include "InstanceScript.h"
21#include "MotionMaster.h"
22#include "ObjectAccessor.h"
23#include "Player.h"
24#include "ScriptedCreature.h"
25#include "ScriptedGossip.h"
26#include "ScriptMgr.h"
27#include "TemporarySummon.h"
28
51
53{
54 // Nefarius
55 // UBRS
59 // BWL
62 // SAY_VAEL_INTRO = 14, Not used - when he corrupts Vaelastrasz
63
64 // Nefarian
81};
82
88
90{
91 NEFARIUS_PATH_2 = 11037368,
92 NEFARIUS_PATH_3 = 11037376
93};
94
100
113
115{
116 // Victor Nefarius
117 // UBRS Spells
118 SPELL_CHROMATIC_CHAOS = 16337, // Self Cast hits 10339
119 SPELL_VAELASTRASZZ_SPAWN = 16354, // Self Cast Depawn one sec after
120 // BWL Spells
124 SPELL_FEAR = 22678,
125
127
128 // Nefarian
135
136 SPELL_MAGE = 23410, // wild magic
137 SPELL_WARRIOR = 23397, // beserk
138 SPELL_DRUID = 23398, // cat form
139 SPELL_PRIEST = 23401, // corrupted healing
140 SPELL_PALADIN = 23418, // syphon blessing
141 SPELL_SHAMAN = 23425, // totems
142 SPELL_WARLOCK = 23427, // infernals
143 SPELL_HUNTER = 23436, // bow broke
144 SPELL_ROGUE = 23414, // Paralise
145 SPELL_DEATH_KNIGHT = 49576 // Death Grip
146
147// 19484
148// 22664
149// 22674
150// 22666
152
158
159Position const NefarianDrakeSpawnLoc[2] = // drakonid
160{
161 { -7591.151855f, -1204.051880f, 476.800476f, 3.0f },
162 { -7514.598633f, -1150.448853f, 476.796570f, 3.0f }
163};
164
166{
167 { -7449.763672f, -1387.816040f, 526.783691f, 3.0f }, // nefarian spawn
168 { -7535.456543f, -1279.562500f, 476.798706f, 3.0f } // nefarian move
169};
170
172
174{
176 {
177 Initialize();
178 }
179
181 {
182 _spawnedAdds = 0;
183 }
184
185 void Reset() override
186 {
187 Initialize();
188
189 if (!me->FindNearestCreature(NPC_NEFARIAN, 1000.0f, true))
190 _Reset();
191
192 me->SetVisible(true);
193 me->SetPhaseMask(1, true);
198 }
199
200 void JustReachedHome() override
201 {
202 Reset();
203 }
204
205 void BeginEvent(Player* target)
206 {
207 _JustEngagedWith(target);
208
210
215 me->SetImmuneToPC(false);
216 AttackStart(target);
219 //events.ScheduleEvent(EVENT_MIND_CONTROL, 30s, 35s);
221 }
222
223 void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
224 {
225 if (summon->GetEntry() != NPC_NEFARIAN && summon->GetEntry() != NPC_BONE_CONSTRUCT)
226 {
228 summon->SetHomePosition(summon->GetPosition());
232 }
233 }
234
235 void JustSummoned(Creature* summon) override
236 {
237 summons.Summon(summon);
238 }
239
240 void SetData(uint32 type, uint32 data) override
241 {
242 if ( type == 1 && data == 1)
243 {
244 me->StopMoving();
246 }
247
248 if (type == 1 && data == 2)
250 }
251
252 void DoAction(int32 param) override
253 {
254 switch (param)
255 {
258 break;
260 for (ObjectGuid const& summon : summons)
261 {
262 if (Creature* boneConstruct = ObjectAccessor::GetCreature(*me, summon))
263 if (boneConstruct->GetEntry() == NPC_BONE_CONSTRUCT && !boneConstruct->IsAlive())
264 {
265 boneConstruct->SetVisible(true);
266 boneConstruct->RemoveAllGameObjects();
267 boneConstruct->SetSpawnHealth();
268 boneConstruct->setDeathState(ALIVE);
269 boneConstruct->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
270 boneConstruct->SetStandState(UNIT_STAND_STATE_STAND);
271 SetAggressiveStateAfter(1s, boneConstruct, true, me);
272 }
273 }
275 break;
276 default:
277 break;
278 }
279 }
280
281 void UpdateAI(uint32 diff) override
282 {
283 if (!UpdateVictim())
284 {
285 events.Update(diff);
286
287 while (uint32 eventId = events.ExecuteEvent())
288 {
289 switch (eventId)
290 {
291 case EVENT_PATH_2:
294 break;
295 case EVENT_CHAOS_1:
296 if (Creature* gyth = me->FindNearestCreature(NPC_GYTH, 75.0f, true))
297 {
298 me->SetFacingToObject(gyth);
300 }
302 break;
303 case EVENT_CHAOS_2:
305 me->SetFacingTo(1.570796f);
306 break;
307 case EVENT_SUCCESS_1:
308 if (Unit* player = me->SelectNearestPlayer(60.0f))
309 {
310 me->SetFacingToObject(player);
312 if (GameObject* portcullis1 = me->FindNearestGameObject(GO_PORTCULLIS_ACTIVE, 65.0f))
313 portcullis1->SetGoState(GO_STATE_ACTIVE);
315 portcullis2->SetGoState(GO_STATE_ACTIVE);
316 }
318 break;
319 case EVENT_SUCCESS_2:
322 break;
323 case EVENT_PATH_3:
325 break;
326 default:
327 break;
328 }
329 }
330 return;
331 }
332
333 // Only do this if we haven't spawned nefarian yet
334 if (UpdateVictim() && _spawnedAdds <= 42)
335 {
336 events.Update(diff);
337
339 return;
340
341 while (uint32 eventId = events.ExecuteEvent())
342 {
343 switch (eventId)
344 {
346 switch (urand(0, 1))
347 {
348 case 0:
350 break;
351 case 1:
352 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
353 DoCast(target, SPELL_SHADOWBOLT);
354 break;
355 }
358 break;
359 case EVENT_FEAR:
360 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
361 DoCast(target, SPELL_FEAR);
363 break;
365 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
368 break;
369 case EVENT_SPAWN_ADD:
370 for (uint8 i = 0; i < 2; ++i)
371 {
372 uint32 CreatureID;
373 if (urand(0, 2) == 0)
374 CreatureID = NPC_CHROMATIC_DRAKANOID;
375 else
376 CreatureID = NefarianEntry[urand(0, 4)];
377 if (Creature* dragon = me->SummonCreature(CreatureID, NefarianDrakeSpawnLoc[i]))
378 {
379 dragon->SetFaction(FACTION_DRAGONFLIGHT_BLACK);
380 dragon->AI()->AttackStart(me->GetVictim());
381 }
382
383 if (++_spawnedAdds >= 42)
384 {
385 if (Creature* nefarian = me->SummonCreature(NPC_NEFARIAN, NefarianLoc[0]))
386 {
387 nefarian->setActive(true);
388 nefarian->SetFarVisible(true);
389 nefarian->SetCanFly(true);
390 nefarian->SetDisableGravity(true);
391 nefarian->CastSpell(nullptr, SPELL_SHADOWFLAME_INITIAL);
392 nefarian->SetHomePosition(NefarianLoc[1]);
393 nefarian->GetMotionMaster()->MovePoint(1, NefarianLoc[1]);
394 }
398 me->SetVisible(false);
399 return;
400 }
401 }
403 break;
404 }
405
407 return;
408 }
409 }
410 }
411
412 bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
413 {
414 if (menuId == GOSSIP_ID && gossipListId == GOSSIP_OPTION_ID)
415 {
416 CloseGossipMenuFor(player);
418 BeginEvent(player);
419 }
420 return false;
421 }
422
423private:
425};
426
427struct boss_nefarian : public BossAI
428{
430 {
431 Initialize();
432 }
433
435 {
436 _phase3 = false;
437 _despawn = false;
438 _despawnTimer = 30000;
439 _sayLowHealth = false;
440 }
441
442 void Reset() override
443 {
444 Initialize();
445 }
446
447 void JustReachedHome() override
448 {
449 _despawn = true;
450 }
451
452 void JustEngagedWith(Unit* /*who*/) override
453 {
458 //events.ScheduleEvent(EVENT_TAILLASH, 10s);
461 }
462
463 void JustDied(Unit* /*killer*/) override
464 {
465 _JustDied();
467 }
468
469 void KilledUnit(Unit* victim) override
470 {
471 if (roll_chance_i(20))
472 return;
473
474 Talk(SAY_SLAY, victim);
475 }
476
477 void MovementInform(uint32 type, uint32 id) override
478 {
479 if (type != POINT_MOTION_TYPE)
480 return;
481
482 if (id == 1)
483 {
484 me->SetCanFly(false);
485 me->SetDisableGravity(false);
487 if (me->GetVictim())
489 }
490 }
491
492 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
493 {
494 // Phase3 begins when health below 20 pct
495 if (!_phase3 && me->HealthBelowPctDamaged(20, damage))
496 {
497 if (TempSummon* temp = me->ToTempSummon())
498 if (Unit* owner = temp->GetSummonerUnit())
499 if (owner->IsAIEnabled())
500 owner->GetAI()->DoAction(ACTION_BONE_CONSTRUCT_START_ATTACK);
501
502 _phase3 = true;
504 }
505
506 if (!_sayLowHealth && me->HealthBelowPctDamaged(5, damage))
507 {
508 _sayLowHealth = true;
510 }
511 }
512
513 void UpdateAI(uint32 diff) override
514 {
515 if (_despawn && _despawnTimer <= diff)
516 {
518 if (TempSummon* temp = me->ToTempSummon())
519 if (Unit* owner = temp->GetSummonerUnit())
520 if (owner->IsAIEnabled())
521 owner->GetAI()->DoAction(ACTION_BONE_CONSTRUCT_DESPAWN);
522 }
523 else
524 _despawnTimer -= diff;
525
526 if (!UpdateVictim())
527 return;
528
529 if (_despawn)
530 _despawn = false;
531
532 events.Update(diff);
533
535 return;
536
537 while (uint32 eventId = events.ExecuteEvent())
538 {
539 switch (eventId)
540 {
544 break;
545 case EVENT_FEAR:
548 break;
552 break;
553 case EVENT_CLEAVE:
556 break;
557 case EVENT_TAILLASH:
558 // Cast NYI since we need a better check for behind target
561 break;
562 case EVENT_CLASSCALL:
563 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
564 switch (target->GetClass())
565 {
566 case CLASS_MAGE:
567 Talk(SAY_MAGE);
569 break;
570 case CLASS_WARRIOR:
573 break;
574 case CLASS_DRUID:
576 DoCast(target, SPELL_DRUID);
577 break;
578 case CLASS_PRIEST:
581 break;
582 case CLASS_PALADIN:
585 break;
586 case CLASS_SHAMAN:
589 break;
590 case CLASS_WARLOCK:
593 break;
594 case CLASS_HUNTER:
597 break;
598 case CLASS_ROGUE:
601 break;
605 break;
606 default:
607 break;
608 }
610 break;
611 }
612
614 return;
615 }
616
618 }
619
620private:
625};
626
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ FAIL
@ POINT_MOTION_TYPE
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
bool roll_chance_i(int chance)
Definition Random.h:59
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
@ UNIT_STAND_STATE_SIT_HIGH_CHAIR
Definition UnitDefines.h:40
@ UNIT_STAND_STATE_DEAD
Definition UnitDefines.h:41
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:34
@ UNIT_NPC_FLAG_GOSSIP
@ UNIT_FLAG_UNINTERACTIBLE
@ ALIVE
Definition Unit.h:211
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
@ DATA_DRAKONID_BONES
#define RegisterBlackwingLairCreatureAI(ai_name)
@ DATA_NEFARIAN
@ NPC_NEFARIAN
Position const NefarianLoc[2]
NefarianGameObjects
@ GO_PORTCULLIS_TOBOSSROOMS
@ GO_PORTCULLIS_ACTIVE
NefarianSpells
@ 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
uint32 constexpr NefarianEntry[5]
Position const NefarianDrakeSpawnLoc[2]
NefarianPaths
@ NEFARIUS_PATH_2
@ NEFARIUS_PATH_3
NefarianSays
@ SAY_DEATH
@ SAY_PALADIN
@ SAY_XHEALTH
@ SAY_CHAOS_SPELL
@ SAY_WARRIOR
@ SAY_SHADOWFLAME
@ 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
void AddSC_boss_nefarian()
NefarianEvents
@ 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
NefarianActions
@ ACTION_BONE_CONSTRUCT_START_ATTACK
@ ACTION_BONE_CONSTRUCT_DESPAWN
NefarianCreatures
@ NPC_BLACK_DRAKANOID
@ NPC_BONE_CONSTRUCT
@ NPC_BLUE_DRAKANOID
@ NPC_CHROMATIC_DRAKANOID
@ NPC_GREEN_DRAKANOID
@ NPC_GYTH
@ NPC_BRONZE_DRAKANOID
@ NPC_RED_DRAKANOID
NefarianGossip
@ GOSSIP_OPTION_ID
@ GOSSIP_ID
InstanceScript *const instance
void _JustEngagedWith(Unit *who)
SummonList summons
EventMap events
void DoZoneInCombat(Creature *creature=nullptr)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void SetPhaseMask(uint32 newPhaseMask, bool update) override
Definition Creature.cpp:652
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:293
void SetImmuneToPC(bool apply) override
Definition Creature.h:129
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition Creature.cpp:540
void Update(uint32 time)
Definition EventMap.h:67
EventId ExecuteEvent()
Definition EventMap.cpp:73
void CancelEvent(EventId eventId)
Definition EventMap.cpp:151
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
virtual bool SetBossState(uint32 id, EncounterState state)
void MovePath(uint32 pathId, bool repeatable)
uint32 GetEntry() const
Definition Object.h:81
void DespawnEntry(uint32 entry)
void Summon(Creature const *summon)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
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 DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
void SetVisible(bool x)
Definition Unit.cpp:8513
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3638
void SetFaction(uint32 faction) override
Definition Unit.h:974
void StopMoving(bool force=false)
Definition Unit.cpp:10312
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:1098
TempSummon * ToTempSummon()
Definition Unit.h:1794
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition Unit.cpp:13286
void SetFacingToObject(WorldObject const *object, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13259
bool SetCanFly(bool enable, bool packetOnly=false)
Definition Unit.cpp:13374
void SetNpcFlag(NPCFlags flags)
Definition Unit.h:1097
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13250
void SetStandState(UnitStandStateType state)
Definition Unit.cpp:10363
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition Unit.h:918
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition Object.cpp:2121
Player * SelectNearestPlayer(float distance) const
Definition Object.cpp:2161
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:1992
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2099
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:56
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void GetPosition(float &x, float &y) const
Definition Position.h:84
void AttackStart(Unit *) override
void ResetThreatList(Unit *who=nullptr)
void SetAggressiveStateAfter(Milliseconds timer, Creature *who=nullptr, bool startCombat=true, Creature *summoner=nullptr, StartCombatArgs const &combatArgs={ })
void MovementInform(uint32 type, uint32 id) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
void JustReachedHome() override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) 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 DoAction(int32 param) override
void JustSummoned(Creature *summon) override
void Reset() override
void SetData(uint32 type, uint32 data) override