Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2024-12-05 00:08:25 +08:00
121 changed files with 4818 additions and 1413 deletions
@@ -268,7 +268,7 @@ public:
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
for(Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
if (Player* player = itr->GetSource())
if (!player->IsGameMaster() && player->IsAlive() && me->GetHomePosition().GetExactDist2d(player) < 52.0f && me->IsWithinLOSInMap(player) && !player->HasAuraType(SPELL_AURA_MOD_INVISIBILITY) && !player->HasAuraType(SPELL_AURA_MOD_STEALTH) && !player->HasAuraType(SPELL_AURA_MOD_UNATTACKABLE))
if (!player->IsGameMaster() && player->IsAlive() && me->GetHomePosition().GetExactDist2d(player) < 52.0f && me->IsWithinLOSInMap(player) && !player->HasInvisibilityAura() && !player->HasStealthAura() && !player->HasUnattackableAura())
return true;
return false;
}
@@ -146,7 +146,7 @@ struct boss_faction_championsAI : public ScriptedAI
{
// check for stun, fear, etc.
// for casting, silence, disarm check individually in the ai
if (me->isFeared() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
if (me->HasFearAura() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
{
if (!IsHeroic())
return true;
@@ -831,7 +831,7 @@ class spell_valkyr_touch_aura : public AuraScript
Map::PlayerList const& pl = caster->GetMap()->GetPlayers();
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
if (Player* plr = itr->GetSource())
if (plr->IsAlive() && !plr->HasAura(excludedID) && !plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
if (plr->IsAlive() && !plr->HasAura(excludedID) && !plr->HasSpiritOfRedemptionAura())
{
uint32 absorb = 0;
uint32 resist = 0;
@@ -957,7 +957,7 @@ public:
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) || me->isFeared() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasFearAura() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
return;
switch (events.ExecuteEvent())
@@ -1065,7 +1065,7 @@ public:
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) || me->isFeared() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasFearAura() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
return;
switch (events.ExecuteEvent())
@@ -1219,7 +1219,7 @@ public:
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) || me->isFeared() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasFearAura() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
return;
switch (events.ExecuteEvent())
@@ -1324,7 +1324,7 @@ public:
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) || me->isFeared() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasFearAura() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
return;
switch (events.ExecuteEvent())
@@ -1418,7 +1418,7 @@ public:
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) || me->isFeared() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasFearAura() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
return;
switch (events.ExecuteEvent())
@@ -2152,7 +2152,7 @@ public:
if (!UpdateVictim())
return;
if (me->HasUnitState(UNIT_STATE_CASTING) || me->isFeared() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasFearAura() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
return;
if (!leaped)
@@ -2211,7 +2211,7 @@ public:
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) || me->isFeared() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasFearAura() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
return;
switch (events.ExecuteEvent())
@@ -2280,7 +2280,7 @@ public:
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) || me->isFeared() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasFearAura() || me->IsCharmed() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED))
return;
switch (events.ExecuteEvent())
@@ -443,7 +443,7 @@ public:
{
if (Unit* trapped = summ->GetSummonerUnit())
{
if (!trapped->IsOnVehicle(me) || !trapped->IsAlive() || !me->GetInstanceScript() || me->GetInstanceScript()->GetBossState(DATA_LORD_MARROWGAR) != IN_PROGRESS || trapped->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
if (!trapped->IsOnVehicle(me) || !trapped->IsAlive() || !me->GetInstanceScript() || me->GetInstanceScript()->GetBossState(DATA_LORD_MARROWGAR) != IN_PROGRESS || trapped->HasSpiritOfRedemptionAura())
{
DoAction(-1337);
return;
@@ -260,7 +260,7 @@ public:
if (target->HasAura(SPELL_FROST_IMBUED_BLADE))
return false;
if (target->IsImmunedToDamageOrSchool(SPELL_SCHOOL_MASK_ALL) || target->HasAura(SPELL_ICE_TOMB_UNTARGETABLE) || target->HasAura(SPELL_ICE_TOMB_DAMAGE) || target->HasAura(SPELL_TANK_MARKER_AURA) || target->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
if (target->IsImmunedToDamageOrSchool(SPELL_SCHOOL_MASK_ALL) || target->HasAura(SPELL_ICE_TOMB_UNTARGETABLE) || target->HasAura(SPELL_ICE_TOMB_DAMAGE) || target->HasAura(SPELL_TANK_MARKER_AURA) || target->HasSpiritOfRedemptionAura())
return false;
return target != _source->GetVictim();
@@ -1684,7 +1684,7 @@ public:
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) || me->isFeared() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED) || ((me->GetEntry() == NPC_YMIRJAR_DEATHBRINGER || me->GetEntry() == NPC_YMIRJAR_FROSTBINDER) && me->HasUnitFlag(UNIT_FLAG_SILENCED)))
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasFearAura() || me->isFrozen() || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_CONFUSED) || ((me->GetEntry() == NPC_YMIRJAR_DEATHBRINGER || me->GetEntry() == NPC_YMIRJAR_FROSTBINDER) && me->HasUnitFlag(UNIT_FLAG_SILENCED)))
return;
switch (events.ExecuteEvent())
@@ -27,15 +27,6 @@ enum Spells
SPELL_WHIRLWIND = 38618
};
enum Events
{
EVENT_BATTLE_SHOUT = 1,
EVENT_FRIGHTENING_SHOUT = 2,
EVENT_WHIRLWIND = 3,
EVENT_COMMANDER_CHARGE = 4,
EVENT_KILL_TALK = 5
};
enum Says
{
SAY_AGGRO = 0,
@@ -45,32 +36,40 @@ enum Says
struct boss_commander_stoutbeard : public BossAI
{
boss_commander_stoutbeard(Creature* creature) : BossAI(creature, DATA_COMMANDER_EVENT) {}
void Reset() override
{
BossAI::Reset();
}
boss_commander_stoutbeard(Creature* creature) : BossAI(creature, DATA_COMMANDER_EVENT) { }
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_BATTLE_SHOUT, 0ms);
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 10s);
events.ScheduleEvent(EVENT_WHIRLWIND, 15s);
events.ScheduleEvent(EVENT_COMMANDER_CHARGE, 1s);
me->RemoveAllAuras();
ScheduleTimedEvent(1s, [&]
{
DoCastSelf(SPELL_BATTLE_SHOUT, true);
}, 2min);
ScheduleTimedEvent(10s, [&]
{
DoCastVictim(SPELL_FRIGHTENING_SHOUT);
}, 15s, 20s);
ScheduleTimedEvent(15s, [&]
{
DoCastAOE(SPELL_WHIRLWIND);
}, 16s);
ScheduleTimedEvent(1s, [&]
{
if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0, 25.0f))
DoCast(target, SPELL_CHARGE);
}, 20s);
}
void KilledUnit(Unit*) override
{
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
Talk(SAY_KILL);
events.ScheduleEvent(EVENT_KILL_TALK, 6s);
}
Talk(SAY_KILL);
}
void JustDied(Unit* killer) override
@@ -78,39 +77,6 @@ struct boss_commander_stoutbeard : public BossAI
BossAI::JustDied(killer);
Talk(SAY_DEATH);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_BATTLE_SHOUT:
me->CastSpell(me, SPELL_BATTLE_SHOUT, true);
events.ScheduleEvent(EVENT_BATTLE_SHOUT, 2min);
break;
case EVENT_FRIGHTENING_SHOUT:
me->CastSpell(me->GetVictim(), SPELL_FRIGHTENING_SHOUT, false);
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 15s, 20s);
break;
case EVENT_WHIRLWIND:
me->CastSpell(me, SPELL_WHIRLWIND, false);
events.ScheduleEvent(EVENT_WHIRLWIND, 16s);
break;
case EVENT_COMMANDER_CHARGE:
if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0, 25.0f))
me->CastSpell(target, SPELL_CHARGE, false);
events.ScheduleEvent(EVENT_COMMANDER_CHARGE, 20s);
break;
}
DoMeleeAttackIfReady();
}
};
void AddSC_boss_commander_stoutbeard()
@@ -145,8 +145,6 @@ public:
if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE)
{
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
if (GameObject* doors = me->GetMap()->GetGameObject(pInstance->GetGuidData(GO_SJONNIR_DOOR)))
doors->SetGoState(GO_STATE_ACTIVE);
if (GameObject* console = me->GetMap()->GetGameObject( pInstance->GetGuidData(GO_SJONNIR_CONSOLE)))
console->SetGoState(GO_STATE_READY);
@@ -155,7 +153,7 @@ public:
{
brann->setDeathState(DeathState::JustDied);
brann->Respawn();
brann->AI()->DoAction(5);
brann->AI()->DoAction(ACTION_SJONNIR_WIPE_START);
}
}
}
@@ -183,7 +181,7 @@ public:
if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE)
if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN)))
brann->AI()->DoAction(3);
brann->AI()->DoAction(ACTION_START_SJONNIR_FIGHT);
}
}
@@ -220,8 +218,7 @@ public:
if (pInstance)
if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN)))
{
brann->Yell("What in the name o' Madoran did THAT do? Oh! Wait: I just about got it...", LANG_UNIVERSAL);
brann->PlayDirectSound(14276);
brann->AI()->Talk(SAY_BRANN_SPAWN_OOZE);
}
}
@@ -229,8 +226,7 @@ public:
{
if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN)))
{
brann->Yell("Ha, that did it! Help's a-comin'! Take this, ya glowin' iron brute!", LANG_UNIVERSAL);
brann->PlayDirectSound(14277);
brann->AI()->Talk(SAY_BRANN_SPAWN_EARTHEN);
}
SummonPhase = PHASE_SUMMON_FRIENDLY_DWARFES;
me->CastSpell(me, SPELL_FRENZY, false);
@@ -276,8 +272,7 @@ public:
{
if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN)))
{
brann->Yell("This is a wee bit trickier that before... Oh, bloody--incomin'!", LANG_UNIVERSAL);
brann->PlayDirectSound(14275);
brann->AI()->Talk(SAY_BRANN_SPAWN_TROGG);
}
break;
@@ -331,7 +326,7 @@ public:
sd->SetGoState(GO_STATE_ACTIVE);
if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN)))
brann->AI()->DoAction(4);
brann->AI()->DoAction(ACTION_SJONNIR_DEAD);
}
}
@@ -28,14 +28,19 @@
#define GOSSIP_ITEM_2 "Let's move Brann, enough of the history lessons!"
#define GOSSIP_ITEM_3 "There will be plenty of time for this later Brann, we need to get moving!"
#define GOSSIP_ITEM_4 "We're with you Brann! Open it!"
#define TEXT_ID_START 13100
#define TEXT_ID_START 13100
#define TEXT_ID_TRIBUNAL_START 13101
#define TEXT_ID_TRIBUNAL_END 14176
#define TEXT_ID_SJONNIR_DOOR 13883
#define TEXT_ID_SJONNIR_END 13308
enum NPCs
{
NPC_DARK_RUNE_PROTECTOR = 27983,
NPC_DARK_RUNE_STORMCALLER = 27984,
NPC_IRON_GOLEM_CUSTODIAN = 27985,
NPC_DARK_MATTER_TRIGGER = 28237,
NPC_DARK_MATTER = 28235,
NPC_DARK_MATTER_TARGET = 28237,
NPC_SEARING_GAZE_TRIGGER = 28265,
};
@@ -44,7 +49,8 @@ enum Misc
// BRANN EVENT
SPELL_GLARE_OF_THE_TRIBUNAL = 50988,
SPELL_GLARE_OF_THE_TRIBUNAL_H = 59870,
SPELL_DARK_MATTER_VISUAL = 51001,
SPELL_DARK_MATTER_VISUAL = 51000,
SPELL_DARK_MATTER_VISUAL_CHANNEL= 51001,
SPELL_DARK_MATTER = 51012,
SPELL_DARK_MATTER_H = 59868,
SPELL_SEARING_GAZE = 51136,
@@ -65,46 +71,49 @@ enum Misc
SPELL_IGC_GROUND_SMASH = 12734,
SPELL_IGC_GROUND_SMASH_H = 59865,
// ACTIONS
ACTION_START_EVENT = 0,
ACTION_START_TRIBUNAL = 1,
ACTION_GO_TO_SJONNIR = 2,
ACTION_START_SJONNIR_FIGHT = 3,
ACTION_SJONNIR_DEAD = 4,
ACTION_ENTEREVADEMODE = 5,
ACTION_WIPE_START = 6,
ACTION_OPEN_DOOR = 7,
// QUESTS
QUEST_HALLS_OF_STONE = 13207,
};
enum events
{
// BRANN
EVENT_KADDRAK_HEAD = 1,
EVENT_MARNAK_HEAD = 2,
EVENT_ABEDNEUM_HEAD = 3,
EVENT_SUMMON_MONSTERS = 4,
EVENT_TRIBUNAL_END = 5,
EVENT_GO_TO_SJONNIR = 6,
EVENT_END = 7,
EVENT_KADDRAK_VISUAL = 8,
EVENT_MARNAK_VISUAL = 9,
EVENT_ABEDNEUM_VISUAL = 10,
EVENT_KADDRAK_SWITCH_EYE = 11,
// BRANN AND TRIBUNAL
EVENT_ABEDNEUM_VISUAL = 1,
EVENT_KADDRAK_VISUAL = 2,
EVENT_MARNAK_VISUAL = 3,
EVENT_ABEDNEUM_HEAD = 4,
EVENT_KADDRAK_HEAD = 5,
EVENT_MARNAK_HEAD = 6,
EVENT_KADDRAK_SWITCH_EYE = 7,
EVENT_SUMMON_MONSTERS = 8,
EVENT_SUMMON_STORMCALLER = 9,
EVENT_SUMMON_CUSTODIAN = 10,
EVENT_DARK_MATTER_START = 11,
EVENT_DARK_MATTER_END = 12,
// DARK RUNE PROTECTOR
EVENT_DRP_CHARGE = 15,
EVENT_DRP_CLEAVE = 16,
EVENT_DRP_CHARGE = 13,
EVENT_DRP_CLEAVE = 14,
// DARK RUNE STORMCALLER
EVENT_DRS_LIGHTNING_BOLD = 20,
EVENT_DRS_SHADOW_WORD_PAIN = 21,
EVENT_DRS_LIGHTNING_BOLD = 15,
EVENT_DRS_SHADOW_WORD_PAIN = 16,
// IRON GOLEM CUSTODIAN
EVENT_IGC_CRUSH = 30,
EVENT_IGC_GROUND_SMASH = 31,
EVENT_IGC_CRUSH = 17,
EVENT_IGC_GROUND_SMASH = 18,
EVENT_TRIBUNAL_END = 19,
EVENT_BREEN_WAITING = 20,
EVENT_TALK_FACE_CHANGE = 21,
EVENT_SKY_ROOM_FLOOR_CHANGE = 22,
//BRANN AND SJONNIR
EVENT_GO_TO_SJONNIR = 23,
EVENT_DOOR_OPEN = 24,
EVENT_RESUME_ESCORT = 25,
EVENT_SJONNIR_END_BRANN_YELL = 26,
EVENT_SJONNIR_END_BRANN_LAST_YELL = 27,
};
struct Yells
@@ -116,46 +125,45 @@ struct Yells
static Yells Conversation[] =
{
{14259, "Time to get some answers! Let's get this show on the road!", NPC_BRANN, 0},
{14247, "Take a moment and relish this with me. Soon... all will be revealed. Okay then, let's do this!", NPC_BRANN, 5000},
{14248, "Now keep an eye out! I'll have this licked in two shakes of a--", NPC_BRANN, 17000},
{13765, "Warning: life form pattern not recognized. Archival processing terminated. Continued interference will result in targeted response.", NPC_ABEDNEUM, 20500},
{14249, "Oh, that doesn't sound good. We might have a complication or two...", NPC_BRANN, 32000},
{13756, "Security breach in progress. Analysis of historical archives transferred to lower-priority queue. Countermeasures engaged.", NPC_KADDRAK, 37000},
{14250, "Ah, you want to play hardball, eh? That's just my game!", NPC_BRANN, 49000},
{14251, "Couple more minutes and I'll--", NPC_BRANN, 100000},
{14248, "Now keep an eye out! I'll have this licked in two shakes of a--", NPC_BRANN, 8000},
{13765, "Warning: life form pattern not recognized. Archival processing terminated. Continued interference will result in targeted response.", NPC_ABEDNEUM, 13000},
{14249, "Oh, that doesn't sound good. We might have a complication or two...", NPC_BRANN, 24000},
{13756, "Security breach in progress. Analysis of historical archives transferred to lower-priority queue. Countermeasures engaged.", NPC_KADDRAK, 30500},
{14250, "Ah, you want to play hardball, eh? That's just my game!", NPC_BRANN, 42000},
{14251, "Couple more minutes and I'll--", NPC_BRANN, 102000},
{13761, "Threat index threshold exceeded. Celestial archive aborted. Security level heightened.", NPC_MARNAK, 105000},
{14252, "Heightened? What's the good news?", NPC_BRANN, 116000},
{14253, "So that was the problem? Now I'm makin' progress...", NPC_BRANN, 195000},
{13767, "Critical threat index. Void analysis diverted. Initiating sanitization protocol.", NPC_ABEDNEUM, 205000},
{14254, "Hang on! Nobody's gonna' be sanitized as long as I have a say in it!", NPC_BRANN, 215000},
{14255, "Ha! The old magic fingers finally won through! Now let's get down to--", NPC_BRANN, 295000},
{13768, "Alert: security fail-safes deactivated. Beginning memory purge and... ", NPC_ABEDNEUM, 303000},
//The fight is completed at this point.
{14256, "Purge? No no no no no.. where did I-- Aha, this should do the trick...", NPC_BRANN, 310000},
{13769, "System online. Life form pattern recognized. Welcome, Branbronzan. Query?", NPC_ABEDNEUM, 321000},
{14263, "Query? What do you think I'm here for, tea and biscuits? Spill the beans already!", NPC_BRANN, 329000},
{14252, "Heightened? What's the good news?", NPC_BRANN, 113000},
{14253, "So that was the problem? Now I'm makin' progress...", NPC_BRANN, 201000},
{13767, "Critical threat index. Void analysis diverted. Initiating sanitization protocol.", NPC_ABEDNEUM, 207500 },
{14254, "Hang on! Nobody's gonna' be sanitized as long as I have a say in it!", NPC_BRANN, 214000},
{14255, "Ha! The old magic fingers finally won through! Now let's get down to--", NPC_BRANN, 305000},
{13768, "Alert: security fail-safes deactivated. Beginning memory purge and... ", NPC_ABEDNEUM, 310000},
//The fight is completed at this point.d
{14256, "Purge? No no no no no.. where did I-- Aha, this should do the trick...", NPC_BRANN, 316000},
{13769, "System online. Life form pattern recognized. Welcome, Branbronzan. Query?", NPC_ABEDNEUM, 322000},
{14263, "Query? What do you think I'm here for, tea and biscuits? Spill the beans already!", NPC_BRANN, 330000},
{14264, "Tell me how the dwarves came to be, and start at the beginning!", NPC_BRANN, 336000},
{13770, "Accessing prehistoric data... retrieved. In the beginning the earthen were created to--", NPC_ABEDNEUM, 342000},
{13770, "Accessing prehistoric data... retrieved. In the beginning the earthen were created to--", NPC_ABEDNEUM, 341000},
{14265, "Right, right... I know the earthen were made from stone to shape the deep regions o' the world. But what about the anomalies? Matrix non-stabilizin' and what-not?", NPC_BRANN, 348000},
{13771, "Accessing... In the early stages of it's development cycle, Azeroth suffered infection by parasitic necrophotic symbiotes.", NPC_ABEDNEUM, 360000},
{14266, "Necrowhatinthe-- Speak bloody Common, will ye?", NPC_BRANN, 373500},
{13772, "Designation: Old Gods. Old Gods rendered all systems, including earthen, defenseless in order to facilitate assimilation. This matrix destabilization has been termed the Curse of Flesh. Effects of destabilization increased over time.", NPC_ABEDNEUM, 380000},
{14267, "Old Gods, huh? So they zapped the earthen with this Curse of Flesh... and then what?", NPC_BRANN, 399500},
{13757, "Accessing... Creators arrived to extirpate symbiotic infection. Assessment revealed that Old God infestation had grown malignant. Excising parasites would result in loss of host--", NPC_KADDRAK, 406000},
{14266, "Necrowhatinthe-- Speak bloody Common, will ye?", NPC_BRANN, 372000},
{13772, "Designation: Old Gods. Old Gods rendered all systems, including earthen, defenseless in order to facilitate assimilation. This matrix destabilization has been termed the Curse of Flesh. Effects of destabilization increased over time.", NPC_ABEDNEUM, 377000},
{14267, "Old Gods, huh? So they zapped the earthen with this Curse of Flesh... and then what?", NPC_BRANN, 400000},
{13757, "Accessing... Creators arrived to extirpate symbiotic infection. Assessment revealed that Old God infestation had grown malignant. Excising parasites would result in loss of host--", NPC_KADDRAK, 407500},
{14268, "If they killed the Old Gods, Azeroth would've been destroyed...", NPC_BRANN, 424000},
{13758, "Correct. Creators neutralized parasitic threat and contained it within the host. Forge of Wills and other systems were instituted to create new earthen. Safeguards were implemented, and protectors were appointed.", NPC_KADDRAK, 429000},
{14269, "What protectors?", NPC_BRANN, 449000},
{13759, "Designations: Aesir and Vanir. Or in the common nomenclature, storm and earth giants. Sentinel Loken designated supreme. Dragon Aspects appointed to monitor evolution on Azeroth.", NPC_KADDRAK, 452000},
{14270, "Aesir and Vanir... Okay, so the Forge o' Wills started makin' new earthen... but what happened to the old ones?", NPC_BRANN, 471000},
{13762, "Additional background is relevant to your query: following global combat between Aesir and Vanir--", NPC_MARNAK, 482000},
{13758, "Correct. Creators neutralized parasitic threat and contained it within the host. Forge of Wills and other systems were instituted to create new earthen. Safeguards were implemented, and protectors were appointed.", NPC_KADDRAK, 431000},
{14269, "What protectors?", NPC_BRANN, 450000},
{13759, "Designations: Aesir and Vanir. Or in the common nomenclature, storm and earth giants. Sentinel Loken designated supreme. Dragon Aspects appointed to monitor evolution on Azeroth.", NPC_KADDRAK, 453000},
{14270, "Aesir and Vanir... Okay, so the Forge o' Wills started makin' new earthen... but what happened to the old ones?", NPC_BRANN, 472000},
{13762, "Additional background is relevant to your query: following global combat between Aesir and Vanir--", NPC_MARNAK, 483000},
{14271, "Hold everything! The Aesir and Vanir went to war? Why?", NPC_BRANN, 489000},
{13763, "Unknown. Data suggests that impetus for global combat originated with prime designate Loken, who neutralized all remaining Aesir and Vanir, affecting termination of conflict. Prime designate Loken then initiated stasis of several seed races, including earthen, giants and vrykul, at designated holding facilities.", NPC_MARNAK, 494000},
{13763, "Unknown. Data suggests that impetus for global combat originated with prime designate Loken, who neutralized all remaining Aesir and Vanir, affecting termination of conflict. Prime designate Loken then initiated stasis of several seed races, including earthen, giants and vrykul, at designated holding facilities.", NPC_MARNAK, 495000},
{14272, "This Loken sounds like a nasty character. Glad we don't have to worry about the likes o' him anymore. So... if I'm understandin' ye right, the original earthen eventually woke up from this stasis, and by that time the destabili-whatever had turned 'em into proper dwarves. Or at least... dwarf ancestors.", NPC_BRANN, 519000},
{13764, "Essentially that is correct.", NPC_MARNAK, 543000},
{14273, "Well, now... that's a lot to digest. I'm gonna need some time to take all this in. Thank ye.", NPC_BRANN, 549000},
{13773, "Acknowledged, Branbronzan. Session terminated.", NPC_ABEDNEUM, 559000},
{0, "I think it's time to see what's behind the door near the entrance. I'm going to sneak over there, nice and quiet. Meet me at the door and I'll get us in.", NPC_BRANN, 574000},
{14273, "Well, now... that's a lot to digest. I'm gonna need some time to take all this in. Thank ye.", NPC_BRANN, 546000},
{13773, "Acknowledged, Branbronzan. Session terminated.", NPC_ABEDNEUM, 554000},
//Go to Sjonnir's door
{0, "I think it's time to see what's behind the door near the entrance. I'm going to sneak over there, nice and quiet. Meet me at the door and I'll get us in.", NPC_BRANN, 561000},
};
class brann_bronzebeard : public CreatureScript
@@ -176,24 +184,27 @@ public:
{
case 1:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, TEXT_ID_START, creature->GetGUID());
break;
case 2:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
SendGossipMenuFor(player, TEXT_ID_TRIBUNAL_START, creature->GetGUID());
break;
case 3:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
SendGossipMenuFor(player, TEXT_ID_TRIBUNAL_END, creature->GetGUID());
break;
case 4:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
SendGossipMenuFor(player, TEXT_ID_SJONNIR_DOOR, creature->GetGUID());
break;
case 5:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
SendGossipMenuFor(player, TEXT_ID_SJONNIR_END, creature->GetGUID());
break;
default:
break;
}
}
SendGossipMenuFor(player, TEXT_ID_START, creature->GetGUID());
return true;
}
@@ -204,7 +215,7 @@ public:
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
creature->AI()->DoAction(ACTION_START_EVENT);
creature->AI()->DoAction(ACTION_START_ESCORT_EVENT);
CloseGossipMenuFor(player);
break;
case GOSSIP_ACTION_INFO_DEF+2:
@@ -216,10 +227,6 @@ public:
CloseGossipMenuFor(player);
break;
case GOSSIP_ACTION_INFO_DEF+4:
creature->AI()->DoAction(ACTION_WIPE_START);
CloseGossipMenuFor(player);
break;
case GOSSIP_ACTION_INFO_DEF+5:
creature->AI()->DoAction(ACTION_OPEN_DOOR);
CloseGossipMenuFor(player);
break;
@@ -246,10 +253,13 @@ public:
ObjectGuid AbedneumGUID;
ObjectGuid MarnakGUID;
ObjectGuid KaddrakGUID;
ObjectGuid darkMatterTargetGUID;
uint8 WaveNum;
bool TalkEvent;
uint32 SpeechCount, SpeechPause;
bool canExecuteEvents = true;
void DespawnHeads()
{
@@ -257,6 +267,7 @@ public:
if ((cr = GetAbedneum())) cr->DespawnOrUnsummon();
if ((cr = GetMarnak())) cr->DespawnOrUnsummon();
if ((cr = GetKaddrak())) cr->DespawnOrUnsummon();
SwitchHeadVisaul(0x7, false);
}
@@ -268,15 +279,46 @@ public:
GameObject* go = nullptr;
if (headMask & 0x1) // Kaddrak
if ((go = me->GetMap()->GetGameObject(pInstance->GetGuidData(GO_KADDRAK))))
activate ? go->SendCustomAnim(0) : go->SetGoState(GO_STATE_READY);
{
if (activate)
{
go->SendCustomAnim(0);
}
else
{
go->SendCustomAnim(1);
if (go->GetGoState() == GO_STATE_ACTIVE)
go->SetGoState(GO_STATE_READY);
}
}
if (headMask & 0x2) // Marnak
if ((go = me->GetMap()->GetGameObject(pInstance->GetGuidData(GO_MARNAK))))
activate ? go->SendCustomAnim(0) : go->SetGoState(GO_STATE_READY);
{
if (activate)
{
go->SendCustomAnim(0);
}
else
{
go->SendCustomAnim(1);
if (go->GetGoState() == GO_STATE_ACTIVE)
go->SetGoState(GO_STATE_READY);
}
}
if (headMask & 0x4) // Abedneum
if ((go = me->GetMap()->GetGameObject(pInstance->GetGuidData(GO_ABEDNEUM))))
activate ? go->SendCustomAnim(0) : go->SetGoState(GO_STATE_READY);
{
if (activate)
{
go->SendCustomAnim(0);
}
else
{
go->SendCustomAnim(1);
if (go->GetGoState() == GO_STATE_ACTIVE)
go->SetGoState(GO_STATE_READY);
}
}
}
void ResetEvent()
@@ -284,6 +326,9 @@ public:
if (GameObject* tribunal = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_TRIBUNAL_CONSOLE)))
tribunal->SetGoState(GO_STATE_READY);
if (GameObject* tribunalSkyFloor = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_SKY_FLOOR)))
tribunalSkyFloor->SetGoState(GO_STATE_READY);
events.Reset();
summons.DespawnAll();
DespawnHeads();
@@ -301,7 +346,8 @@ public:
Creature* GetMarnak() { return ObjectAccessor::GetCreature(*me, MarnakGUID); }
Creature* GetKaddrak() { return ObjectAccessor::GetCreature(*me, KaddrakGUID); }
void MoveInLineOfSight(Unit* /*pWho*/) override { }
bool leftEye = true;
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (damage && pInstance)
@@ -325,7 +371,18 @@ public:
pInstance->SetData(DATA_BRANN_ACHIEVEMENT, true);
if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE)
pInstance->SetData(BRANN_BRONZEBEARD, (pInstance->GetData(BOSS_SJONNIR) == DONE) ? 5 : 4);
{
pInstance->SetData(BRANN_BRONZEBEARD, 4);
if (GameObject* door = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_TRIBUNAL_ACCESS_DOOR)))
door->SetGoState(GO_STATE_ACTIVE);
}
if (pInstance->GetData(BOSS_SJONNIR) == DONE)
{
pInstance->SetData(BRANN_BRONZEBEARD, 5);
if (GameObject* door = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_SJONNIR_DOOR)))
door->SetGoState(GO_STATE_ACTIVE);
}
}
}
@@ -333,58 +390,79 @@ public:
{
switch (action)
{
case ACTION_START_EVENT:
case ACTION_START_ESCORT_EVENT:
Start(false, true, ObjectGuid::Empty, 0, true, false);
Talk(SAY_BRANN_ESCORT_START);
me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
me->SetReactState(REACT_AGGRESSIVE);
me->SetRegeneratingHealth(false);
break;
case ACTION_START_TRIBUNAL:
{
Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
if (!PlayerList.IsEmpty())
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
me->SetFaction(i->GetSource()->GetFaction());
break;
}
{
me->SetReactState(REACT_PASSIVE);
Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
if (!PlayerList.IsEmpty())
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
me->SetFaction(i->GetSource()->GetFaction());
break;
}
SetEscortPaused(false);
InitializeEvent();
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
break;
}
case ACTION_GO_TO_SJONNIR:
SetEscortPaused(false);
InitializeEvent();
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
break;
}
case ACTION_TRIBUNAL_WIPE_START:
SetNextWaypoint(1, false);
SetEscortPaused(false);
ResetEvent();
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
break;
case ACTION_GO_TO_SJONNIR:
Talk(SAY_BRANN_ENTRANCE_MEET);
me->SetFaction(FACTION_FRIENDLY);
me->SetReactState(REACT_PASSIVE);
me->SetRegeneratingHealth(true);
SetEscortPaused(false);
ResetEvent();
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
DoCast(me, 58506, false);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY_UNARMED);
me->SendMovementFlagUpdate();
break;
case ACTION_START_SJONNIR_FIGHT:
me->SetFaction(FACTION_FRIENDLY);
me->Yell("Don't worry! Ol' Brann's got yer back! Keep that metal monstrosity busy, and I'll see if I can't sweet talk this machine into helping ye!", LANG_UNIVERSAL);
me->PlayDirectSound(14274);
SetEscortPaused(false);
break;
case ACTION_SJONNIR_DEAD:
me->Yell("Loken? That's downright bothersome... We might've neutralized the iron dwarves, but I'd lay odds there's another machine somewhere else churnin' out a whole mess o' these iron vrykul!", LANG_UNIVERSAL);
me->PlayDirectSound(14278);
events.ScheduleEvent(EVENT_END, 14000);
if (pInstance)
pInstance->SetData(BRANN_BRONZEBEARD, 5);
SetEscortPaused(false);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND);
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
me->SetOrientation(3.132660f);
me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_SJONNIR_END_BRANN_YELL, 10000ms);
events.ScheduleEvent(EVENT_SJONNIR_END_BRANN_LAST_YELL, 22000ms);
break;
case ACTION_ENTEREVADEMODE:
RemoveEscortState(0x7); // all states
me->SetHomePosition(1077.41f, 474.16f, 207.8f, 2.70526f);
me->UpdatePosition(1077.41f, 474.16f, 207.9f, 2.70526f, true);
me->StopMovingOnCurrentPos();
case ACTION_SJONNIR_WIPE_START:
Reset();
break;
case ACTION_WIPE_START:
Start(false, true, ObjectGuid::Empty, 0, true, false);
SetNextWaypoint(20, false);
ResetEvent();
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
SetNextWaypoint(33, true);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY_UNARMED);
me->StopMovingOnCurrentPos();
DoCast(me, 58506, false);
if (GameObject* door = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_SJONNIR_DOOR)))
door->SetGoState(GO_STATE_READY);
break;
case ACTION_OPEN_DOOR:
if (GameObject* door = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_SJONNIR_DOOR)))
door->SetGoState(GO_STATE_ACTIVE);
Start(false, true, ObjectGuid::Empty, 0, true, false);
SetNextWaypoint(34, false);
SetEscortPaused(false);
me->RemoveAura(58506);
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
me->SetWalk(true);
me->SetSpeed(MOVE_WALK, 1.0f);
break;
}
}
@@ -400,68 +478,130 @@ public:
void UpdateEscortAI(uint32 diff) override
{
events.Update(diff);
switch (events.ExecuteEvent())
if (uint32 eventId = events.ExecuteEvent())
{
case EVENT_KADDRAK_VISUAL:
switch (eventId)
{
case EVENT_KADDRAK_VISUAL:
{
SwitchHeadVisaul(0x1, true);
break;
}
case EVENT_MARNAK_VISUAL:
case EVENT_MARNAK_VISUAL:
{
SwitchHeadVisaul(0x2, true);
break;
}
case EVENT_ABEDNEUM_VISUAL:
case EVENT_ABEDNEUM_VISUAL:
{
SwitchHeadVisaul(0x4, true);
break;
}
case EVENT_KADDRAK_HEAD: // First
case EVENT_KADDRAK_HEAD: // Phase 1
{
if (!canExecuteEvents)
return;
if (Creature* kaddrak = GetKaddrak())
{
if (Player* plr = SelectTargetFromPlayerList(100.0f))
kaddrak->CastSpell(plr, DUNGEON_MODE(SPELL_GLARE_OF_THE_TRIBUNAL, SPELL_GLARE_OF_THE_TRIBUNAL_H), true);
}
events.RescheduleEvent(EVENT_KADDRAK_SWITCH_EYE, 1500ms);
events.Repeat(2s, 4s);
events.RescheduleEvent(EVENT_KADDRAK_SWITCH_EYE, 1000ms);
events.Repeat(1500ms);
break;
}
case EVENT_KADDRAK_SWITCH_EYE:
case EVENT_KADDRAK_SWITCH_EYE:
{
if (!canExecuteEvents)
return;
if (Creature* kaddrak = GetKaddrak())
{
if (urand(0, 1))
if (leftEye)
kaddrak->UpdatePosition(927.9f, 330.9f, 219.4f, 2.4f, true);
else
kaddrak->UpdatePosition(923.7f, 326.9f, 219.5f, 2.1f, true);
leftEye = !leftEye;
kaddrak->StopMovingOnCurrentPos();
}
break;
}
case EVENT_MARNAK_HEAD: // Second
case EVENT_MARNAK_HEAD: // Phase 2
{
if (!canExecuteEvents)
return;
if (Creature* marnak = GetMarnak())
{
if (Creature* cr = me->SummonCreature(NPC_DARK_MATTER_TRIGGER, marnak->GetPositionX(), marnak->GetPositionY(), marnak->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000))
if (Creature* cr = me->SummonCreature(NPC_DARK_MATTER_TARGET, 899.843f, 355.271f, 214.301f, 0, TEMPSUMMON_TIMED_DESPAWN, 10000))
{
cr->CastSpell(cr, SPELL_DARK_MATTER_VISUAL, true);
if (Player* plr = SelectTargetFromPlayerList(100.0f))
cr->SetCanFly(true);
//right eye
if (Creature* cra = me->SummonCreature(NPC_DARK_MATTER, marnak->GetPositionX(), marnak->GetPositionY(), marnak->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 5000))
cra->CastSpell(cra, SPELL_DARK_MATTER_VISUAL_CHANNEL, false);
//left eye
if (Creature* crb = me->SummonCreature(NPC_DARK_MATTER, 891.543f, 359.5252f, 219.338f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 5000))
crb->CastSpell(crb, SPELL_DARK_MATTER_VISUAL_CHANNEL, false);
darkMatterTargetGUID = cr->GetGUID();
events.RescheduleEvent(EVENT_DARK_MATTER_START, 5000ms);
}
}
events.Repeat(30s);
break;
}
case EVENT_DARK_MATTER_START:
{
if (Creature* darkMatterTarget = ObjectAccessor::GetCreature(*me, darkMatterTargetGUID))
{
darkMatterTarget->CastSpell(darkMatterTarget, SPELL_DARK_MATTER_VISUAL, false);
if (Player* plr = SelectTargetFromPlayerList(100.0f))
{
if (!plr)
return; //no target
float speed = 10.0f;
float tooFarAwaySpeed = me->GetDistance(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ()) / (5000.0f * 0.001f);
if (speed < tooFarAwaySpeed)
speed = tooFarAwaySpeed;
darkMatterTarget->MonsterMoveWithSpeed(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), speed);
if (darkMatterTarget->GetDistance(plr) < 15.0f)
{
float speed = me->GetDistance(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ()) / (4000.0f * 0.001f);
cr->MonsterMoveWithSpeed(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), speed);
events.RescheduleEvent(EVENT_DARK_MATTER_END, 3000ms);
}
else if (darkMatterTarget->GetDistance(plr) < 30.0f)
{
events.RescheduleEvent(EVENT_DARK_MATTER_END, 3500ms);
}
else
{
events.RescheduleEvent(EVENT_DARK_MATTER_END, 4500ms);
}
}
}
events.Repeat(20s);
break;
}
case EVENT_ABEDNEUM_HEAD: // Third
case EVENT_DARK_MATTER_END:
{
if (Creature* darkMatterTarget = ObjectAccessor::GetCreature(*me, darkMatterTargetGUID))
{
darkMatterTarget->CastSpell(darkMatterTarget, darkMatterTarget->GetMap()->IsHeroic() ? SPELL_DARK_MATTER_H : SPELL_DARK_MATTER, true);
darkMatterTarget->DespawnOrUnsummon(500);
}
break;
}
case EVENT_ABEDNEUM_HEAD: // Phase 3
{
if (!canExecuteEvents)
return;
if (GetAbedneum())
{
Player* plr = SelectTargetFromPlayerList(100.0f);
@@ -475,38 +615,50 @@ public:
cr->CastSpell(cr, DUNGEON_MODE(SPELL_SEARING_GAZE, SPELL_SEARING_GAZE_H), true);
}
}
events.Repeat(30s);
events.Repeat(15s);
break;
}
case EVENT_SUMMON_MONSTERS:
case EVENT_SUMMON_MONSTERS:
{
uint32 Time = 45000 - (2500 * WaveNum);
SummonCreatures(NPC_DARK_RUNE_PROTECTOR, 3);
if (!canExecuteEvents)
return;
uint32 Time = 40000 - (2500 * WaveNum);
SummonCreatures(NPC_DARK_RUNE_PROTECTOR, 3, 0);
if (WaveNum > 2)
SummonCreatures(NPC_DARK_RUNE_STORMCALLER, 2);
events.ScheduleEvent(EVENT_SUMMON_STORMCALLER, urand(10 - WaveNum, 15 - WaveNum) * 1000);
if (WaveNum > 5)
SummonCreatures(NPC_IRON_GOLEM_CUSTODIAN, 1);
events.ScheduleEvent(EVENT_SUMMON_CUSTODIAN, urand(10 - WaveNum, 15 - WaveNum) * 1000);
WaveNum++;
events.RepeatEvent(Time);
break;
}
case EVENT_TRIBUNAL_END:
case EVENT_SUMMON_STORMCALLER:
{
if (!canExecuteEvents)
return;
SummonCreatures(NPC_DARK_RUNE_STORMCALLER, 2, 1);
break;
}
case EVENT_SUMMON_CUSTODIAN:
{
if (!canExecuteEvents)
return;
SummonCreatures(NPC_IRON_GOLEM_CUSTODIAN, 1, 1);
break;
}
case EVENT_TRIBUNAL_END:
{
canExecuteEvents = false;
// Has to be here!
events.Reset();
//DespawnHeads();
summons.DespawnAll();
if (pInstance)
{
pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, DONE);
pInstance->SetData(BRANN_BRONZEBEARD, 3);
me->CastSpell(me, 59046, true); // credit
}
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
// Spawn Chest and quest credit
if (Player* plr = SelectTargetFromPlayerList(200.0f))
{
@@ -520,31 +672,89 @@ public:
plr->GroupEventHappens(QUEST_HALLS_OF_STONE, me);
}
events.ScheduleEvent(EVENT_GO_TO_SJONNIR, 279s);
events.ScheduleEvent(EVENT_BREEN_WAITING, 11s);
events.ScheduleEvent(EVENT_SKY_ROOM_FLOOR_CHANGE, 92s);
events.ScheduleEvent(EVENT_TALK_FACE_CHANGE, 97s); //kaddrak speaks
events.ScheduleEvent(EVENT_SKY_ROOM_FLOOR_CHANGE, 168s);
events.ScheduleEvent(EVENT_TALK_FACE_CHANGE, 173s); //marnak speaks
events.ScheduleEvent(EVENT_SKY_ROOM_FLOOR_CHANGE, 239s);
events.ScheduleEvent(EVENT_TALK_FACE_CHANGE, 244s); //abedneum speaks
events.ScheduleEvent(EVENT_GO_TO_SJONNIR, 251s);
events.ScheduleEvent(EVENT_SKY_ROOM_FLOOR_CHANGE, 253s);
break;
}
case EVENT_GO_TO_SJONNIR:
case EVENT_BREEN_WAITING:
{
if (GameObject* door = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_SJONNIR_DOOR)))
door->SetGoState(GO_STATE_ACTIVE);
SetEscortPaused(false);
ResetEvent();
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
break;
}
case EVENT_END:
{
events.Reset();
if (pInstance)
pInstance->SetData(BRANN_BRONZEBEARD, 6);
{
pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, DONE);
pInstance->SetData(BRANN_BRONZEBEARD, 3);
me->CastSpell(me, 59046, true); // credit
}
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
me->Yell("I'll use the forge to make batches o' earthen to stand guard... But our greatest challenge still remains: find and stop Loken!", LANG_UNIVERSAL);
me->PlayDirectSound(14279);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND);
me->SendMovementFlagUpdate();
break;
}
case EVENT_TALK_FACE_CHANGE:
{
if (pInstance)
pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, DONE);
break;
}
case EVENT_SKY_ROOM_FLOOR_CHANGE:
{
if (pInstance)
pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, SPECIAL);
break;
}
case EVENT_GO_TO_SJONNIR:
{
me->AI()->DoAction(ACTION_GO_TO_SJONNIR);
break;
}
case EVENT_DOOR_OPEN:
{
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
me->AddUnitMovementFlag(MOVEMENTFLAG_NONE);
if (pInstance)
{
if (GameObject* door = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_SJONNIR_DOOR)))
{
door->SetGoState(GO_STATE_ACTIVE);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY_UNARMED);
me->SendMovementFlagUpdate();
}
}
break;
}
case EVENT_RESUME_ESCORT:
{
SetEscortPaused(false);
break;
}
case EVENT_SJONNIR_END_BRANN_YELL:
{
Talk(SAY_BRANN_VICTORY_SJONNIR_1);
break;
}
case EVENT_SJONNIR_END_BRANN_LAST_YELL:
{
events.Reset();
SetEscortPaused(false);
Talk(SAY_BRANN_VICTORY_SJONNIR_2);
break;
}
}
}
npc_escortAI::UpdateEscortAI(diff);
if (TalkEvent)
{
SpeechPause += diff;
@@ -581,11 +791,16 @@ public:
}
}
void SummonCreatures(uint32 entry, uint8 count)
void SummonCreatures(uint32 entry, uint8 count, uint8 pos)
{
Creature* cr;
for (int i = 0; i < count; ++i)
{
Creature* cr = me->SummonCreature(entry, 946.5971f + urand(0, 6), 383.5330f + urand(0, 6), 205.9943f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
if (pos == 0)
cr = me->SummonCreature(entry, 943.088f + urand(0, 5), 401.378f + urand(0, 5), 206.078f, 3.8f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000); //left
else
cr = me->SummonCreature(entry, 964.302f + urand(0, 4), 378.942f + urand(0, 4), 206.078f, 3.85f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000); //right
if (cr)
{
cr->AI()->AttackStart(me);
@@ -602,9 +817,18 @@ public:
{
if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN)))
{
brann->HandleEmoteCommand(EMOTE_STATE_DEAD);
brann->setDeathState(DeathState::JustDied);
brann->Respawn();
brann->AI()->DoAction(5);
if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) != DONE)
{
brann->AI()->DoAction(ACTION_TRIBUNAL_WIPE_START);
pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, FAIL);
}
if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE)
{
brann->AI()->DoAction(ACTION_SJONNIR_WIPE_START);
}
}
if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) != DONE)
pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, NOT_STARTED);
@@ -635,16 +859,18 @@ void brann_bronzebeard::brann_bronzebeardAI::InitializeEvent()
TalkEvent = true;
events.Reset();
events.ScheduleEvent(EVENT_SUMMON_MONSTERS, 21s);
events.ScheduleEvent(EVENT_KADDRAK_HEAD, 20s);
events.ScheduleEvent(EVENT_MARNAK_HEAD, 105s);
events.ScheduleEvent(EVENT_ABEDNEUM_HEAD, 205s);
events.ScheduleEvent(EVENT_TRIBUNAL_END, 315s);
// Viusals
events.ScheduleEvent(EVENT_KADDRAK_VISUAL, 20s);
events.ScheduleEvent(EVENT_KADDRAK_VISUAL, 30s);
events.ScheduleEvent(EVENT_MARNAK_VISUAL, 105s);
events.ScheduleEvent(EVENT_ABEDNEUM_VISUAL, 205s);
events.ScheduleEvent(EVENT_ABEDNEUM_VISUAL, 207s);
// Fight
events.ScheduleEvent(EVENT_SUMMON_MONSTERS, 47s);
events.ScheduleEvent(EVENT_KADDRAK_HEAD, 47s);
events.ScheduleEvent(EVENT_MARNAK_HEAD, 115s);
events.ScheduleEvent(EVENT_ABEDNEUM_HEAD, 217s);
events.ScheduleEvent(EVENT_TRIBUNAL_END, 310s);
}
void brann_bronzebeard::brann_bronzebeardAI::WaypointReached(uint32 id)
@@ -652,46 +878,89 @@ void brann_bronzebeard::brann_bronzebeardAI::WaypointReached(uint32 id)
switch (id)
{
// Stop before stairs and ask to start
case 9:
case 14:
SetEscortPaused(true);
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
if (pInstance)
{
me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
Talk(SAY_BRANN_EVENT_INTRO_1);
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
pInstance->SetData(BRANN_BRONZEBEARD, 2);
}
break;
// In front of Console
case 11:
case 16:
SetEscortPaused(true);
if (pInstance)
{
pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, IN_PROGRESS);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
if (GameObject* tribunal = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_TRIBUNAL_CONSOLE)))
tribunal->SetGoState(GO_STATE_ACTIVE);
}
break;
// Before Sjonnir's door
case 27:
//Tribunal end, stand in the middle of the sky room
case 17:
SetEscortPaused(true);
me->SetOrientation(3.91672f);
me->SendMovementFlagUpdate();
break;
//Run to the skyroom door and then teleport before Sjonnir's door
case 18:
SetEscortPaused(true);
SetNextWaypoint(33, false);
if (pInstance)
{
pInstance->SetData(BRANN_BRONZEBEARD, 5);
pInstance->SetData(BRANN_BRONZEBEARD, 4);
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_SJONNIR)))
cr->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetOrientation(3.132660f);
DoCast(me, 58506, false);
me->SendMovementFlagUpdate();
me->SetHomePosition(1199.8f, 667.138f, 196.242f, 3.12967f);
me->Relocate(1199.8f, 667.138f, 196.242f, 3.12967f);
}
break;
case 28:
// Before Sjonnir's door
case 33:
SetEscortPaused(true);
break;
case 29:
//Walk to the door, run after opening it
case 34:
SetEscortPaused(true);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_DOOR_OPEN, 1500);
me->SetWalk(false);
me->SetSpeed(MOVE_RUN, 1.0f, false);
events.ScheduleEvent(EVENT_RESUME_ESCORT, 3500);
break;
//Brann stops in front of Sjonnir and awaits the start of the battle.
case 36:
SetEscortPaused(true);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY_UNARMED);
me->SendMovementFlagUpdate();
Talk(SAY_BRANN_FRONT_OF_SJONNIR);
break;
//Brann steps back and uses the Sjonnir console.
case 38:
SetEscortPaused(true);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
if (pInstance)
{
if (GameObject* console = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(GO_SJONNIR_CONSOLE)))
console->SetGoState(GO_STATE_ACTIVE);
}
break;
//After Sjonnir's death, Brann steps away from the console and talk.
case 39:
SetEscortPaused(true);
break;
//Brann steps back and uses the Sjonnir console.
case 40:
SetEscortPaused(true);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
break;
}
}
@@ -864,9 +1133,9 @@ public:
};
};
class spell_hos_dark_matter_aura : public AuraScript
class spell_hos_dark_matter : public AuraScript
{
PrepareAuraScript(spell_hos_dark_matter_aura);
PrepareAuraScript(spell_hos_dark_matter);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
@@ -881,7 +1150,23 @@ class spell_hos_dark_matter_aura : public AuraScript
void Register() override
{
OnEffectRemove += AuraEffectRemoveFn(spell_hos_dark_matter_aura::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_hos_dark_matter::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_hos_dark_matter_size : public SpellScript
{
PrepareSpellScript(spell_hos_dark_matter_size);
void HandleApplyTouch()
{
if (Unit* target = GetHitUnit())
target->SetObjectScale(0.35f);
}
void Register() override
{
AfterHit += SpellHitFn(spell_hos_dark_matter_size::HandleApplyTouch);
}
};
@@ -891,5 +1176,6 @@ void AddSC_brann_bronzebeard()
new dark_rune_protectors();
new dark_rune_stormcaller();
new iron_golem_custodian();
RegisterSpellScript(spell_hos_dark_matter_aura);
RegisterSpellScript(spell_hos_dark_matter);
RegisterSpellScript(spell_hos_dark_matter_size);
}
@@ -24,6 +24,23 @@
#define HallsOfStoneScriptName "instance_halls_of_stone"
enum Texts
{
SAY_BRANN_KILL = 0,
SAY_BRANN_LOW_HEALTH = 1,
SAY_BRANN_DEATH = 2,
SAY_BRANN_PLAYER_DEATH = 3,
SAY_BRANN_ESCORT_START = 4,
SAY_BRANN_FRONT_OF_SJONNIR = 5,
SAY_BRANN_SPAWN_TROGG = 6,
SAY_BRANN_SPAWN_OOZE = 7,
SAY_BRANN_SPAWN_EARTHEN = 8,
SAY_BRANN_EVENT_INTRO_1 = 9,
SAY_BRANN_VICTORY_SJONNIR_1 = 30,
SAY_BRANN_VICTORY_SJONNIR_2 = 31,
SAY_BRANN_ENTRANCE_MEET = 32,
};
enum Encounter
{
BOSS_KRYSTALLUS = 0,
@@ -61,6 +78,15 @@ enum npcs
NPC_ABEDNEUM = 30899,
NPC_SJONNIR = 27978,
NPC_BRANN = 28070,
ACTION_START_ESCORT_EVENT = 0,
ACTION_START_TRIBUNAL = 1,
ACTION_TRIBUNAL_WIPE_START = 2,
ACTION_GO_TO_SJONNIR = 3,
ACTION_OPEN_DOOR = 4,
ACTION_START_SJONNIR_FIGHT = 5,
ACTION_SJONNIR_DEAD = 6,
ACTION_SJONNIR_WIPE_START = 7,
};
template <class AI, class T>
@@ -157,6 +157,8 @@ public:
return goMarnakGUID;
case GO_ABEDNEUM:
return goAbedneumGUID;
case GO_SKY_FLOOR:
return goSkyRoomFloorGUID;
case NPC_SJONNIR:
return SjonnirGUID;
@@ -210,23 +212,91 @@ public:
if (GameObject* tribunalDoor = instance->GetGameObject(goTribunalDoorGUID))
tribunalDoor->SetGoState(GO_STATE_ACTIVE);
if (type == BOSS_TRIBUNAL_OF_AGES && data == SPECIAL)
{
if (GameObject* pSkyRoomFloor = instance->GetGameObject(goSkyRoomFloorGUID))
pSkyRoomFloor->SetGoState(GO_STATE_READY);
}
if (type == BOSS_TRIBUNAL_OF_AGES && data == DONE)
{
if (GameObject* pA = instance->GetGameObject(goAbedneumGUID))
pA->SetGoState(GO_STATE_ACTIVE);
if (GameObject* pF = instance->GetGameObject(goSkyRoomFloorGUID))
pF->SetGoState(GO_STATE_ACTIVE);
GameObject* pAbedneum = instance->GetGameObject(goAbedneumGUID);
GameObject* pKaddrak = instance->GetGameObject(goKaddrakGUID);
GameObject* pMarnak = instance->GetGameObject(goMarnakGUID);
GameObject* pSkyRoomFloor = instance->GetGameObject(goSkyRoomFloorGUID);
bool skyRoomDown = false;
if (pAbedneum && pKaddrak && pMarnak && pSkyRoomFloor)
{
if (pAbedneum->GetGoState() != GO_STATE_ACTIVE)
{
if (pKaddrak->GetGoState() != GO_STATE_ACTIVE && pMarnak->GetGoState() != GO_STATE_ACTIVE)
{
//Abedneum first talk
pAbedneum->SetGoState(GO_STATE_ACTIVE);
}
else if (pMarnak->GetGoState() == GO_STATE_ACTIVE)
{
//Abedneum second talk
pAbedneum->SetGoState(GO_STATE_ACTIVE);
pMarnak->SetGoState(GO_STATE_READY);
pSkyRoomFloor->SetGoState(GO_STATE_READY);
skyRoomDown = true;
}
else
{
//Marnak talk
if (pKaddrak->GetGoState() == GO_STATE_ACTIVE)
{
pMarnak->SetGoState(GO_STATE_ACTIVE);
pKaddrak->SetGoState(GO_STATE_READY);
pSkyRoomFloor->SetGoState(GO_STATE_READY);
}
}
}
else
{
//Kaddrak talk
if (pKaddrak->GetGoState() != GO_STATE_ACTIVE)
{
pAbedneum->SetGoState(GO_STATE_READY);
pKaddrak->SetGoState(GO_STATE_ACTIVE);
pSkyRoomFloor->SetGoState(GO_STATE_READY);
}
}
if (!skyRoomDown)
pSkyRoomFloor->SetGoState(GO_STATE_ACTIVE);
}
// Make sjonnir attackable
if (Creature* cr = instance->GetCreature(SjonnirGUID))
cr->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
if (Creature* cSjonnir = instance->GetCreature(SjonnirGUID))
cSjonnir->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
if (type == BOSS_TRIBUNAL_OF_AGES && data == NOT_STARTED)
{
if (GameObject* pA = instance->GetGameObject(goAbedneumGUID))
pA->SetGoState(GO_STATE_READY);
if (GameObject* pF = instance->GetGameObject(goSkyRoomFloorGUID))
pF->SetGoState(GO_STATE_READY);
if (GameObject* pAbedneum = instance->GetGameObject(goAbedneumGUID))
pAbedneum->SetGoState(GO_STATE_READY);
if (GameObject* pKaddrak = instance->GetGameObject(goKaddrakGUID))
pKaddrak->SetGoState(GO_STATE_READY);
if (GameObject* pMarnak = instance->GetGameObject(goMarnakGUID))
pMarnak->SetGoState(GO_STATE_READY);
if (GameObject* pSkyRoomFloor = instance->GetGameObject(goSkyRoomFloorGUID))
pSkyRoomFloor->SetGoState(GO_STATE_READY);
}
if (type == BOSS_TRIBUNAL_OF_AGES && data == FAIL)
{
if (GameObject* pAbedneum = instance->GetGameObject(goAbedneumGUID))
pAbedneum->SetGoState(GO_STATE_ACTIVE);
if (GameObject* pKaddrak = instance->GetGameObject(goKaddrakGUID))
pKaddrak->SetGoState(GO_STATE_ACTIVE);
if (GameObject* pMarnak = instance->GetGameObject(goMarnakGUID))
pMarnak->SetGoState(GO_STATE_ACTIVE);
if (GameObject* pSkyRoomFloor = instance->GetGameObject(goSkyRoomFloorGUID))
pSkyRoomFloor->SetGoState(GO_STATE_READY);
}
if (type == DATA_BRANN_ACHIEVEMENT)
@@ -1129,7 +1129,7 @@ public:
DoMeleeAttackIfReady();
Unit* cannon = GetS3();
if (!cannon || cannon->HasUnitState(UNIT_STATE_CASTING) || me->HasUnitState(UNIT_STATE_CASTING) || me->HasAuraType(SPELL_AURA_MOD_SILENCE))
if (!cannon || cannon->HasUnitState(UNIT_STATE_CASTING) || me->HasUnitState(UNIT_STATE_CASTING) || me->HasSilenceAura())
return;
switch (events.ExecuteEvent())
@@ -2603,7 +2603,7 @@ class spell_yogg_saron_insane_periodic_trigger : public SpellScript
{
std::list<WorldObject*> tmplist;
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
if ((*itr)->IsPlayer() && !(*itr)->ToPlayer()->HasAuraType(SPELL_AURA_AOE_CHARM) && !(*itr)->ToPlayer()->HasAura(SPELL_SANITY))
if ((*itr)->IsPlayer() && !(*itr)->ToPlayer()->HasAOECharmAura() && !(*itr)->ToPlayer()->HasAura(SPELL_SANITY))
tmplist.push_back(*itr);
targets.clear();
@@ -99,299 +99,288 @@ enum eEvents
EVENT_AXE_PICKUP,
};
class boss_ingvar_the_plunderer : public CreatureScript
struct boss_ingvar_the_plunderer : public ScriptedAI
{
public:
boss_ingvar_the_plunderer() : CreatureScript("boss_ingvar_the_plunderer") { }
CreatureAI* GetAI(Creature* pCreature) const override
boss_ingvar_the_plunderer(Creature* c) : ScriptedAI(c), summons(me)
{
return GetUtgardeKeepAI<boss_ingvar_the_plundererAI>(pCreature);
pInstance = c->GetInstanceScript();
}
struct boss_ingvar_the_plundererAI : public ScriptedAI
InstanceScript* pInstance;
EventMap events;
SummonList summons;
ObjectGuid ValkyrGUID;
ObjectGuid ThrowGUID;
void Reset() override
{
boss_ingvar_the_plundererAI(Creature* c) : ScriptedAI(c), summons(me)
{
pInstance = c->GetInstanceScript();
}
ValkyrGUID.Clear();
ThrowGUID.Clear();
events.Reset();
summons.DespawnAll();
me->SetDisplayId(DISPLAYID_DEFAULT);
me->LoadEquipment(1);
FeignDeath(false);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
InstanceScript* pInstance;
EventMap events;
SummonList summons;
ObjectGuid ValkyrGUID;
ObjectGuid ThrowGUID;
if (pInstance)
pInstance->SetData(DATA_INGVAR, NOT_STARTED);
}
void Reset() override
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (me->GetDisplayId() == DISPLAYID_DEFAULT && damage >= me->GetHealth())
{
ValkyrGUID.Clear();
ThrowGUID.Clear();
events.Reset();
summons.DespawnAll();
me->SetDisplayId(DISPLAYID_DEFAULT);
me->LoadEquipment(1);
FeignDeath(false);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
damage = 0;
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
if (pInstance)
pInstance->SetData(DATA_INGVAR, NOT_STARTED);
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (me->GetDisplayId() == DISPLAYID_DEFAULT && damage >= me->GetHealth())
{
damage = 0;
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
me->GetMotionMaster()->MovementExpired();
me->GetMotionMaster()->MoveIdle();
me->StopMoving();
FeignDeath(true);
events.Reset();
events.RescheduleEvent(EVENT_START_RESURRECTION, 1s);
events.RescheduleEvent(EVENT_YELL_DEAD_1, 0ms);
}
}
void JustEngagedWith(Unit* /*who*/) override
{
me->GetMotionMaster()->MovementExpired();
me->GetMotionMaster()->MoveIdle();
me->StopMoving();
FeignDeath(true);
events.Reset();
// schedule Phase 1 abilities
events.RescheduleEvent(EVENT_START_RESURRECTION, 1s);
events.RescheduleEvent(EVENT_YELL_DEAD_1, 0ms);
}
}
void JustEngagedWith(Unit* /*who*/) override
{
events.Reset();
// schedule Phase 1 abilities
events.RescheduleEvent(EVENT_SPELL_ROAR, 15s);
events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2s);
events.RescheduleEvent(EVENT_SPELL_SMASH, 5s);
events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10s);
Talk(YELL_AGGRO_1);
me->LowerPlayerDamageReq(me->GetMaxHealth());
if (pInstance)
pInstance->SetData(DATA_INGVAR, IN_PROGRESS);
}
void JustSummoned(Creature* s) override
{
summons.Summon(s);
if (s->GetEntry() == NPC_ANNHYLDE)
{
ValkyrGUID = s->GetGUID();
s->SetCanFly(true);
s->SetDisableGravity(true);
s->SetPosition(s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() + 35.0f, s->GetOrientation());
s->SetFacingTo(s->GetOrientation());
}
else if (s->GetEntry() == NPC_THROW)
{
ThrowGUID = s->GetGUID();
if (Unit* t = SelectTarget(SelectTargetMethod::Random, 0, 70.0f, true))
s->GetMotionMaster()->MovePoint(0, t->GetPositionX(), t->GetPositionY(), t->GetPositionZ());
}
}
void KilledUnit(Unit* /*who*/) override
{
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
Talk(YELL_KILL_2);
else
Talk(YELL_KILL_1);
}
void FeignDeath(bool apply)
{
if (apply)
{
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetDynamicFlag(UNIT_DYNFLAG_DEAD);
}
else
{
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD);
}
}
void JustDied(Unit* /*killer*/) override
{
events.Reset();
summons.DespawnAll();
Talk(YELL_DEAD_2);
if (pInstance)
{
pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_INGVAR_UNDEAD, 1); // undead entry needed for achievements
pInstance->SetData(DATA_INGVAR, DONE);
}
}
void EnterEvadeMode(EvadeReason why) override
{
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
ScriptedAI::EnterEvadeMode(why);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case 0:
break;
case EVENT_YELL_DEAD_1:
Talk(YELL_DEAD_1);
break;
case EVENT_START_RESURRECTION:
me->CastSpell(me, SPELL_SUMMON_VALKYR, true);
events.RescheduleEvent(EVENT_VALKYR_BEAM, 7s);
events.RescheduleEvent(EVENT_VALKYR_MOVE, 1ms);
events.RescheduleEvent(EVENT_ANNHYLDE_YELL, 3s);
break;
case EVENT_VALKYR_MOVE:
if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID))
s->GetMotionMaster()->MovePoint(1, s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() - 15.0f);
break;
case EVENT_ANNHYLDE_YELL:
if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID))
s->AI()->Talk(YELL_ANHYLDE_2);
break;
case EVENT_VALKYR_BEAM:
me->RemoveAura(SPELL_SUMMON_VALKYR);
if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID))
c->CastSpell(me, SPELL_RESURRECTION_BEAM, false);
events.RescheduleEvent(EVENT_RESURRECTION_BALL, 4s);
break;
case EVENT_RESURRECTION_BALL:
me->CastSpell(me, SPELL_RESURRECTION_BALL, true);
events.RescheduleEvent(EVENT_RESURRECTION_HEAL, 4s);
break;
case EVENT_RESURRECTION_HEAL:
me->RemoveAura(SPELL_RESURRECTION_BALL);
me->CastSpell(me, SPELL_RESURRECTION_HEAL, true);
FeignDeath(false);
events.RescheduleEvent(EVENT_MORPH_TO_UNDEAD, 3s);
break;
case EVENT_MORPH_TO_UNDEAD:
me->CastSpell(me, SPELL_INGVAR_TRANSFORM, true);
events.RescheduleEvent(EVENT_START_PHASE_2, 1s);
break;
case EVENT_START_PHASE_2:
if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID))
{
c->DespawnOrUnsummon();
summons.DespawnAll();
}
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
AttackStart(me->GetVictim());
me->GetMotionMaster()->MoveChase(me->GetVictim());
Talk(YELL_AGGRO_2);
// schedule Phase 2 abilities
events.RescheduleEvent(EVENT_SPELL_ROAR, 15s);
events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2s);
events.RescheduleEvent(EVENT_SPELL_SMASH, 5s);
events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10s);
Talk(YELL_AGGRO_1);
me->LowerPlayerDamageReq(me->GetMaxHealth());
break;
if (pInstance)
pInstance->SetData(DATA_INGVAR, IN_PROGRESS);
}
void JustSummoned(Creature* s) override
{
summons.Summon(s);
if (s->GetEntry() == NPC_ANNHYLDE)
{
ValkyrGUID = s->GetGUID();
s->SetCanFly(true);
s->SetDisableGravity(true);
s->SetPosition(s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() + 35.0f, s->GetOrientation());
s->SetFacingTo(s->GetOrientation());
}
else if (s->GetEntry() == NPC_THROW)
{
ThrowGUID = s->GetGUID();
if (Unit* t = SelectTarget(SelectTargetMethod::Random, 0, 70.0f, true))
s->GetMotionMaster()->MovePoint(0, t->GetPositionX(), t->GetPositionY(), t->GetPositionZ());
}
}
void KilledUnit(Unit* /*who*/) override
{
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
Talk(YELL_KILL_2);
else
Talk(YELL_KILL_1);
}
void FeignDeath(bool apply)
{
if (apply)
{
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetDynamicFlag(UNIT_DYNFLAG_DEAD);
}
else
{
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD);
}
}
void JustDied(Unit* /*killer*/) override
{
events.Reset();
summons.DespawnAll();
Talk(YELL_DEAD_2);
if (pInstance)
{
pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_INGVAR_UNDEAD, 1); // undead entry needed for achievements
pInstance->SetData(DATA_INGVAR, DONE);
}
}
void EnterEvadeMode(EvadeReason why) override
{
// ABILITIES HERE:
case EVENT_UNROOT:
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
ScriptedAI::EnterEvadeMode(why);
}
break;
case EVENT_SPELL_ROAR:
Talk(EMOTE_ROAR);
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
me->_AddCreatureSpellCooldown(SPELL_STAGGERING_ROAR, 0, 0);
me->_AddCreatureSpellCooldown(SPELL_DREADFUL_ROAR, 0, 0);
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell((Unit*)nullptr, SPELL_STAGGERING_ROAR, false);
else
me->CastSpell((Unit*)nullptr, SPELL_DREADFUL_ROAR, false);
events.Repeat(15s, 20s);
break;
case EVENT_SPELL_CLEAVE_OR_WOE_STRIKE:
if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0)
{
case 0:
break;
case EVENT_YELL_DEAD_1:
Talk(YELL_DEAD_1);
break;
case EVENT_START_RESURRECTION:
me->CastSpell(me, SPELL_SUMMON_VALKYR, true);
events.RescheduleEvent(EVENT_VALKYR_BEAM, 7s);
events.RescheduleEvent(EVENT_VALKYR_MOVE, 1ms);
events.RescheduleEvent(EVENT_ANNHYLDE_YELL, 3s);
break;
case EVENT_VALKYR_MOVE:
if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID))
s->GetMotionMaster()->MovePoint(1, s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() - 15.0f);
break;
case EVENT_ANNHYLDE_YELL:
if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID))
s->AI()->Talk(YELL_ANHYLDE_2);
break;
case EVENT_VALKYR_BEAM:
me->RemoveAura(SPELL_SUMMON_VALKYR);
if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID))
c->CastSpell(me, SPELL_RESURRECTION_BEAM, false);
events.RescheduleEvent(EVENT_RESURRECTION_BALL, 4s);
break;
case EVENT_RESURRECTION_BALL:
me->CastSpell(me, SPELL_RESURRECTION_BALL, true);
events.RescheduleEvent(EVENT_RESURRECTION_HEAL, 4s);
break;
case EVENT_RESURRECTION_HEAL:
me->RemoveAura(SPELL_RESURRECTION_BALL);
me->CastSpell(me, SPELL_RESURRECTION_HEAL, true);
FeignDeath(false);
events.RescheduleEvent(EVENT_MORPH_TO_UNDEAD, 3s);
break;
case EVENT_MORPH_TO_UNDEAD:
me->CastSpell(me, SPELL_INGVAR_TRANSFORM, true);
events.RescheduleEvent(EVENT_START_PHASE_2, 1s);
break;
case EVENT_START_PHASE_2:
if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID))
{
c->DespawnOrUnsummon();
summons.DespawnAll();
}
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
AttackStart(me->GetVictim());
me->GetMotionMaster()->MoveChase(me->GetVictim());
Talk(YELL_AGGRO_2);
// schedule Phase 2 abilities
events.RescheduleEvent(EVENT_SPELL_ROAR, 15s);
events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2s);
events.RescheduleEvent(EVENT_SPELL_SMASH, 5s);
events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10s);
break;
// ABILITIES HERE:
case EVENT_UNROOT:
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
break;
case EVENT_SPELL_ROAR:
Talk(EMOTE_ROAR);
me->_AddCreatureSpellCooldown(SPELL_STAGGERING_ROAR, 0, 0);
me->_AddCreatureSpellCooldown(SPELL_DREADFUL_ROAR, 0, 0);
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell((Unit*)nullptr, SPELL_STAGGERING_ROAR, false);
else
me->CastSpell((Unit*)nullptr, SPELL_DREADFUL_ROAR, false);
events.Repeat(15s, 20s);
break;
case EVENT_SPELL_CLEAVE_OR_WOE_STRIKE:
if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0 )
{
events.Repeat(3s);
break;
}
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
else
me->CastSpell(me->GetVictim(), SPELL_WOE_STRIKE, false);
events.Repeat(3s, 7s);
break;
case EVENT_SPELL_SMASH:
if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0 )
{
events.Repeat(3s);
break;
}
me->SetControlled(true, UNIT_STATE_ROOT);
me->DisableRotate(true);
me->SendMovementFlagUpdate();
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell((Unit*)nullptr, SPELL_SMASH, false);
else
me->CastSpell((Unit*)nullptr, SPELL_DARK_SMASH, false);
events.Repeat(9s, 11s);
events.RescheduleEvent(EVENT_UNROOT, 3750ms);
break;
case EVENT_SPELL_ENRAGE_OR_SHADOW_AXE:
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
{
me->CastSpell(me, SPELL_ENRAGE, false);
events.Repeat(10s);
}
else
{
me->CastSpell((Unit*)nullptr, SPELL_SHADOW_AXE, true);
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
events.Repeat(35s);
events.RescheduleEvent(EVENT_AXE_RETURN, 10s);
}
break;
case EVENT_AXE_RETURN:
if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
c->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
events.RescheduleEvent(EVENT_AXE_PICKUP, 1500ms);
break;
case EVENT_AXE_PICKUP:
if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
{
c->DestroyForNearbyPlayers();
c->DespawnOrUnsummon();
summons.DespawnAll();
}
ThrowGUID.Clear();
SetEquipmentSlots(true);
break;
events.Repeat(3s);
break;
}
if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
DoMeleeAttackIfReady();
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
else
me->CastSpell(me->GetVictim(), SPELL_WOE_STRIKE, false);
events.Repeat(3s, 7s);
break;
case EVENT_SPELL_SMASH:
if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0)
{
events.Repeat(3s);
break;
}
me->SetControlled(true, UNIT_STATE_ROOT);
me->DisableRotate(true);
me->SendMovementFlagUpdate();
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell((Unit*)nullptr, SPELL_SMASH, false);
else
me->CastSpell((Unit*)nullptr, SPELL_DARK_SMASH, false);
events.Repeat(9s, 11s);
events.RescheduleEvent(EVENT_UNROOT, 3750ms);
break;
case EVENT_SPELL_ENRAGE_OR_SHADOW_AXE:
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
{
me->CastSpell(me, SPELL_ENRAGE, false);
events.Repeat(10s);
}
else
{
me->CastSpell((Unit*)nullptr, SPELL_SHADOW_AXE, true);
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
events.Repeat(35s);
events.RescheduleEvent(EVENT_AXE_RETURN, 10s);
}
break;
case EVENT_AXE_RETURN:
if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
c->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
events.RescheduleEvent(EVENT_AXE_PICKUP, 1500ms);
break;
case EVENT_AXE_PICKUP:
if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
{
c->DestroyForNearbyPlayers();
c->DespawnOrUnsummon();
summons.DespawnAll();
}
ThrowGUID.Clear();
SetEquipmentSlots(true);
break;
}
};
if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
DoMeleeAttackIfReady();
}
};
void AddSC_boss_ingvar_the_plunderer()
{
new boss_ingvar_the_plunderer();
RegisterUtgardeKeepCreatureAI(boss_ingvar_the_plunderer);
}
@@ -51,183 +51,105 @@ enum eSpells
#define SPELL_SHADOWBOLT DUNGEON_MODE(SPELL_SHADOWBOLT_N, SPELL_SHADOWBOLT_H)
enum eEvents
struct npc_frost_tomb : public NullCreatureAI
{
EVENT_SPELL_SHADOWBOLT = 1,
EVENT_FROST_TOMB,
EVENT_SUMMON_SKELETONS,
};
class npc_frost_tomb : public CreatureScript
{
public:
npc_frost_tomb() : CreatureScript("npc_frost_tomb") { }
CreatureAI* GetAI(Creature* pCreature) const override
npc_frost_tomb(Creature* c) : NullCreatureAI(c)
{
return GetUtgardeKeepAI<npc_frost_tombAI>(pCreature);
}
struct npc_frost_tombAI : public NullCreatureAI
{
npc_frost_tombAI(Creature* c) : NullCreatureAI(c)
{
if (TempSummon* t = c->ToTempSummon())
if (Unit* s = t->GetSummonerUnit())
{
PrisonerGUID = s->GetGUID();
if (me->GetInstanceScript() && me->GetInstanceScript()->instance->IsHeroic())
{
const int32 dmg = 2000;
c->CastCustomSpell(s, SPELL_FROST_TOMB_AURA, nullptr, &dmg, nullptr, true);
}
else
c->CastSpell(s, SPELL_FROST_TOMB_AURA, true);
}
}
ObjectGuid PrisonerGUID;
void JustDied(Unit* killer) override
{
if (killer && killer->GetGUID() != me->GetGUID())
if (InstanceScript* pInstance = me->GetInstanceScript())
pInstance->SetData(DATA_ON_THE_ROCKS_ACHIEV, 0);
if (PrisonerGUID)
if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID))
p->RemoveAurasDueToSpell(SPELL_FROST_TOMB_AURA);
me->DespawnOrUnsummon(5000);
}
void UpdateAI(uint32 /*diff*/) override
{
if (PrisonerGUID)
if (WorldObject* summoner = GetSummoner())
if (Unit* summonerUnit = summoner->ToUnit())
{
if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID))
PrisonerGUID = summonerUnit->GetGUID();
if (me->GetInstanceScript() && me->GetInstanceScript()->instance->IsHeroic())
{
if (!p->HasAura(SPELL_FROST_TOMB_AURA))
me->KillSelf();
const int32 dmg = 2000;
c->CastCustomSpell(summonerUnit, SPELL_FROST_TOMB_AURA, nullptr, &dmg, nullptr, true);
}
else
me->KillSelf();
c->CastSpell(summonerUnit, SPELL_FROST_TOMB_AURA, true);
}
}
};
};
class boss_keleseth : public CreatureScript
{
public:
boss_keleseth() : CreatureScript("boss_keleseth") { }
CreatureAI* GetAI(Creature* pCreature) const override
{
return GetUtgardeKeepAI<boss_kelesethAI>(pCreature);
}
struct boss_kelesethAI : public ScriptedAI
ObjectGuid PrisonerGUID;
void JustDied(Unit* killer) override
{
boss_kelesethAI(Creature* c) : ScriptedAI(c)
{
pInstance = c->GetInstanceScript();
}
if (killer && killer->GetGUID() != me->GetGUID())
if (InstanceScript* pInstance = me->GetInstanceScript())
pInstance->SetData(DATA_ON_THE_ROCKS_ACHIEV, 0);
InstanceScript* pInstance;
EventMap events;
if (PrisonerGUID)
if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID))
p->RemoveAurasDueToSpell(SPELL_FROST_TOMB_AURA);
me->DespawnOrUnsummon(5000);
}
void Reset() override
void UpdateAI(uint32 /*diff*/) override
{
if (PrisonerGUID)
{
events.Reset();
if (pInstance)
pInstance->SetData(DATA_KELESETH, NOT_STARTED);
}
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer())
if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID))
{
Talk(SAY_KILL);
if (!p->HasAura(SPELL_FROST_TOMB_AURA))
me->KillSelf();
}
else
me->KillSelf();
}
}
};
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
if (pInstance)
pInstance->SetData(DATA_KELESETH, DONE);
}
struct boss_keleseth : public BossAI
{
boss_keleseth(Creature* creature) : BossAI(creature, DATA_KELESETH) { }
void JustEngagedWith(Unit* /*who*/) override
{
events.Reset();
events.RescheduleEvent(EVENT_SPELL_SHADOWBOLT, 0ms);
events.RescheduleEvent(EVENT_FROST_TOMB, 28s);
events.RescheduleEvent(EVENT_SUMMON_SKELETONS, 4s);
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer())
Talk(SAY_KILL);
}
Talk(SAY_START_COMBAT);
DoZoneInCombat();
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
}
if (pInstance)
pInstance->SetData(DATA_KELESETH, IN_PROGRESS);
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
Talk(SAY_START_COMBAT);
void AttackStart(Unit* who) override
{
if (!who)
return;
ScheduleTimedEvent(1s, [&] {
DoCastVictim(SPELL_SHADOWBOLT);
}, 4s, 5s);
UnitAI::AttackStartCaster(who, 12.0f);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
ScheduleTimedEvent(28s, [&] {
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_FROST_TOMB_AURA))
{
case 0:
break;
case EVENT_SPELL_SHADOWBOLT:
me->CastSpell(me->GetVictim(), SPELL_SHADOWBOLT, false);
events.Repeat(4s, 5s);
break;
case EVENT_FROST_TOMB:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true))
if (!target->HasAura(SPELL_FROST_TOMB_AURA))
{
Talk(SAY_FROST_TOMB_EMOTE, target);
Talk(SAY_FROST_TOMB);
me->CastSpell(target, SPELL_FROST_TOMB, false);
events.Repeat(15s);
break;
}
events.Repeat(1s);
break;
case EVENT_SUMMON_SKELETONS:
Talk(SAY_SUMMON_SKELETONS);
for (uint8 i = 0; i < 5; ++i)
{
float dist = rand_norm() * 4 + 3.0f;
float angle = rand_norm() * 2 * M_PI;
if (Creature* c = me->SummonCreature(NPC_SKELETON, 156.2f + cos(angle) * dist, 259.1f + std::sin(angle) * dist, 42.9f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
if (Unit* target = c->SelectNearestTarget(250.0f))
{
c->AddThreat(target, 5.0f);
DoZoneInCombat(c);
}
}
break;
Talk(SAY_FROST_TOMB_EMOTE, target);
Talk(SAY_FROST_TOMB);
DoCast(target, SPELL_FROST_TOMB);
}
}, 15s);
DoMeleeAttackIfReady();
}
};
me->m_Events.AddEventAtOffset([this]() {
Talk(SAY_SUMMON_SKELETONS);
for (uint8 i = 0; i < 5; ++i)
{
float dist = rand_norm() * 4 + 3.0f;
float angle = rand_norm() * 2 * M_PI;
me->SummonCreature(NPC_SKELETON, 156.2f + cos(angle) * dist, 259.1f + std::sin(angle) * dist, 42.9f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
}
}, 4s);
}
void AttackStart(Unit* who) override
{
if (!who)
return;
UnitAI::AttackStartCaster(who, 12.0f);
}
};
enum eSkeletonEnum
@@ -242,105 +164,94 @@ enum eSkeletonEnum
EVENT_RESURRECT_2,
};
class npc_vrykul_skeleton : public CreatureScript
struct npc_vrykul_skeleton : public ScriptedAI
{
public:
npc_vrykul_skeleton() : CreatureScript("npc_vrykul_skeleton") { }
CreatureAI* GetAI(Creature* pCreature) const override
npc_vrykul_skeleton(Creature* c) : ScriptedAI(c)
{
return GetUtgardeKeepAI<npc_vrykul_skeletonAI>(pCreature);
pInstance = c->GetInstanceScript();
}
struct npc_vrykul_skeletonAI : public ScriptedAI
InstanceScript* pInstance;
EventMap events;
void Reset() override
{
npc_vrykul_skeletonAI(Creature* c) : ScriptedAI(c)
events.Reset();
events.RescheduleEvent(EVENT_SPELL_DECREPIFY, 10s, 20s);
if (IsHeroic())
events.RescheduleEvent(EVENT_SPELL_BONE_ARMOR, 25s, 120s);
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (damage >= me->GetHealth())
{
pInstance = c->GetInstanceScript();
damage = 0;
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(true, UNIT_STATE_ROOT);
me->GetMotionMaster()->MovementExpired();
me->GetMotionMaster()->MoveIdle();
me->StopMoving();
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetDynamicFlag(UNIT_DYNFLAG_DEAD);
events.RescheduleEvent(EVENT_RESURRECT, 12s);
}
}
void UpdateAI(uint32 diff) override
{
if (pInstance && pInstance->GetBossState(DATA_KELESETH) != IN_PROGRESS)
{
if (me->IsAlive())
me->KillSelf();
return;
}
InstanceScript* pInstance;
EventMap events;
if (!UpdateVictim())
return;
void Reset() override
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
events.Reset();
events.RescheduleEvent(EVENT_SPELL_DECREPIFY, 10s, 20s);
if (IsHeroic())
events.RescheduleEvent(EVENT_SPELL_BONE_ARMOR, 25s, 120s);
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (damage >= me->GetHealth())
{
damage = 0;
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(true, UNIT_STATE_ROOT);
me->GetMotionMaster()->MovementExpired();
me->GetMotionMaster()->MoveIdle();
me->StopMoving();
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetDynamicFlag(UNIT_DYNFLAG_DEAD);
events.RescheduleEvent(EVENT_RESURRECT, 12s);
}
}
void UpdateAI(uint32 diff) override
{
if (pInstance && pInstance->GetData(DATA_KELESETH) != IN_PROGRESS )
{
if (me->IsAlive())
me->KillSelf();
return;
}
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case 0:
break;
case EVENT_SPELL_DECREPIFY:
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
me->CastSpell(me->GetVictim(), SPELL_DECREPIFY, false);
events.Repeat(15s, 25s);
break;
case EVENT_SPELL_BONE_ARMOR:
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
me->CastSpell((Unit*)nullptr, SPELL_BONE_ARMOR, false);
events.Repeat(40s, 120s);
break;
case EVENT_RESURRECT:
events.DelayEvents(3500ms);
DoCast(me, SPELL_SCOURGE_RESURRECTION, true);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD);
events.RescheduleEvent(EVENT_RESURRECT_2, 3s);
break;
case EVENT_RESURRECT_2:
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->GetMotionMaster()->MoveChase(me->GetVictim());
break;
}
case 0:
break;
case EVENT_SPELL_DECREPIFY:
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
DoMeleeAttackIfReady();
me->CastSpell(me->GetVictim(), SPELL_DECREPIFY, false);
events.Repeat(15s, 25s);
break;
case EVENT_SPELL_BONE_ARMOR:
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
me->CastSpell((Unit*)nullptr, SPELL_BONE_ARMOR, false);
events.Repeat(40s, 120s);
break;
case EVENT_RESURRECT:
events.DelayEvents(3500ms);
DoCast(me, SPELL_SCOURGE_RESURRECTION, true);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD);
events.RescheduleEvent(EVENT_RESURRECT_2, 3s);
break;
case EVENT_RESURRECT_2:
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->GetMotionMaster()->MoveChase(me->GetVictim());
break;
}
};
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
DoMeleeAttackIfReady();
}
};
class spell_frost_tomb_aura : public AuraScript
@@ -368,8 +279,8 @@ class spell_frost_tomb_aura : public AuraScript
void AddSC_boss_keleseth()
{
new boss_keleseth();
new npc_frost_tomb();
new npc_vrykul_skeleton();
RegisterUtgardeKeepCreatureAI(boss_keleseth);
RegisterUtgardeKeepCreatureAI(npc_frost_tomb);
RegisterUtgardeKeepCreatureAI(npc_vrykul_skeleton);
RegisterSpellScript(spell_frost_tomb_aura);
}
@@ -66,182 +66,161 @@ enum eEvents
EVENT_MATE_DIED
};
class boss_skarvald_the_constructor : public CreatureScript
struct boss_skarvald_the_constructor : public ScriptedAI
{
public:
boss_skarvald_the_constructor() : CreatureScript("boss_skarvald_the_constructor") { }
CreatureAI* GetAI(Creature* pCreature) const override
boss_skarvald_the_constructor(Creature* c) : ScriptedAI(c)
{
return GetUtgardeKeepAI<boss_skarvald_the_constructorAI>(pCreature);
pInstance = c->GetInstanceScript();
}
struct boss_skarvald_the_constructorAI : public ScriptedAI
InstanceScript* pInstance;
EventMap events;
void Reset() override
{
boss_skarvald_the_constructorAI(Creature* c) : ScriptedAI(c)
me->SetLootMode(0);
events.Reset();
if (me->GetEntry() == NPC_SKARVALD)
{
pInstance = c->GetInstanceScript();
}
InstanceScript* pInstance;
EventMap events;
void Reset() override
{
me->SetLootMode(0);
events.Reset();
if (me->GetEntry() == NPC_SKARVALD)
{
if (pInstance)
{
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, NOT_STARTED);
}
}
else // NPC_SKARVALD_GHOST
{
if (Unit* target = me->SelectNearestTarget(50.0f))
{
me->AddThreat(target, 0.0f);
AttackStart(target);
}
}
}
void DoAction(int32 param) override
{
switch (param)
{
case 1:
events.RescheduleEvent(EVENT_MATE_DIED, 3500ms);
break;
}
}
void JustEngagedWith(Unit* who) override
{
events.Reset();
events.RescheduleEvent(EVENT_SHARVALD_CHARGE, 5s);
events.RescheduleEvent(EVENT_STONE_STRIKE, 10s);
if (me->GetEntry() == NPC_SKARVALD)
{
Talk(YELL_SKARVALD_AGGRO);
if (IsHeroic())
{
events.ScheduleEvent(EVENT_ENRAGE, 1s);
}
}
if (pInstance)
{
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, IN_PROGRESS);
if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN)))
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, NOT_STARTED);
}
}
else // NPC_SKARVALD_GHOST
{
if (Unit* target = me->SelectNearestTarget(50.0f))
{
me->AddThreat(target, 0.0f);
AttackStart(target);
}
}
}
void DoAction(int32 param) override
{
switch (param)
{
case 1:
events.RescheduleEvent(EVENT_MATE_DIED, 3500ms);
break;
}
}
void JustEngagedWith(Unit* who) override
{
events.Reset();
events.RescheduleEvent(EVENT_SHARVALD_CHARGE, 5s);
events.RescheduleEvent(EVENT_STONE_STRIKE, 10s);
if (me->GetEntry() == NPC_SKARVALD)
{
Talk(YELL_SKARVALD_AGGRO);
if (IsHeroic())
{
events.ScheduleEvent(EVENT_ENRAGE, 1s);
}
}
if (pInstance)
{
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, IN_PROGRESS);
if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN)))
{
if (!dalronn->IsInCombat() && who)
{
if (!dalronn->IsInCombat() && who)
{
dalronn->AddThreat(who, 0.0f);
dalronn->AI()->AttackStart(who);
}
dalronn->AddThreat(who, 0.0f);
dalronn->AI()->AttackStart(who);
}
}
}
}
void KilledUnit(Unit* /*victim*/) override
void KilledUnit(Unit* /*victim*/) override
{
if (me->GetEntry() == NPC_SKARVALD)
{
if (me->GetEntry() == NPC_SKARVALD)
{
Talk(YELL_SKARVALD_KILL);
}
Talk(YELL_SKARVALD_KILL);
}
}
void JustDied(Unit* /*Killer*/) override
void JustDied(Unit* /*Killer*/) override
{
if (me->GetEntry() != NPC_SKARVALD)
return;
if (pInstance)
{
if (me->GetEntry() != NPC_SKARVALD)
return;
if (pInstance)
if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN)))
{
if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN)))
if (dalronn->isDead())
{
if (dalronn->isDead())
{
Talk(YELL_SKARVALD_SKA_DIEDFIRST);
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, DONE);
pInstance->SetData(DATA_UNLOCK_SKARVALD_LOOT, 0);
return;
}
else
{
Talk(YELL_SKARVALD_DAL_DIED);
dalronn->AI()->DoAction(1);
}
Talk(YELL_SKARVALD_SKA_DIEDFIRST);
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, DONE);
pInstance->SetData(DATA_UNLOCK_SKARVALD_LOOT, 0);
return;
}
else
{
Talk(YELL_SKARVALD_DAL_DIED);
dalronn->AI()->DoAction(1);
}
}
me->CastSpell((Unit*)nullptr, SPELL_SUMMON_SKARVALD_GHOST, true);
}
me->CastSpell((Unit*)nullptr, SPELL_SUMMON_SKARVALD_GHOST, true);
}
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
case 0:
break;
case EVENT_MATE_DIED:
Talk(YELL_SKARVALD_DAL_DIEDFIRST);
break;
case EVENT_SHARVALD_CHARGE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, (IsHeroic() ? 100.0f : 30.0f), true))
{
case 0:
break;
case EVENT_MATE_DIED:
Talk(YELL_SKARVALD_DAL_DIEDFIRST);
break;
case EVENT_SHARVALD_CHARGE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, (IsHeroic() ? 100.0f : 30.0f), true))
{
DoResetThreatList();
me->AddThreat(target, 10000.0f);
me->CastSpell(target, SPELL_CHARGE, false);
}
events.Repeat(5s, 10s);
break;
case EVENT_STONE_STRIKE:
if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()))
{
me->CastSpell(me->GetVictim(), SPELL_STONE_STRIKE, false);
events.Repeat(5s, 10s);
}
else
{
events.Repeat(3s);
}
break;
case EVENT_ENRAGE:
if (me->GetHealthPct() <= 60)
{
me->CastSpell(me, SPELL_ENRAGE, true);
break;
}
events.Repeat(1s);
break;
DoResetThreatList();
me->AddThreat(target, 10000.0f);
me->CastSpell(target, SPELL_CHARGE, false);
}
DoMeleeAttackIfReady();
events.Repeat(5s, 10s);
break;
case EVENT_STONE_STRIKE:
if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()))
{
me->CastSpell(me->GetVictim(), SPELL_STONE_STRIKE, false);
events.Repeat(5s, 10s);
}
else
{
events.Repeat(3s);
}
break;
case EVENT_ENRAGE:
if (me->GetHealthPct() <= 60)
{
me->CastSpell(me, SPELL_ENRAGE, true);
break;
}
events.Repeat(1s);
break;
}
};
DoMeleeAttackIfReady();
}
};
class boss_dalronn_the_controller : public CreatureScript
{
public:
boss_dalronn_the_controller() : CreatureScript("boss_dalronn_the_controller") { }
CreatureAI* GetAI(Creature* pCreature) const override
struct boss_dalronn_the_controller : public ScriptedAI
{
return GetUtgardeKeepAI<boss_dalronn_the_controllerAI>(pCreature);
}
struct boss_dalronn_the_controllerAI : public ScriptedAI
{
boss_dalronn_the_controllerAI(Creature* c) : ScriptedAI(c), summons(me)
boss_dalronn_the_controller(Creature* c) : ScriptedAI(c), summons(me)
{
pInstance = c->GetInstanceScript();
}
@@ -397,10 +376,9 @@ public:
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_skarvald_dalronn()
{
new boss_skarvald_the_constructor();
new boss_dalronn_the_controller();
RegisterUtgardeKeepCreatureAI(boss_skarvald_the_constructor);
RegisterUtgardeKeepCreatureAI(boss_dalronn_the_controller);
}
@@ -44,6 +44,8 @@ public:
{
instance_utgarde_keep_InstanceMapScript(Map* pMap) : InstanceScript(pMap)
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadObjectData(creatureData, nullptr);
}
@@ -69,12 +71,26 @@ public:
bool IsEncounterInProgress() const override
{
if (InstanceScript::IsEncounterInProgress())
return true;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS) return true;
return false;
}
bool SetBossState(uint32 type, EncounterState state) override
{
if (!InstanceScript::SetBossState(type, state))
return false;
if (type == DATA_KELESETH && state == NOT_STARTED)
bRocksAchiev = true;
return true;
}
void OnPlayerEnter(Player* plr) override
{
if (Creature* c = GetCreature(DATA_DARK_RANGER_MARRAH))
@@ -160,11 +176,6 @@ public:
{
switch (type)
{
case DATA_KELESETH:
m_auiEncounter[0] = data;
if (data == NOT_STARTED)
bRocksAchiev = true;
break;
case DATA_ON_THE_ROCKS_ACHIEV:
bRocksAchiev = false;
break;
@@ -23,72 +23,61 @@
#include "SpellScriptLoader.h"
#include "Vehicle.h"
class npc_dragonflayer_forge_master : public CreatureScript
struct npc_dragonflayer_forge_master : public ScriptedAI
{
public:
npc_dragonflayer_forge_master() : CreatureScript("npc_dragonflayer_forge_master") { }
CreatureAI* GetAI(Creature* pCreature) const override
npc_dragonflayer_forge_master(Creature* c) : ScriptedAI(c)
{
return GetUtgardeKeepAI<npc_dragonflayer_forge_masterAI>(pCreature);
pInstance = c->GetInstanceScript();
float x = me->GetHomePosition().GetPositionX();
float y = me->GetHomePosition().GetPositionY();
if (x > 344.0f && x < 357.0f && y < -35.0f && y > -44.0f)
{
dataId = DATA_FORGE_1;
prevDataId = 0;
}
else if (x > 380.0f && x < 389.0f && y < -12.0f && y > -21.0f)
{
dataId = DATA_FORGE_2;
prevDataId = DATA_FORGE_1;
}
else
{
dataId = DATA_FORGE_3;
prevDataId = DATA_FORGE_2;
}
}
struct npc_dragonflayer_forge_masterAI : public ScriptedAI
InstanceScript* pInstance;
uint32 dataId;
uint32 prevDataId;
void Reset() override
{
npc_dragonflayer_forge_masterAI(Creature* c) : ScriptedAI(c)
if (pInstance)
pInstance->SetData(dataId, NOT_STARTED);
}
void JustDied(Unit* /*killer*/) override
{
if (pInstance)
pInstance->SetData(dataId, DONE);
me->SaveRespawnTime();
}
void JustEngagedWith(Unit* /*who*/) override
{
if (pInstance)
{
pInstance = c->GetInstanceScript();
float x = me->GetHomePosition().GetPositionX();
float y = me->GetHomePosition().GetPositionY();
if (x > 344.0f && x < 357.0f && y < -35.0f && y > -44.0f)
if (prevDataId && !pInstance->GetData(prevDataId))
{
dataId = DATA_FORGE_1;
prevDataId = 0;
}
else if (x > 380.0f && x < 389.0f && y < -12.0f && y > -21.0f)
{
dataId = DATA_FORGE_2;
prevDataId = DATA_FORGE_1;
}
else
{
dataId = DATA_FORGE_3;
prevDataId = DATA_FORGE_2;
EnterEvadeMode();
return;
}
pInstance->SetData(dataId, IN_PROGRESS);
}
InstanceScript* pInstance;
uint32 dataId;
uint32 prevDataId;
void Reset() override
{
if (pInstance)
pInstance->SetData(dataId, NOT_STARTED);
}
void JustDied(Unit* /*killer*/) override
{
if (pInstance)
pInstance->SetData(dataId, DONE);
me->SaveRespawnTime();
}
void JustEngagedWith(Unit* /*who*/) override
{
if (pInstance)
{
if (prevDataId && !pInstance->GetData(prevDataId))
{
EnterEvadeMode();
return;
}
pInstance->SetData(dataId, IN_PROGRESS);
}
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
}
};
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
}
};
enum EnslavedProtoDrake
@@ -111,97 +100,86 @@ enum EnslavedProtoDrake
const Position protodrakeCheckPos = {206.24f, -190.28f, 200.11f, 0.f};
class npc_enslaved_proto_drake : public CreatureScript
struct npc_enslaved_proto_drake : public ScriptedAI
{
public:
npc_enslaved_proto_drake() : CreatureScript("npc_enslaved_proto_drake") { }
struct npc_enslaved_proto_drakeAI : public ScriptedAI
npc_enslaved_proto_drake(Creature* creature) : ScriptedAI(creature)
{
npc_enslaved_proto_drakeAI(Creature* creature) : ScriptedAI(creature)
{
_setData = false;
}
void Reset() override
{
_events.Reset();
_events.ScheduleEvent(EVENT_REND, 2s, 3s);
_events.ScheduleEvent(EVENT_FLAME_BREATH, 5500ms, 7000ms);
_events.ScheduleEvent(EVENT_KNOCKAWAY, 3500ms, 6000ms);
}
void MovementInform(uint32 type, uint32 id) override
{
if (type == WAYPOINT_MOTION_TYPE && id == POINT_LAST)
{
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f);
if (Vehicle* v = me->GetVehicleKit())
if (Unit* p = v->GetPassenger(0))
if (Creature* rider = p->ToCreature())
rider->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f);
me->SetCanFly(false);
me->SetDisableGravity(false);
me->SetFacingTo(0.25f);
me->SetImmuneToAll(false);
}
}
void SetData(uint32 type, uint32 data) override
{
if (type == TYPE_PROTODRAKE_AT && data == DATA_PROTODRAKE_MOVE && !_setData && me->IsAlive() && me->GetDistance(protodrakeCheckPos) < 10.0f)
{
_setData = true;
me->SetCanFly(true);
me->SetDisableGravity(true);
me->GetMotionMaster()->MovePath(PATH_PROTODRAKE, false);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventid = _events.ExecuteEvent())
{
switch (eventid)
{
case EVENT_REND:
DoCast(SPELL_REND);
_events.ScheduleEvent(EVENT_REND, 15s, 20s);
break;
case EVENT_FLAME_BREATH:
DoCast(SPELL_FLAME_BREATH);
_events.ScheduleEvent(EVENT_FLAME_BREATH, 11s, 12s);
break;
case EVENT_KNOCKAWAY:
DoCast(SPELL_KNOCK_AWAY);
_events.ScheduleEvent(EVENT_KNOCKAWAY, 7000ms, 8500ms);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
bool _setData;
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetUtgardeKeepAI<npc_enslaved_proto_drakeAI>(creature);
_setData = false;
}
void Reset() override
{
_events.Reset();
_events.ScheduleEvent(EVENT_REND, 2s, 3s);
_events.ScheduleEvent(EVENT_FLAME_BREATH, 5500ms, 7000ms);
_events.ScheduleEvent(EVENT_KNOCKAWAY, 3500ms, 6000ms);
}
void MovementInform(uint32 type, uint32 id) override
{
if (type == WAYPOINT_MOTION_TYPE && id == POINT_LAST)
{
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f);
if (Vehicle* v = me->GetVehicleKit())
if (Unit* p = v->GetPassenger(0))
if (Creature* rider = p->ToCreature())
rider->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f);
me->SetCanFly(false);
me->SetDisableGravity(false);
me->SetFacingTo(0.25f);
me->SetImmuneToAll(false);
}
}
void SetData(uint32 type, uint32 data) override
{
if (type == TYPE_PROTODRAKE_AT && data == DATA_PROTODRAKE_MOVE && !_setData && me->IsAlive() && me->GetDistance(protodrakeCheckPos) < 10.0f)
{
_setData = true;
me->SetCanFly(true);
me->SetDisableGravity(true);
me->GetMotionMaster()->MovePath(PATH_PROTODRAKE, false);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventid = _events.ExecuteEvent())
{
switch (eventid)
{
case EVENT_REND:
DoCast(SPELL_REND);
_events.ScheduleEvent(EVENT_REND, 15s, 20s);
break;
case EVENT_FLAME_BREATH:
DoCast(SPELL_FLAME_BREATH);
_events.ScheduleEvent(EVENT_FLAME_BREATH, 11s, 12s);
break;
case EVENT_KNOCKAWAY:
DoCast(SPELL_KNOCK_AWAY);
_events.ScheduleEvent(EVENT_KNOCKAWAY, 7000ms, 8500ms);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
bool _setData;
EventMap _events;
};
enum TickingTimeBomb
@@ -234,8 +212,8 @@ class spell_ticking_time_bomb_aura : public AuraScript
void AddSC_utgarde_keep()
{
new npc_dragonflayer_forge_master();
new npc_enslaved_proto_drake();
RegisterUtgardeKeepCreatureAI(npc_dragonflayer_forge_master);
RegisterUtgardeKeepCreatureAI(npc_enslaved_proto_drake);
RegisterSpellScript(spell_ticking_time_bomb_aura);
}
@@ -22,6 +22,10 @@
#define UtgardeKeepScriptName "instance_utgarde_keep"
#define DataHeader "UK"
uint32 const EncounterCount = 3;
enum eData
{
DATA_KELESETH,
@@ -83,4 +87,6 @@ inline AI* GetUtgardeKeepAI(T* obj)
return GetInstanceAI<AI>(obj, UtgardeKeepScriptName);
}
#define RegisterUtgardeKeepCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetUtgardeKeepAI)
#endif
@@ -34,19 +34,12 @@ enum Yells
enum eSpells
{
SPELL_ARCANE_VACUUM = 58694,
SPELL_BLIZZARD_N = 58693,
SPELL_BLIZZARD_H = 59369,
SPELL_BLIZZARD = 58693,
SPELL_MANA_DESTRUCTION = 59374,
SPELL_TAIL_SWEEP_N = 58690,
SPELL_TAIL_SWEEP_H = 59283,
SPELL_UNCONTROLLABLE_ENERGY_N = 58688,
SPELL_UNCONTROLLABLE_ENERGY_H = 59281,
SPELL_TAIL_SWEEP = 58690,
SPELL_UNCONTROLLABLE_ENERGY = 58688
};
#define SPELL_BLIZZARD DUNGEON_MODE(SPELL_BLIZZARD_N, SPELL_BLIZZARD_H)
#define SPELL_TAIL_SWEEP DUNGEON_MODE(SPELL_TAIL_SWEEP_N, SPELL_TAIL_SWEEP_H)
#define SPELL_UNCONTROLLABLE_ENERGY DUNGEON_MODE(SPELL_UNCONTROLLABLE_ENERGY_N, SPELL_UNCONTROLLABLE_ENERGY_H)
enum eEvents
{
EVENT_SPELL_ARCANE_VACUUM = 1,
@@ -23,10 +23,8 @@ enum eSpells
{
SPELL_BLOODLUST = 54516,
SPELL_BREAK_BONDS = 59463,
SPELL_CHAIN_HEAL_N = 54481,
SPELL_CHAIN_HEAL_H = 59473,
SPELL_EARTH_SHIELD_N = 54479,
SPELL_EARTH_SHIELD_H = 59471,
SPELL_CHAIN_HEAL = 54481,
SPELL_EARTH_SHIELD = 54479,
//SPELL_EARTH_SHIELD_TRIGGERED_N = 54480,
//SPELL_EARTH_SHIELD_TRIGGERED_H = 59472,
SPELL_EARTH_SHOCK = 54511,
@@ -34,9 +32,6 @@ enum eSpells
SPELL_STORMSTRIKE = 51876,
};
#define SPELL_CHAIN_HEAL DUNGEON_MODE(SPELL_CHAIN_HEAL_N, SPELL_CHAIN_HEAL_H)
#define SPELL_EARTH_SHIELD DUNGEON_MODE(SPELL_EARTH_SHIELD_N, SPELL_EARTH_SHIELD_H)
enum Yells
{
SAY_AGGRO = 0,
@@ -53,23 +53,16 @@ enum eCreatures
enum eSpells
{
SPELL_DRAINED = 59820,
SPELL_FRENZY_N = 54312,
SPELL_FRENZY_H = 59522,
SPELL_FRENZY = 54312,
SPELL_PROTECTIVE_BUBBLE = 54306,
SPELL_WATER_BLAST_N = 54237,
SPELL_WATER_BLAST_H = 59520,
SPELL_WATER_BOLT_VOLLEY_N = 54241,
SPELL_WATER_BOLT_VOLLEY_H = 59521,
SPELL_WATER_BLAST = 54237,
SPELL_WATER_BOLT_VOLLEY = 54241,
SPELL_SPLASH = 59516, // casted by globule upon death
SPELL_WATER_GLOBULE = 54268, // casted when hit by visual
SPELL_CREATE_GLOBULE_VISUAL = 54260, // tar 25
};
#define SPELL_WATER_BLAST DUNGEON_MODE(SPELL_WATER_BLAST_N, SPELL_WATER_BLAST_H)
#define SPELL_WATER_BOLT_VOLLEY DUNGEON_MODE(SPELL_WATER_BOLT_VOLLEY_N, SPELL_WATER_BOLT_VOLLEY_H)
#define SPELL_FRENZY DUNGEON_MODE(SPELL_FRENZY_N, SPELL_FRENZY_H)
class boss_ichoron : public CreatureScript
{
public:
@@ -22,18 +22,11 @@
enum eSpells
{
SPELL_CAUTERIZING_FLAMES = 59466,
SPELL_FIREBOLT_N = 54235,
SPELL_FIREBOLT_H = 59468,
SPELL_FLAME_BREATH_N = 54282,
SPELL_FLAME_BREATH_H = 59469,
SPELL_LAVA_BURN_N = 54249,
SPELL_LAVA_BURN_H = 59594,
SPELL_FIREBOLT = 54235,
SPELL_FLAME_BREATH = 54282,
SPELL_LAVA_BURN = 54249
};
#define SPELL_FIREBOLT DUNGEON_MODE(SPELL_FIREBOLT_N, SPELL_FIREBOLT_H)
#define SPELL_FLAME_BREATH DUNGEON_MODE(SPELL_FLAME_BREATH_N, SPELL_FLAME_BREATH_H)
#define SPELL_LAVA_BURN DUNGEON_MODE(SPELL_LAVA_BURN_N, SPELL_LAVA_BURN_H)
enum eEvents
{
EVENT_SPELL_FIREBOLT = 1,
@@ -24,12 +24,10 @@
enum eSpells
{
SPELL_RAY_OF_SUFFERING_N = 54442,
SPELL_RAY_OF_SUFFERING_H = 59524,
SPELL_RAY_OF_SUFFERING = 54442,
//SPELL_RAY_OF_SUFFERING_TRIGGERED = 54417,
SPELL_RAY_OF_PAIN_N = 54438,
SPELL_RAY_OF_PAIN_H = 59523,
SPELL_RAY_OF_PAIN = 54438,
//SPELL_RAY_OF_PAIN_TRIGGERED_N = 54416,
//SPELL_RAY_OF_PAIN_TRIGGERED_H = 59525,
@@ -37,9 +35,6 @@ enum eSpells
SPELL_OPTIC_LINK = 54396,
};
#define SPELL_RAY_OF_SUFFERING DUNGEON_MODE(SPELL_RAY_OF_SUFFERING_N, SPELL_RAY_OF_SUFFERING_H)
#define SPELL_RAY_OF_PAIN DUNGEON_MODE(SPELL_RAY_OF_PAIN_N, SPELL_RAY_OF_PAIN_H)
enum eEvents
{
EVENT_SPELL_CORROSIVE_SALIVA = 1,
@@ -32,24 +32,17 @@ enum Yells
enum eSpells
{
SPELL_ARCANE_BARRAGE_VOLLEY_N = 54202,
SPELL_ARCANE_BARRAGE_VOLLEY_H = 59483,
SPELL_ARCANE_BUFFET_N = 54226,
SPELL_ARCANE_BUFFET_H = 59485,
SPELL_ARCANE_BARRAGE_VOLLEY = 54202,
SPELL_ARCANE_BUFFET = 54226,
SPELL_SUMMON_ETHEREAL_SPHERE_1 = 54102,
SPELL_SUMMON_ETHEREAL_SPHERE_2 = 54137,
SPELL_SUMMON_ETHEREAL_SPHERE_3 = 54138,
SPELL_ARCANE_POWER_N = 54160,
SPELL_ARCANE_POWER_H = 59474,
SPELL_ARCANE_POWER = 54160
//SPELL_SUMMON_PLAYERS = 54164, // not used
//SPELL_POWER_BALL_VISUAL = 54141,
};
#define SPELL_ARCANE_BARRAGE_VOLLEY DUNGEON_MODE(SPELL_ARCANE_BARRAGE_VOLLEY_N, SPELL_ARCANE_BARRAGE_VOLLEY_H)
#define SPELL_ARCANE_BUFFET DUNGEON_MODE(SPELL_ARCANE_BUFFET_N, SPELL_ARCANE_BUFFET_H)
#define SPELL_ARCANE_POWER DUNGEON_MODE(SPELL_ARCANE_POWER_N, SPELL_ARCANE_POWER_H)
enum eEvents
{
EVENT_SPELL_ARCANE_BARRAGE_VOLLEY = 1,
@@ -32,10 +32,8 @@ enum Yells
enum eSpells
{
SPELL_SHROUD_OF_DARKNESS_N = 54524,
SPELL_SHROUD_OF_DARKNESS_H = 59745,
SPELL_VOID_SHIFT_N = 54361,
SPELL_VOID_SHIFT_H = 59743,
SPELL_SHROUD_OF_DARKNESS = 54524,
SPELL_VOID_SHIFT = 54361,
SPELL_SUMMON_VOID_SENTRY = 54369,
SPELL_SUMMON_VOID_SENTRY_BALL = 58650,
@@ -44,8 +42,6 @@ enum eSpells
};
#define NPC_VOID_SENTRY_BALL 29365
#define SPELL_SHROUD_OF_DARKNESS DUNGEON_MODE(SPELL_SHROUD_OF_DARKNESS_N, SPELL_SHROUD_OF_DARKNESS_H)
#define SPELL_VOID_SHIFT DUNGEON_MODE(SPELL_VOID_SHIFT_N, SPELL_VOID_SHIFT_H)
enum eEvents
{
@@ -350,7 +350,7 @@ public:
void EnterEvadeMode(EvadeReason why) override
{
if (switching || me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
if (switching || me->HasControlVehicleAura())
return;
ScriptedAI::EnterEvadeMode(why);
}