mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-25 06:36:24 +00:00
Merge branch 'master' into Playerbot
# Conflicts: # src/server/game/Guilds/Guild.cpp
This commit is contained in:
@@ -168,20 +168,19 @@ public:
|
||||
int32 multiplier = 1;
|
||||
switch (aurEff->GetTickNumber())
|
||||
{
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
multiplier = 2;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
multiplier = 3;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
multiplier = 4;
|
||||
break;
|
||||
case 7:
|
||||
multiplier = 6;
|
||||
break;
|
||||
case 8:
|
||||
multiplier = 5;
|
||||
multiplier = 10;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,12 @@ public:
|
||||
|
||||
// Not in progress
|
||||
instance->SetData(DATA_ARAN, NOT_STARTED);
|
||||
instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), true);
|
||||
|
||||
if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR)))
|
||||
{
|
||||
libraryDoor->SetGoState(GO_STATE_ACTIVE);
|
||||
libraryDoor->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
@@ -147,7 +152,12 @@ public:
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
instance->SetData(DATA_ARAN, DONE);
|
||||
instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), true);
|
||||
|
||||
if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR)))
|
||||
{
|
||||
libraryDoor->SetGoState(GO_STATE_ACTIVE);
|
||||
libraryDoor->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
@@ -155,7 +165,13 @@ public:
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
instance->SetData(DATA_ARAN, IN_PROGRESS);
|
||||
instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), false);
|
||||
|
||||
if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR)))
|
||||
{
|
||||
libraryDoor->SetGoState(GO_STATE_READY);
|
||||
libraryDoor->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
@@ -203,7 +219,11 @@ public:
|
||||
{
|
||||
if (CloseDoorTimer <= diff)
|
||||
{
|
||||
instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), false);
|
||||
if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR)))
|
||||
{
|
||||
libraryDoor->SetGoState(GO_STATE_READY);
|
||||
libraryDoor->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
CloseDoorTimer = 0;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -163,7 +163,6 @@ Position const RimefangFlyPos = {4413.309f, 2456.421f, 233.3795f, 2.890186f
|
||||
Position const RimefangLandPos = {4413.309f, 2456.421f, 203.3848f, 2.890186f};
|
||||
Position const SpinestalkerFlyPos = {4418.895f, 2514.233f, 230.4864f, 3.396045f};
|
||||
Position const SpinestalkerLandPos = {4418.895f, 2514.233f, 203.3848f, 3.396045f};
|
||||
Position const SindragosaSpawnPos = {4818.700f, 2483.710f, 287.0650f, 3.089233f};
|
||||
Position const SindragosaFlyInPos = {4420.190f, 2484.360f, 232.5150f, 3.141593f};
|
||||
Position const SindragosaLandPos = {4419.190f, 2484.570f, 203.3848f, 3.141593f};
|
||||
Position const SindragosaAirPos = {4475.990f, 2484.430f, 247.9340f, 3.141593f};
|
||||
@@ -273,7 +272,7 @@ public:
|
||||
|
||||
struct boss_sindragosaAI : public BossAI
|
||||
{
|
||||
boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA), _summoned(false)
|
||||
boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA)
|
||||
{
|
||||
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_HASTE_SPELLS, true);
|
||||
}
|
||||
@@ -286,16 +285,9 @@ public:
|
||||
_bombCount = 0;
|
||||
_mysticBuffetStack = 0;
|
||||
_Reset();
|
||||
me->DisableRotate(false);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->SetSpeed(MOVE_RUN, me->GetCreatureTemplate()->speed_run);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->CastSpell(me, SPELL_TANK_MARKER, true);
|
||||
|
||||
if (!_summoned)
|
||||
{
|
||||
me->SetDisableGravity(true);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
@@ -359,20 +351,9 @@ public:
|
||||
return me->IsVisible() && target->GetEntry() != NPC_CROK_SCOURGEBANE;
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(DATA_SINDRAGOSA, FAIL);
|
||||
if (_summoned)
|
||||
{
|
||||
me->SetDisableGravity(false);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
me->DisableRotate(false);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
instance->SetBossState(DATA_SINDRAGOSA, FAIL);
|
||||
BossAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
@@ -386,10 +367,6 @@ public:
|
||||
{
|
||||
if (action == ACTION_START_FROSTWYRM)
|
||||
{
|
||||
if (_summoned)
|
||||
return;
|
||||
|
||||
_summoned = true;
|
||||
if (TempSummon* summon = me->ToTempSummon())
|
||||
summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN);
|
||||
|
||||
@@ -403,7 +380,11 @@ public:
|
||||
float moveTime = me->GetExactDist(&SindragosaFlyInPos) / (me->GetSpeed(MOVE_RUN) * 0.001f);
|
||||
me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, SindragosaLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250));
|
||||
me->GetMotionMaster()->MovePoint(POINT_FROSTWYRM_FLY_IN, SindragosaFlyInPos);
|
||||
me->CastSpell(me, SPELL_SINDRAGOSA_S_FURY, true);
|
||||
|
||||
if (!instance->GetData(DATA_SINDRAGOSA_INTRO))
|
||||
{
|
||||
DoCastAOE(SPELL_SINDRAGOSA_S_FURY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,7 +666,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool _summoned;
|
||||
uint8 _bombCount;
|
||||
uint8 _mysticBuffetStack;
|
||||
bool _didFirstFlyPhase;
|
||||
@@ -1724,13 +1704,10 @@ public:
|
||||
if (Creature* rimefang = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_RIMEFANG)))
|
||||
rimefang->AI()->DoAction(ACTION_START_FROSTWYRM);
|
||||
|
||||
if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) && !instance->GetGuidData(DATA_SINDRAGOSA) && instance->GetBossState(DATA_SINDRAGOSA) != DONE)
|
||||
if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS))
|
||||
{
|
||||
if (instance->GetData(DATA_HAS_LIMITED_ATTEMPTS) && !instance->GetData(DATA_HEROIC_ATTEMPTS))
|
||||
return true;
|
||||
|
||||
player->GetMap()->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
|
||||
if (Creature* sindragosa = player->GetMap()->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
|
||||
if (Creature* sindragosa = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_SINDRAGOSA)))
|
||||
sindragosa->AI()->DoAction(ACTION_START_FROSTWYRM);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ enum DataTypes
|
||||
DATA_PUTRICIDE_TRAP_STATE = 254,
|
||||
DATA_HAS_LIMITED_ATTEMPTS = 255,
|
||||
DATA_LK_HC_AVAILABLE = 256,
|
||||
DATA_SINDRAGOSA_INTRO = 257,
|
||||
|
||||
DATA_BPC_TRASH_DIED = 300,
|
||||
};
|
||||
|
||||
@@ -49,7 +49,8 @@ enum TimedEvents
|
||||
EVENT_UPDATE_EXECUTION_TIME = 1,
|
||||
EVENT_QUAKE_SHATTER = 2,
|
||||
EVENT_REBUILD_PLATFORM = 3,
|
||||
EVENT_RESPAWN_GUNSHIP = 4
|
||||
EVENT_RESPAWN_GUNSHIP = 4,
|
||||
EVENT_RESPAWN_SINDRAGOSA = 5
|
||||
};
|
||||
|
||||
enum Spells
|
||||
@@ -140,6 +141,7 @@ Position const JainaSpawnPos = { -48.65278f, 2211.026f, 27.98586f, 3.124139f
|
||||
Position const MuradinSpawnPos = { -47.34549f, 2208.087f, 27.98586f, 3.106686f };
|
||||
Position const UtherSpawnPos = { -26.58507f, 2211.524f, 30.19898f, 3.124139f };
|
||||
Position const SylvanasSpawnPos = { -41.45833f, 2222.891f, 27.98586f, 3.647738f };
|
||||
Position const SindragosaSpawnPos = { 4818.6997f, 2483.7102f, 287.06497f, 3.286661f };
|
||||
|
||||
// Set position traps Spirit Alarm
|
||||
std::vector<Position> GoSpiritAlarm_1 = { { -160.96f, 2210.46f, 35.24f, 0.0f }, { -176.27f, 2201.93f, 35.24f, 0.0f}, { -207.83f, 2207.38f, 35.24f, 0.0f } };
|
||||
@@ -212,6 +214,7 @@ public:
|
||||
BloodQuickeningState = NOT_STARTED;
|
||||
BloodQuickeningMinutes = 0;
|
||||
BloodPrinceTrashCount = 0;
|
||||
IsSindragosaIntroDone = false;
|
||||
}
|
||||
|
||||
void FillInitialWorldStates(WorldPacket& data) override
|
||||
@@ -254,6 +257,11 @@ public:
|
||||
if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE)
|
||||
SpawnGunship();
|
||||
|
||||
if (GetBossState(DATA_SINDRAGOSA) != DONE && IsSindragosaIntroDone && SindragosaGUID.IsEmpty() && Events.GetTimeUntilEvent(EVENT_RESPAWN_SINDRAGOSA) == Milliseconds::max())
|
||||
{
|
||||
Events.ScheduleEvent(EVENT_RESPAWN_SINDRAGOSA, 30s);
|
||||
}
|
||||
|
||||
if (IsBuffAvailable)
|
||||
{
|
||||
SpellAreaForAreaMapBounds saBounds = sSpellMgr->GetSpellAreaForAreaMapBounds(4812);
|
||||
@@ -937,6 +945,8 @@ public:
|
||||
return BloodQuickeningState;
|
||||
case DATA_HEROIC_ATTEMPTS:
|
||||
return HeroicAttempts;
|
||||
case DATA_SINDRAGOSA_INTRO:
|
||||
return (IsSindragosaIntroDone ? 1 : 0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1161,7 +1171,21 @@ public:
|
||||
if (state == DONE)
|
||||
CheckLichKingAvailability();
|
||||
else if (state == FAIL)
|
||||
{
|
||||
IsSindragosaIntroDone = true;
|
||||
HandleDropAttempt();
|
||||
if (instance->IsHeroic())
|
||||
{
|
||||
if (HeroicAttempts)
|
||||
{
|
||||
Events.ScheduleEvent(EVENT_RESPAWN_SINDRAGOSA, 30s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Events.ScheduleEvent(EVENT_RESPAWN_SINDRAGOSA, 30s);
|
||||
}
|
||||
}
|
||||
if (state == DONE && !instance->IsHeroic() && LichKingHeroicAvailable)
|
||||
{
|
||||
LichKingHeroicAvailable = false;
|
||||
@@ -1626,6 +1650,7 @@ public:
|
||||
data >> BloodPrinceTrashCount;
|
||||
data >> IsBuffAvailable;
|
||||
SetData(DATA_BUFF_AVAILABLE, IsBuffAvailable);
|
||||
data >> IsSindragosaIntroDone;
|
||||
}
|
||||
|
||||
void WriteSaveDataMore(std::ostringstream& data) override
|
||||
@@ -1638,7 +1663,8 @@ public:
|
||||
<< PutricideEventProgress << ' '
|
||||
<< uint32(LichKingHeroicAvailable ? 1 : 0) << ' '
|
||||
<< BloodPrinceTrashCount << ' '
|
||||
<< uint32(IsBuffAvailable ? 1 : 0);
|
||||
<< uint32(IsBuffAvailable ? 1 : 0) << ' '
|
||||
<< uint32(IsSindragosaIntroDone ? 1 : 0);
|
||||
}
|
||||
|
||||
void Update(uint32 diff) override
|
||||
@@ -1679,7 +1705,7 @@ public:
|
||||
else
|
||||
DarkwhisperElevatorTimer -= diff;
|
||||
|
||||
if (BloodQuickeningState != IN_PROGRESS && GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != FAIL)
|
||||
if (Events.Empty())
|
||||
return;
|
||||
|
||||
Events.Update(diff);
|
||||
@@ -1732,6 +1758,21 @@ public:
|
||||
case EVENT_RESPAWN_GUNSHIP:
|
||||
SpawnGunship();
|
||||
break;
|
||||
case EVENT_RESPAWN_SINDRAGOSA:
|
||||
if (Creature* sindragosa = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
|
||||
{
|
||||
sindragosa->setActive(true);
|
||||
sindragosa->SetDisableGravity(true);
|
||||
sindragosa->GetMotionMaster()->MovePath(NPC_SINDRAGOSA * 10, true);
|
||||
|
||||
if (TempSummon* summon = sindragosa->ToTempSummon())
|
||||
{
|
||||
summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN);
|
||||
}
|
||||
}
|
||||
// Could happen more than once if more than one player enters before she respawns.
|
||||
Events.CancelEvent(EVENT_RESPAWN_SINDRAGOSA);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1944,6 +1985,7 @@ public:
|
||||
bool IsOozeDanceEligible;
|
||||
bool IsNauseaEligible;
|
||||
bool IsOrbWhispererEligible;
|
||||
bool IsSindragosaIntroDone;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
enum vYells
|
||||
{
|
||||
CYANIGOSA_SAY_SPAWN = 3,
|
||||
SAY_SINCLARI_1 = 0
|
||||
SAY_SINCLARI_LEAVING = 0,
|
||||
SAY_SINCLARI_DOOR_LOCK = 1,
|
||||
SAY_SINCLARI_COMPLETE = 2,
|
||||
};
|
||||
|
||||
class instance_violet_hold : public InstanceMapScript
|
||||
@@ -214,7 +216,7 @@ public:
|
||||
{
|
||||
EncounterStatus = IN_PROGRESS;
|
||||
if (Creature* c = instance->GetCreature(NPC_SinclariGUID))
|
||||
c->AI()->Talk(SAY_SINCLARI_1);
|
||||
c->AI()->Talk(SAY_SINCLARI_LEAVING);
|
||||
events.RescheduleEvent(EVENT_GUARDS_FALL_BACK, 4s);
|
||||
}
|
||||
break;
|
||||
@@ -251,7 +253,12 @@ public:
|
||||
EncounterStatus = DONE;
|
||||
HandleGameObject(GO_MainGateGUID, true);
|
||||
DoUpdateWorldState(WORLD_STATE_VH_SHOW, 0);
|
||||
if (Creature* c = instance->GetCreature(NPC_SinclariGUID)) { c->DespawnOrUnsummon(); c->SetRespawnTime(3); }
|
||||
if (Creature* c = instance->GetCreature(NPC_SinclariGUID))
|
||||
{
|
||||
c->AI()->Talk(SAY_SINCLARI_COMPLETE);
|
||||
c->DespawnOrUnsummon();
|
||||
c->SetRespawnTime(3);
|
||||
}
|
||||
}
|
||||
SaveToDB();
|
||||
if (WaveCount < 18)
|
||||
@@ -440,8 +447,14 @@ public:
|
||||
break;
|
||||
case EVENT_START_ENCOUNTER:
|
||||
{
|
||||
if (Creature* c = instance->GetCreature(NPC_SinclariGUID))
|
||||
{
|
||||
c->AI()->Talk(SAY_SINCLARI_DOOR_LOCK);
|
||||
}
|
||||
if (Creature* c = instance->GetCreature(NPC_DoorSealGUID))
|
||||
{
|
||||
c->RemoveAllAuras(); // just to be sure...
|
||||
}
|
||||
GateHealth = 100;
|
||||
HandleGameObject(GO_MainGateGUID, false);
|
||||
DoUpdateWorldState(WORLD_STATE_VH_SHOW, 1);
|
||||
|
||||
@@ -24,6 +24,21 @@
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
/// @todo: Missing Sinclari Trigger announcements (32204) Look at its creature_text for more info.
|
||||
/// @todo: Activation Crystals (go_vh_activation_crystal) (193611) are spammable, should be a 1 time use per crystal.
|
||||
|
||||
enum Texts
|
||||
{
|
||||
GOSSIP_MENU_START_EVENT = 9998,
|
||||
GOSSIP_MENU_ITEM = 9997,
|
||||
GOSSIP_MENU_LATE_JOIN = 10275,
|
||||
|
||||
NPC_TEXT_SINCLARI_IN = 13853,
|
||||
NPC_TEXT_SINCLARI_ITEM = 13854,
|
||||
NPC_TEXT_SINCLARI_DONE = 13910,
|
||||
NPC_TEXT_SINCLARI_LATE_JOIN = 14271,
|
||||
};
|
||||
|
||||
/***********
|
||||
** DEFENSE SYSTEM CRYSTAL
|
||||
***********/
|
||||
@@ -45,10 +60,6 @@ public:
|
||||
** SINCLARI
|
||||
***********/
|
||||
|
||||
#define GOSSIP_START_EVENT "Get your people to safety, we'll keep the Blue Dragonflight's forces at bay."
|
||||
#define GOSSIP_ITEM_1 "Activate the crystals when we get in trouble, right."
|
||||
#define GOSSIP_I_WANT_IN "Sorry, I'm late! Can I get in to help my friends?"
|
||||
|
||||
class npc_vh_sinclari : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -60,16 +71,16 @@ public:
|
||||
switch (pInstance->GetData(DATA_ENCOUNTER_STATUS))
|
||||
{
|
||||
case NOT_STARTED:
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
SendGossipMenuFor(player, 13853, creature->GetGUID());
|
||||
AddGossipItemFor(player, GOSSIP_MENU_ITEM, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
AddGossipItemFor(player, GOSSIP_MENU_START_EVENT, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
SendGossipMenuFor(player, NPC_TEXT_SINCLARI_IN, creature->GetGUID());
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_I_WANT_IN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
SendGossipMenuFor(player, 13853, creature->GetGUID());
|
||||
AddGossipItemFor(player, GOSSIP_MENU_LATE_JOIN, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
SendGossipMenuFor(player, NPC_TEXT_SINCLARI_LATE_JOIN, creature->GetGUID());
|
||||
break;
|
||||
default: // DONE or invalid
|
||||
SendGossipMenuFor(player, 13910, creature->GetGUID());
|
||||
SendGossipMenuFor(player, NPC_TEXT_SINCLARI_DONE, creature->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -86,7 +97,7 @@ public:
|
||||
pInstance->SetData(DATA_START_INSTANCE, 1);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
SendGossipMenuFor(player, 13854, creature->GetGUID());
|
||||
SendGossipMenuFor(player, NPC_TEXT_SINCLARI_ITEM, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+3:
|
||||
player->NearTeleportTo(playerTeleportPosition.GetPositionX(), playerTeleportPosition.GetPositionY(), playerTeleportPosition.GetPositionZ(), playerTeleportPosition.GetOrientation(), true);
|
||||
|
||||
@@ -43,7 +43,7 @@ enum Spells
|
||||
|
||||
struct boss_talon_king_ikiss : public BossAI
|
||||
{
|
||||
boss_talon_king_ikiss(Creature* creature) : BossAI(creature, DATA_IKISS), _spoken(false), _manaShield(false)
|
||||
boss_talon_king_ikiss(Creature* creature) : BossAI(creature, DATA_IKISS), _spoken(false)
|
||||
{
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
@@ -55,8 +55,44 @@ struct boss_talon_king_ikiss : public BossAI
|
||||
{
|
||||
_Reset();
|
||||
_spoken = false;
|
||||
_manaShield = false;
|
||||
_comboHealthStages.fill(false);
|
||||
|
||||
ScheduleHealthCheckEvent(80, [&] {
|
||||
TeleportAndCastExplosion();
|
||||
});
|
||||
|
||||
ScheduleHealthCheckEvent(50, [&] {
|
||||
TeleportAndCastExplosion();
|
||||
});
|
||||
|
||||
ScheduleHealthCheckEvent(25, [&] {
|
||||
TeleportAndCastExplosion();
|
||||
});
|
||||
|
||||
ScheduleHealthCheckEvent(20, [&] {
|
||||
DoCast(me, SPELL_MANA_SHIELD);
|
||||
});
|
||||
}
|
||||
|
||||
/// @todo: remove this once pets stop going through doors.
|
||||
bool CanAIAttack(Unit const* /*victim*/) const override
|
||||
{
|
||||
return _spoken;
|
||||
}
|
||||
|
||||
void TeleportAndCastExplosion()
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
});
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
@@ -106,69 +142,6 @@ struct boss_talon_king_ikiss : public BossAI
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
{
|
||||
if (!_comboHealthStages[0] && me->HealthBelowPctDamaged(80, damage))
|
||||
{
|
||||
_comboHealthStages[0] = true;
|
||||
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
});
|
||||
}
|
||||
|
||||
if (!_comboHealthStages[1] && me->HealthBelowPctDamaged(50, damage))
|
||||
{
|
||||
_comboHealthStages[1] = true;
|
||||
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
});
|
||||
}
|
||||
|
||||
if (!_comboHealthStages[2] && me->HealthBelowPctDamaged(25, damage))
|
||||
{
|
||||
_comboHealthStages[2] = true;
|
||||
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
});
|
||||
}
|
||||
|
||||
if (!_manaShield && me->HealthBelowPctDamaged(20, damage))
|
||||
{
|
||||
DoCast(me, SPELL_MANA_SHIELD);
|
||||
_manaShield = true;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
if (urand(0, 1))
|
||||
@@ -177,8 +150,6 @@ struct boss_talon_king_ikiss : public BossAI
|
||||
|
||||
private:
|
||||
bool _spoken;
|
||||
bool _manaShield;
|
||||
std::array<bool, 3> _comboHealthStages;
|
||||
};
|
||||
|
||||
// 38194 - Blink
|
||||
|
||||
@@ -37,6 +37,8 @@ enum Spells
|
||||
SPELL_ARCANE_TORRENT = 36022,
|
||||
SPELL_MANA_TAP = 36021,
|
||||
SPELL_DOMINATION = 35280,
|
||||
SPELL_FRENZY = 36992,
|
||||
SPELL_SUICIDE = 35301,
|
||||
SPELL_ETHEREAL_TELEPORT = 34427,
|
||||
SPELL_GREATER_INVISIBILITY = 34426,
|
||||
SPELL_SUMMON_NETHER_WRAITH_1 = 35285,
|
||||
@@ -48,6 +50,8 @@ enum Spells
|
||||
enum Misc
|
||||
{
|
||||
ACTION_BRIDGE_MOB_DEATH = 1, // Used by SAI
|
||||
EQUIPMENT_NORMAL = 1,
|
||||
EQUIPMENT_FRENZY = 2,
|
||||
};
|
||||
|
||||
struct boss_pathaleon_the_calculator : public BossAI
|
||||
@@ -60,9 +64,13 @@ struct boss_pathaleon_the_calculator : public BossAI
|
||||
});
|
||||
}
|
||||
|
||||
bool _isEnraged;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
_isEnraged = false;
|
||||
me->LoadEquipment(EQUIPMENT_NORMAL);
|
||||
|
||||
if (instance->GetPersistentData(DATA_BRIDGE_MOB_DEATH_COUNT) < 4)
|
||||
{
|
||||
@@ -81,18 +89,23 @@ struct boss_pathaleon_the_calculator : public BossAI
|
||||
|
||||
ScheduleHealthCheckEvent(20, [&]()
|
||||
{
|
||||
summons.DespawnAll();
|
||||
DoCastSelf(SPELL_DISGRUNTLED_ANGER, true);
|
||||
DoCastSelf(SPELL_SUICIDE, true);
|
||||
DoCastSelf(SPELL_FRENZY, true);
|
||||
Talk(SAY_ENRAGE);
|
||||
_isEnraged = true;
|
||||
me->LoadEquipment(EQUIPMENT_FRENZY);
|
||||
});
|
||||
|
||||
scheduler.Schedule(30s, [this](TaskContext context)
|
||||
scheduler.Schedule(20s, 25s, [this](TaskContext context)
|
||||
{
|
||||
for (uint8 i = 0; i < DUNGEON_MODE(3, 4); ++i)
|
||||
me->CastSpell(me, SPELL_SUMMON_NETHER_WRAITH_1 + i, true);
|
||||
if (!_isEnraged)
|
||||
{
|
||||
for (uint8 i = 0; i < DUNGEON_MODE(3, 4); ++i)
|
||||
me->CastSpell(me, SPELL_SUMMON_NETHER_WRAITH_1 + i, true);
|
||||
|
||||
Talk(SAY_SUMMON);
|
||||
context.Repeat(30s, 40s);
|
||||
Talk(SAY_SUMMON);
|
||||
}
|
||||
context.Repeat(45s, 50s);
|
||||
}).Schedule(12s, [this](TaskContext context)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 40.0f, false)))
|
||||
@@ -106,13 +119,17 @@ struct boss_pathaleon_the_calculator : public BossAI
|
||||
me->ModifyPower(POWER_MANA, 5000);
|
||||
DoCastSelf(SPELL_ARCANE_TORRENT);
|
||||
context.Repeat(15s);
|
||||
}).Schedule(25s, [this](TaskContext context)
|
||||
}).Schedule(10s, 15s, [this](TaskContext context)
|
||||
{
|
||||
if (DoCastRandomTarget(SPELL_DOMINATION, 1, 50.0f) == SPELL_CAST_OK)
|
||||
{
|
||||
Talk(SAY_DOMINATION);
|
||||
}
|
||||
context.Repeat(30s);
|
||||
context.Repeat(27s, 40s);
|
||||
}).Schedule(25s, [this](TaskContext context)
|
||||
{
|
||||
DoCast(SPELL_DISGRUNTLED_ANGER);
|
||||
context.Repeat(40s, 90s);
|
||||
});
|
||||
|
||||
if (IsHeroic())
|
||||
|
||||
@@ -349,7 +349,10 @@ public:
|
||||
instance->SetBossState(DATA_WARDEN_MELLICHAR, DONE);
|
||||
if (Creature* creature = summons.GetCreatureWithEntry(NPC_MILLHOUSE))
|
||||
{
|
||||
instance->DoCastSpellOnPlayers(SPELL_QID10886);
|
||||
if (IsHeroic())
|
||||
{
|
||||
instance->DoCastSpellOnPlayers(SPELL_QID10886);
|
||||
}
|
||||
creature->AI()->Talk(SAY_COMPLETE);
|
||||
creature->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP);
|
||||
}
|
||||
|
||||
@@ -91,15 +91,15 @@ struct boss_dalliah_the_doomsayer : public BossAI
|
||||
}
|
||||
}
|
||||
|
||||
scheduler.Schedule(1s, 4s, [this](TaskContext context)
|
||||
scheduler.Schedule(8s, 12s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_GIFT_OF_THE_DOOMSAYER);
|
||||
context.Repeat(16s, 21s);
|
||||
}).Schedule(7s, 9s, [this](TaskContext context)
|
||||
context.Repeat(17s, 35s);
|
||||
}).Schedule(20s, 30s, [this](TaskContext context)
|
||||
{
|
||||
Talk(SAY_WHIRLWIND);
|
||||
DoCastAOE(SPELL_WHIRLWIND);
|
||||
context.Repeat(19s, 21s);
|
||||
context.Repeat();
|
||||
|
||||
scheduler.Schedule(7s, [this](TaskContext)
|
||||
{
|
||||
@@ -110,10 +110,10 @@ struct boss_dalliah_the_doomsayer : public BossAI
|
||||
|
||||
if (IsHeroic())
|
||||
{
|
||||
scheduler.Schedule(11s, 16s, [this](TaskContext context)
|
||||
scheduler.Schedule(11s, 30s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_SHADOW_WAVE);
|
||||
context.Repeat(11s, 16s);
|
||||
context.Repeat();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,9 +128,10 @@ struct boss_wrath_scryer_soccothrates : public BossAI
|
||||
|
||||
scheduler.Schedule(30s, 35s, [this](TaskContext context)
|
||||
{
|
||||
scheduler.DelayAll(5s);
|
||||
me->CastSpell(me, SPELL_KNOCK_AWAY, false);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
|
||||
Talk(SAY_KNOCK_AWAY);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
|
||||
|
||||
scheduler.Schedule(4600ms, [this](TaskContext)
|
||||
{
|
||||
@@ -149,7 +150,7 @@ struct boss_wrath_scryer_soccothrates : public BossAI
|
||||
});
|
||||
|
||||
context.Repeat(20s, 35s);
|
||||
}).Schedule(12s, 14s, [this](TaskContext context)
|
||||
}).Schedule(8500ms, 22s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_FELFIRE_SHOCK);
|
||||
context.Repeat();
|
||||
|
||||
@@ -56,22 +56,22 @@ struct boss_zereketh_the_unbound : public BossAI
|
||||
_JustEngagedWith();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
scheduler.Schedule(6s, [this](TaskContext context)
|
||||
scheduler.Schedule(11s, 29s, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_VOID_ZONE, 0, 60.0f);
|
||||
context.Repeat(15s);
|
||||
}).Schedule(10s, [this](TaskContext context)
|
||||
context.Repeat();
|
||||
}).Schedule(12s, 22s, [this](TaskContext context)
|
||||
{
|
||||
DoCastAOE(SPELL_SHADOW_NOVA);
|
||||
if (roll_chance_i(50))
|
||||
{
|
||||
Talk(SAY_SHADOW_NOVA);
|
||||
}
|
||||
context.Repeat(12s);
|
||||
}).Schedule(16s, [this](TaskContext context)
|
||||
context.Repeat();
|
||||
}).Schedule(6s, 12s, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_SEED_OF_CORRUPTION, 0, 30.0f);
|
||||
context.Repeat(16s);
|
||||
context.Repeat(13s, 27s);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user