mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-08 15:58:04 +00:00
fix(Scripts/ObsidianSanctum): enable Sartharion drakes patrols (#24702)
Co-authored-by: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
DELETE FROM `waypoint_data` WHERE `id` IN (304490, 304520, 304510);
|
||||||
|
|
||||||
|
-- CREATURE_FLAG_EXTRA_HARD_RESET
|
||||||
|
UPDATE `creature_template` SET `flags_extra` = `flags_extra` | 0x80000000 WHERE (`entry` = 28860);
|
||||||
@@ -36,6 +36,8 @@ enum Says
|
|||||||
SAY_SARTHARION_SLAY = 8,
|
SAY_SARTHARION_SLAY = 8,
|
||||||
SAY_SARTHARION_SPECIAL_4 = 10, // 9 is whisper
|
SAY_SARTHARION_SPECIAL_4 = 10, // 9 is whisper
|
||||||
|
|
||||||
|
SAY_DRAKE_RESPOND = 4,
|
||||||
|
|
||||||
// TENEBRON
|
// TENEBRON
|
||||||
SAY_TENEBRON_AGGRO = 0,
|
SAY_TENEBRON_AGGRO = 0,
|
||||||
SAY_TENEBRON_SLAY = 1,
|
SAY_TENEBRON_SLAY = 1,
|
||||||
@@ -87,6 +89,7 @@ enum Spells
|
|||||||
SPELL_LAVA_STRIKE_SUMMON = 57572,
|
SPELL_LAVA_STRIKE_SUMMON = 57572,
|
||||||
SPELL_SARTHARION_PYROBUFFET = 56916,
|
SPELL_SARTHARION_PYROBUFFET = 56916,
|
||||||
SPELL_SARTHARION_BERSERK = 61632,
|
SPELL_SARTHARION_BERSERK = 61632,
|
||||||
|
SPELL_SARTHARION_ENRAGE = 56916,
|
||||||
SPELL_SARTHARION_TWILIGHT_REVENGE = 60639,
|
SPELL_SARTHARION_TWILIGHT_REVENGE = 60639,
|
||||||
|
|
||||||
// Sartharion with drakes
|
// Sartharion with drakes
|
||||||
@@ -105,6 +108,7 @@ enum Spells
|
|||||||
SPELL_FLAME_TSUNAMI_DAMAGE_AURA = 57492,
|
SPELL_FLAME_TSUNAMI_DAMAGE_AURA = 57492,
|
||||||
SPELL_FLAME_TSUNAMI_LEAP = 60241,
|
SPELL_FLAME_TSUNAMI_LEAP = 60241,
|
||||||
SPELL_SARTHARION_PYROBUFFET_TRIGGER = 57557,
|
SPELL_SARTHARION_PYROBUFFET_TRIGGER = 57557,
|
||||||
|
SPELL_FULL_HEAL = 43978,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum NPCs
|
enum NPCs
|
||||||
@@ -130,9 +134,7 @@ enum Misc
|
|||||||
ACTION_DRAKE_DIED = 3,
|
ACTION_DRAKE_DIED = 3,
|
||||||
|
|
||||||
// Movement points
|
// Movement points
|
||||||
POINT_FINAL_TENEBRON = 9,
|
POINT_LANDING = 1,
|
||||||
POINT_FINAL_SHADRON = 5,
|
|
||||||
POINT_FINAL_VESPERON = 5,
|
|
||||||
|
|
||||||
// Lava directions. Its used to identify to which side lava was moving by last time
|
// Lava directions. Its used to identify to which side lava was moving by last time
|
||||||
LAVA_LEFT_SIDE = 0,
|
LAVA_LEFT_SIDE = 0,
|
||||||
@@ -156,6 +158,8 @@ enum Events
|
|||||||
EVENT_MINIBOSS_OPEN_PORTAL = 4,
|
EVENT_MINIBOSS_OPEN_PORTAL = 4,
|
||||||
EVENT_MINIBOSS_SPAWN_HELPERS = 5,
|
EVENT_MINIBOSS_SPAWN_HELPERS = 5,
|
||||||
EVENT_MINIBOSS_RESPOND = 6,
|
EVENT_MINIBOSS_RESPOND = 6,
|
||||||
|
EVENT_DRAGON_START_PATROL = 7,
|
||||||
|
EVENT_DRAGON_PATROL_WAYPOINT = 8,
|
||||||
|
|
||||||
// Sartharion abilities
|
// Sartharion abilities
|
||||||
EVENT_SARTHARION_CAST_CLEAVE = 10,
|
EVENT_SARTHARION_CAST_CLEAVE = 10,
|
||||||
@@ -222,6 +226,45 @@ const Position AreaTriggerSummonPos[MAX_AREA_TRIGGER_COUNT] =
|
|||||||
{ 3242.84f, 553.979f, 58.8272f, 0.0f },
|
{ 3242.84f, 553.979f, 58.8272f, 0.0f },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Patrol waypoints for Vesperon (circular patrol above Sartharion)
|
||||||
|
const Position VesperonPatrolPath[8] =
|
||||||
|
{
|
||||||
|
{ 3296.785f, 555.0555f, 87.29027f, 0.0f },
|
||||||
|
{ 3266.8242f, 575.95245f, 89.76242f, 0.0f },
|
||||||
|
{ 3227.2224f, 577.1228f, 89.87349f, 0.0f },
|
||||||
|
{ 3197.2644f, 553.5248f, 88.651405f, 0.0f },
|
||||||
|
{ 3195.9875f, 507.7954f, 87.45695f, 0.0f },
|
||||||
|
{ 3224.5435f, 481.11807f, 84.70684f, 0.0f },
|
||||||
|
{ 3265.2356f, 481.7216f, 83.595764f, 0.0f },
|
||||||
|
{ 3299.8765f, 506.4301f, 83.87355f, 0.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Patrol waypoints for Tenebron (circular patrol above Sartharion)
|
||||||
|
const Position TenebronPatrolPath[8] =
|
||||||
|
{
|
||||||
|
{ 3232.0261f, 569.16376f, 97.53158f, 0.0f },
|
||||||
|
{ 3203.6875f, 548.84595f, 98.50729f, 0.0f },
|
||||||
|
{ 3206.0713f, 513.54425f, 99.3684f, 0.0f },
|
||||||
|
{ 3234.5671f, 489.96832f, 99.47933f, 0.0f },
|
||||||
|
{ 3265.446f, 490.026f, 98.423836f, 0.0f },
|
||||||
|
{ 3287.5674f, 503.39835f, 97.645226f, 0.0f },
|
||||||
|
{ 3288.8157f, 549.16187f, 96.70078f, 0.0f },
|
||||||
|
{ 3264.5164f, 568.97516f, 95.97868f, 0.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Patrol waypoints for Shadron (circular patrol above Sartharion)
|
||||||
|
const Position ShadronPatrolPath[8] =
|
||||||
|
{
|
||||||
|
{ 3196.095f, 548.7049f, 115.83286f, 0.0f },
|
||||||
|
{ 3224.809f, 573.8922f, 116.08303f, 0.0f },
|
||||||
|
{ 3270.8267f, 572.1468f, 112.77744f, 0.0f },
|
||||||
|
{ 3295.5364f, 547.12506f, 109.66705f, 0.0f },
|
||||||
|
{ 3296.5833f, 503.22397f, 106.95133f, 0.0f },
|
||||||
|
{ 3254.0688f, 489.25906f, 108.92368f, 0.0f },
|
||||||
|
{ 3223.111f, 488.90338f, 110.53484f, 0.0f },
|
||||||
|
{ 3197.9263f, 511.4375f, 113.22937f, 0.0f },
|
||||||
|
};
|
||||||
|
|
||||||
float const FlameTsunamiLeftOffsets[MAX_LEFT_LAVA_TSUNAMIS] =
|
float const FlameTsunamiLeftOffsets[MAX_LEFT_LAVA_TSUNAMIS] =
|
||||||
{
|
{
|
||||||
476.0f, 484.0f, 492.0f,
|
476.0f, 484.0f, 492.0f,
|
||||||
@@ -239,13 +282,30 @@ const Position bigIslandMiddlePos = { 3242.822754f, 477.279816f, 57.430473f };
|
|||||||
|
|
||||||
const uint32 dragons[MAX_DRAGONS] = { DATA_TENEBRON, DATA_VESPERON, DATA_SHADRON };
|
const uint32 dragons[MAX_DRAGONS] = { DATA_TENEBRON, DATA_VESPERON, DATA_SHADRON };
|
||||||
|
|
||||||
|
const Position dragonLandingPos[MAX_DRAGONS] ={
|
||||||
|
{3249.75f, 566.95184f, 59.424007f, 0}, // Tenebron
|
||||||
|
{3230.4963f, 533.0001f, 59.5598f, 0}, // Shadron
|
||||||
|
{3269.7134f, 532.7908f, 59.51278f, 0} // Vesperon
|
||||||
|
};
|
||||||
|
|
||||||
|
static Position const& GetDragonLandingPos(uint32 entry)
|
||||||
|
{
|
||||||
|
switch (entry)
|
||||||
|
{
|
||||||
|
case NPC_TENEBRON: return dragonLandingPos[0];
|
||||||
|
case NPC_SHADRON: return dragonLandingPos[1];
|
||||||
|
case NPC_VESPERON: return dragonLandingPos[2];
|
||||||
|
default: return dragonLandingPos[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// SARTHARION
|
// SARTHARION
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
|
|
||||||
struct boss_sartharion : public BossAI
|
struct boss_sartharion : public BossAI
|
||||||
{
|
{
|
||||||
boss_sartharion(Creature* creature) : BossAI(creature, DATA_SARTHARION),
|
explicit boss_sartharion(Creature* creature) : BossAI(creature, DATA_SARTHARION),
|
||||||
dragonsCount(0),
|
dragonsCount(0),
|
||||||
lastLavaSide(LAVA_RIGHT_SIDE),
|
lastLavaSide(LAVA_RIGHT_SIDE),
|
||||||
usedBerserk(false),
|
usedBerserk(false),
|
||||||
@@ -257,7 +317,7 @@ struct boss_sartharion : public BossAI
|
|||||||
{
|
{
|
||||||
_Reset();
|
_Reset();
|
||||||
extraEvents.Reset();
|
extraEvents.Reset();
|
||||||
RespawnDragons(false);
|
|
||||||
SummonStartingTriggers();
|
SummonStartingTriggers();
|
||||||
usedBerserk = false;
|
usedBerserk = false;
|
||||||
below11PctReached = false;
|
below11PctReached = false;
|
||||||
@@ -266,6 +326,21 @@ struct boss_sartharion : public BossAI
|
|||||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_SHIFT);
|
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnterEvadeMode(EvadeReason why) override
|
||||||
|
{
|
||||||
|
BossAI::EnterEvadeMode(why);
|
||||||
|
|
||||||
|
// Despawn drakes
|
||||||
|
for (uint32 i : dragons)
|
||||||
|
{
|
||||||
|
if (instance->GetBossState(i) == DONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Creature* boss = instance->GetCreature(i) )
|
||||||
|
boss->DespawnOnEvade();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DoAction(int32 param) override
|
void DoAction(int32 param) override
|
||||||
{
|
{
|
||||||
if (param == ACTION_DRAKE_DIED)
|
if (param == ACTION_DRAKE_DIED)
|
||||||
@@ -276,6 +351,7 @@ struct boss_sartharion : public BossAI
|
|||||||
{
|
{
|
||||||
_JustEngagedWith();
|
_JustEngagedWith();
|
||||||
DoCastSelf(SPELL_SARTHARION_PYROBUFFET, true);
|
DoCastSelf(SPELL_SARTHARION_PYROBUFFET, true);
|
||||||
|
ScheduleEnrageTimer(SPELL_SARTHARION_ENRAGE, 15min);
|
||||||
Talk(SAY_SARTHARION_AGGRO);
|
Talk(SAY_SARTHARION_AGGRO);
|
||||||
|
|
||||||
// Combat events
|
// Combat events
|
||||||
@@ -296,7 +372,7 @@ struct boss_sartharion : public BossAI
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
dragon->SetImmuneToNPC(true);
|
dragon->SetImmuneToNPC(true);
|
||||||
dragon->SetFullHealth();
|
dragon->CastSpell(dragon, SPELL_FULL_HEAL, true);
|
||||||
|
|
||||||
++dragonsCount;
|
++dragonsCount;
|
||||||
me->AddLootMode(1 << dragonsCount);
|
me->AddLootMode(1 << dragonsCount);
|
||||||
@@ -306,33 +382,35 @@ struct boss_sartharion : public BossAI
|
|||||||
case DATA_TENEBRON:
|
case DATA_TENEBRON:
|
||||||
{
|
{
|
||||||
dragon->CastSpell(dragon, SPELL_POWER_OF_TENEBRON, true);
|
dragon->CastSpell(dragon, SPELL_POWER_OF_TENEBRON, true);
|
||||||
extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_TENEBRON, 10s);
|
extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_TENEBRON, 20s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DATA_SHADRON:
|
case DATA_SHADRON:
|
||||||
{
|
{
|
||||||
dragon->CastSpell(dragon, SPELL_POWER_OF_SHADRON, true);
|
dragon->CastSpell(dragon, SPELL_POWER_OF_SHADRON, true);
|
||||||
extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_SHADRON, 65s);
|
extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_SHADRON, 60s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DATA_VESPERON:
|
case DATA_VESPERON:
|
||||||
{
|
{
|
||||||
dragon->CastSpell(dragon, SPELL_POWER_OF_VESPERON, true);
|
dragon->CastSpell(dragon, SPELL_POWER_OF_VESPERON, true);
|
||||||
extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_VESPERON, 115s);
|
extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_VESPERON, 120s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dragonsCount)
|
if (dragonsCount)
|
||||||
|
{
|
||||||
DoCastSelf(SPELL_WILL_OF_SARTHARION, true);
|
DoCastSelf(SPELL_WILL_OF_SARTHARION, true);
|
||||||
|
instance->DoAction(ACTION_START_PATROL);
|
||||||
|
}
|
||||||
|
|
||||||
me->CallForHelp(500.0f);
|
me->CallForHelp(500.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
{
|
{
|
||||||
RespawnDragons(true);
|
|
||||||
_JustDied();
|
_JustDied();
|
||||||
Talk(SAY_SARTHARION_DEATH);
|
Talk(SAY_SARTHARION_DEATH);
|
||||||
}
|
}
|
||||||
@@ -475,6 +553,8 @@ struct boss_sartharion : public BossAI
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,6 +615,8 @@ struct boss_sartharion : public BossAI
|
|||||||
summons.DespawnEntry(NPC_SAFE_AREA_TRIGGER);
|
summons.DespawnEntry(NPC_SAFE_AREA_TRIGGER);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
@@ -547,15 +629,11 @@ struct boss_sartharion : public BossAI
|
|||||||
private:
|
private:
|
||||||
void SummonStartingTriggers()
|
void SummonStartingTriggers()
|
||||||
{
|
{
|
||||||
for (uint8 i = 0; i < MAX_CYCLONE_COUNT; ++i)
|
for (auto const& CycloneSummonPo : CycloneSummonPos)
|
||||||
{
|
me->SummonCreature(NPC_FIRE_CYCLONE, CycloneSummonPo);
|
||||||
me->SummonCreature(NPC_FIRE_CYCLONE, CycloneSummonPos[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8 i = 0; i < MAX_AREA_TRIGGER_COUNT; ++i)
|
for (auto const& AreaTriggerSummonPo : AreaTriggerSummonPos)
|
||||||
{
|
me->SummonCreature(NPC_SAFE_AREA_TRIGGER, AreaTriggerSummonPo);
|
||||||
me->SummonCreature(NPC_SAFE_AREA_TRIGGER, AreaTriggerSummonPos[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SummonLavaWaves()
|
void SummonLavaWaves()
|
||||||
@@ -617,26 +695,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RespawnDragons(bool checkCombat)
|
|
||||||
{
|
|
||||||
for (uint8 i = 0; i < MAX_DRAGONS; ++i)
|
|
||||||
{
|
|
||||||
if (instance->GetBossState(dragons[i]) == DONE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (Creature* dragon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(dragons[i])))
|
|
||||||
{
|
|
||||||
if (checkCombat && dragon->IsInCombat())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dragon->DespawnOrUnsummon();
|
|
||||||
dragon->SetRespawnTime(5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dragonsCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
EventMap extraEvents;
|
EventMap extraEvents;
|
||||||
std::list<uint32> volcanoBlows;
|
std::list<uint32> volcanoBlows;
|
||||||
uint8 dragonsCount;
|
uint8 dragonsCount;
|
||||||
@@ -647,20 +705,21 @@ private:
|
|||||||
|
|
||||||
struct boss_sartharion_dragonAI : public BossAI
|
struct boss_sartharion_dragonAI : public BossAI
|
||||||
{
|
{
|
||||||
boss_sartharion_dragonAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), isCalledBySartharion(false)
|
boss_sartharion_dragonAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), isCalledBySartharion(false), currentPatrolPoint(0) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
_Reset();
|
_Reset();
|
||||||
events.Reset();
|
events.Reset();
|
||||||
|
extraEvents.Reset();
|
||||||
ClearInstance();
|
ClearInstance();
|
||||||
|
|
||||||
me->SetImmuneToNPC(false);
|
me->SetImmuneToNPC(false);
|
||||||
me->SetSpeed(MOVE_FLIGHT, 1.0f);
|
me->SetSpeed(MOVE_FLIGHT, 1.0f);
|
||||||
me->SetCanFly(false);
|
me->SetDisableGravity(false);
|
||||||
|
me->SetHover(true);
|
||||||
me->ResetLootMode();
|
me->ResetLootMode();
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
portalGUID.Clear();
|
portalGUID.Clear();
|
||||||
isCalledBySartharion = false;
|
isCalledBySartharion = false;
|
||||||
instance->DoAction(ACTION_CLEAR_PORTAL);
|
instance->DoAction(ACTION_CLEAR_PORTAL);
|
||||||
@@ -673,11 +732,14 @@ struct boss_sartharion_dragonAI : public BossAI
|
|||||||
isCalledBySartharion = true;
|
isCalledBySartharion = true;
|
||||||
extraEvents.RescheduleEvent(EVENT_MINIDRAKE_SPEECH, 4s);
|
extraEvents.RescheduleEvent(EVENT_MINIDRAKE_SPEECH, 4s);
|
||||||
}
|
}
|
||||||
|
else if (param == ACTION_START_PATROL)
|
||||||
|
extraEvents.ScheduleEvent(EVENT_DRAGON_START_PATROL, 500ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit* who) final
|
void MoveInLineOfSight(Unit* who) final
|
||||||
{
|
{
|
||||||
if (isCalledBySartharion)
|
// Prevent aggro during patrol (NOT_SELECTABLE set) and while flying to landing position
|
||||||
|
if (isCalledBySartharion || me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ScriptedAI::MoveInLineOfSight(who);
|
ScriptedAI::MoveInLineOfSight(who);
|
||||||
@@ -685,33 +747,21 @@ struct boss_sartharion_dragonAI : public BossAI
|
|||||||
|
|
||||||
void MovementInform(uint32 type, uint32 pointId) final
|
void MovementInform(uint32 type, uint32 pointId) final
|
||||||
{
|
{
|
||||||
if (type != WAYPOINT_MOTION_TYPE)
|
if (type == POINT_MOTION_TYPE && pointId == POINT_LANDING)
|
||||||
return;
|
|
||||||
|
|
||||||
switch (me->GetEntry())
|
|
||||||
{
|
{
|
||||||
case NPC_TENEBRON:
|
// Dragon has landed - set ground flags
|
||||||
{
|
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
if (pointId != POINT_FINAL_TENEBRON)
|
me->SetDisableGravity(false);
|
||||||
return;
|
me->SetHover(false);
|
||||||
break;
|
me->SetAnimTier(AnimTier::Ground);
|
||||||
}
|
me->SetImmuneToNPC(false);
|
||||||
case NPC_SHADRON:
|
me->SetInCombatWithZone();
|
||||||
{
|
}
|
||||||
if (pointId != POINT_FINAL_SHADRON)
|
else if (type == POINT_MOTION_TYPE && pointId >= 100 && pointId < 200)
|
||||||
return;
|
{
|
||||||
break;
|
// Patrol waypoint reached - schedule next waypoint
|
||||||
}
|
extraEvents.ScheduleEvent(EVENT_DRAGON_PATROL_WAYPOINT, 100ms);
|
||||||
case NPC_VESPERON:
|
|
||||||
{
|
|
||||||
if (pointId != POINT_FINAL_VESPERON)
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
me->SetImmuneToNPC(false);
|
|
||||||
me->SetInCombatWithZone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustSummoned(Creature* summon) override
|
void JustSummoned(Creature* summon) override
|
||||||
@@ -735,7 +785,6 @@ struct boss_sartharion_dragonAI : public BossAI
|
|||||||
if (me->IsFlying())
|
if (me->IsFlying())
|
||||||
{
|
{
|
||||||
me->SetSpeed(MOVE_FLIGHT, 1.0f);
|
me->SetSpeed(MOVE_FLIGHT, 1.0f);
|
||||||
me->SetCanFly(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCalledBySartharion || instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
|
if (!isCalledBySartharion || instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
|
||||||
@@ -881,7 +930,66 @@ struct boss_sartharion_dragonAI : public BossAI
|
|||||||
RemoveTwilightPortal();
|
RemoveTwilightPortal();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void HandleExtraEvent(uint32 const /*eventId*/) { }
|
void HandleExtraEvent(uint32 const eventId)
|
||||||
|
{
|
||||||
|
if (eventId == EVENT_MINIDRAKE_SPEECH)
|
||||||
|
{
|
||||||
|
// Dragon speaks and starts flying to landing position
|
||||||
|
Talk(SAY_DRAKE_RESPOND);
|
||||||
|
me->GetMotionMaster()->Clear();
|
||||||
|
me->SetDisableGravity(true);
|
||||||
|
me->SetHover(true);
|
||||||
|
me->SetAnimTier(AnimTier::Fly);
|
||||||
|
me->SetSpeed(MOVE_FLIGHT, 3.0f);
|
||||||
|
me->GetMotionMaster()->MovePoint(POINT_LANDING, GetDragonLandingPos(me->GetEntry()));
|
||||||
|
}
|
||||||
|
else if (eventId == EVENT_DRAGON_START_PATROL)
|
||||||
|
{
|
||||||
|
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
me->SetDisableGravity(true);
|
||||||
|
me->SetHover(true);
|
||||||
|
me->SetAnimTier(AnimTier::Fly);
|
||||||
|
currentPatrolPoint = 0;
|
||||||
|
|
||||||
|
// Start patrol using custom waypoint system
|
||||||
|
extraEvents.ScheduleEvent(EVENT_DRAGON_PATROL_WAYPOINT, 100ms);
|
||||||
|
}
|
||||||
|
else if (eventId == EVENT_DRAGON_PATROL_WAYPOINT)
|
||||||
|
{
|
||||||
|
// Only continue patrol if not in combat and still selectable flag is set
|
||||||
|
if (!me->IsInCombat() && me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||||
|
{
|
||||||
|
// Ensure flying flags are maintained
|
||||||
|
me->SetDisableGravity(true);
|
||||||
|
me->SetHover(true);
|
||||||
|
me->SetAnimTier(AnimTier::Fly);
|
||||||
|
|
||||||
|
// Get the appropriate patrol path based on creature entry
|
||||||
|
Position const* patrolPath = nullptr;
|
||||||
|
switch (me->GetEntry())
|
||||||
|
{
|
||||||
|
case NPC_VESPERON:
|
||||||
|
patrolPath = VesperonPatrolPath;
|
||||||
|
break;
|
||||||
|
case NPC_TENEBRON:
|
||||||
|
patrolPath = TenebronPatrolPath;
|
||||||
|
break;
|
||||||
|
case NPC_SHADRON:
|
||||||
|
patrolPath = ShadronPatrolPath;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to next patrol point (use pointId 100+ to identify patrol points)
|
||||||
|
me->GetMotionMaster()->MovePoint(100 + currentPatrolPoint, patrolPath[currentPatrolPoint]);
|
||||||
|
|
||||||
|
// Cycle to next waypoint
|
||||||
|
currentPatrolPoint = (currentPatrolPoint + 1) % 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void RemoveTwilightPortal()
|
void RemoveTwilightPortal()
|
||||||
{
|
{
|
||||||
@@ -897,6 +1005,7 @@ protected:
|
|||||||
EventMap extraEvents;
|
EventMap extraEvents;
|
||||||
ObjectGuid portalGUID;
|
ObjectGuid portalGUID;
|
||||||
bool isCalledBySartharion;
|
bool isCalledBySartharion;
|
||||||
|
uint8 currentPatrolPoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
@@ -905,9 +1014,7 @@ protected:
|
|||||||
|
|
||||||
struct boss_sartharion_tenebron : public boss_sartharion_dragonAI
|
struct boss_sartharion_tenebron : public boss_sartharion_dragonAI
|
||||||
{
|
{
|
||||||
boss_sartharion_tenebron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_TENEBRON), summons2(creature)
|
explicit boss_sartharion_tenebron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_TENEBRON), summons2(creature) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
@@ -935,17 +1042,6 @@ struct boss_sartharion_tenebron : public boss_sartharion_dragonAI
|
|||||||
boss_sartharion_dragonAI::JustDied(killer);
|
boss_sartharion_dragonAI::JustDied(killer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleExtraEvent(uint32 const eventId) override
|
|
||||||
{
|
|
||||||
if (eventId == EVENT_MINIDRAKE_SPEECH)
|
|
||||||
{
|
|
||||||
Talk(SAY_TENEBRON_RESPOND);
|
|
||||||
me->SetCanFly(true);
|
|
||||||
me->SetSpeed(MOVE_FLIGHT, 3.0f);
|
|
||||||
me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteEvent(uint32 eventId) override
|
void ExecuteEvent(uint32 eventId) override
|
||||||
{
|
{
|
||||||
switch (eventId)
|
switch (eventId)
|
||||||
@@ -1036,6 +1132,8 @@ struct boss_sartharion_tenebron : public boss_sartharion_dragonAI
|
|||||||
summons.DoAction(ACTION_SWITCH_PHASE, pred);
|
summons.DoAction(ACTION_SWITCH_PHASE, pred);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1055,9 +1153,7 @@ private:
|
|||||||
|
|
||||||
struct boss_sartharion_shadron : public boss_sartharion_dragonAI
|
struct boss_sartharion_shadron : public boss_sartharion_dragonAI
|
||||||
{
|
{
|
||||||
boss_sartharion_shadron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_SHADRON)
|
explicit boss_sartharion_shadron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_SHADRON) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
@@ -1087,17 +1183,6 @@ struct boss_sartharion_shadron : public boss_sartharion_dragonAI
|
|||||||
events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s);
|
events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleExtraEvent(uint32 const eventId) override
|
|
||||||
{
|
|
||||||
if (eventId == EVENT_MINIDRAKE_SPEECH)
|
|
||||||
{
|
|
||||||
Talk(SAY_SHADRON_RESPOND);
|
|
||||||
me->SetCanFly(true);
|
|
||||||
me->SetSpeed(MOVE_FLIGHT, 3.0f);
|
|
||||||
me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteEvent(uint32 eventId) override
|
void ExecuteEvent(uint32 eventId) override
|
||||||
{
|
{
|
||||||
switch (eventId)
|
switch (eventId)
|
||||||
@@ -1147,6 +1232,8 @@ struct boss_sartharion_shadron : public boss_sartharion_dragonAI
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1157,9 +1244,7 @@ struct boss_sartharion_shadron : public boss_sartharion_dragonAI
|
|||||||
|
|
||||||
struct boss_sartharion_vesperon : public boss_sartharion_dragonAI
|
struct boss_sartharion_vesperon : public boss_sartharion_dragonAI
|
||||||
{
|
{
|
||||||
boss_sartharion_vesperon(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_VESPERON)
|
explicit boss_sartharion_vesperon(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_VESPERON) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
@@ -1182,17 +1267,6 @@ struct boss_sartharion_vesperon : public boss_sartharion_dragonAI
|
|||||||
events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s);
|
events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleExtraEvent(uint32 const eventId) override
|
|
||||||
{
|
|
||||||
if (eventId == EVENT_MINIDRAKE_SPEECH)
|
|
||||||
{
|
|
||||||
Talk(SAY_SHADRON_RESPOND);
|
|
||||||
me->SetCanFly(true);
|
|
||||||
me->SetSpeed(MOVE_FLIGHT, 3.0f);
|
|
||||||
me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteEvent(uint32 eventId) override
|
void ExecuteEvent(uint32 eventId) override
|
||||||
{
|
{
|
||||||
switch (eventId)
|
switch (eventId)
|
||||||
@@ -1241,6 +1315,8 @@ struct boss_sartharion_vesperon : public boss_sartharion_dragonAI
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1258,9 +1334,7 @@ private:
|
|||||||
// other
|
// other
|
||||||
struct npc_twilight_summon : public ScriptedAI
|
struct npc_twilight_summon : public ScriptedAI
|
||||||
{
|
{
|
||||||
npc_twilight_summon(Creature* creature) : ScriptedAI(creature),
|
explicit npc_twilight_summon(Creature* creature) : ScriptedAI(creature), fadeArmorTimer(urand(0, 15000)) {
|
||||||
fadeArmorTimer(urand(0, 15000))
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
@@ -1349,7 +1423,7 @@ class spell_sartharion_lava_strike : public SpellScript
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _spawned;
|
bool _spawned{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 57491 - Flame Tsunami
|
// 57491 - Flame Tsunami
|
||||||
|
|||||||
@@ -21,6 +21,15 @@
|
|||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "obsidian_sanctum.h"
|
#include "obsidian_sanctum.h"
|
||||||
|
|
||||||
|
ObjectData const creatureData[] =
|
||||||
|
{
|
||||||
|
{ NPC_SARTHARION, DATA_SARTHARION },
|
||||||
|
{ NPC_TENEBRON, DATA_TENEBRON },
|
||||||
|
{ NPC_SHADRON, DATA_SHADRON },
|
||||||
|
{ NPC_VESPERON, DATA_VESPERON },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
class instance_obsidian_sanctum : public InstanceMapScript
|
class instance_obsidian_sanctum : public InstanceMapScript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -33,46 +42,16 @@ public:
|
|||||||
|
|
||||||
struct instance_obsidian_sanctum_InstanceMapScript : public InstanceScript
|
struct instance_obsidian_sanctum_InstanceMapScript : public InstanceScript
|
||||||
{
|
{
|
||||||
instance_obsidian_sanctum_InstanceMapScript(Map* pMap) : InstanceScript(pMap), portalCount(0)
|
explicit instance_obsidian_sanctum_InstanceMapScript(Map* pMap) : InstanceScript(pMap), portalCount(0)
|
||||||
{
|
{
|
||||||
SetHeaders(DataHeader);
|
SetHeaders(DataHeader);
|
||||||
SetBossNumber(MAX_ENCOUNTERS);
|
SetBossNumber(MAX_ENCOUNTERS);
|
||||||
}
|
LoadObjectData(creatureData, nullptr);
|
||||||
|
|
||||||
void OnCreatureCreate(Creature* pCreature) override
|
|
||||||
{
|
|
||||||
switch (pCreature->GetEntry())
|
|
||||||
{
|
|
||||||
case NPC_SARTHARION:
|
|
||||||
m_uiSartharionGUID = pCreature->GetGUID();
|
|
||||||
break;
|
|
||||||
case NPC_TENEBRON:
|
|
||||||
m_uiTenebronGUID = pCreature->GetGUID();
|
|
||||||
break;
|
|
||||||
case NPC_SHADRON:
|
|
||||||
m_uiShadronGUID = pCreature->GetGUID();
|
|
||||||
break;
|
|
||||||
case NPC_VESPERON:
|
|
||||||
m_uiVesperonGUID = pCreature->GetGUID();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectGuid GetGuidData(uint32 uiData) const override
|
ObjectGuid GetGuidData(uint32 uiData) const override
|
||||||
{
|
{
|
||||||
switch (uiData)
|
return GetObjectGuid(uiData);
|
||||||
{
|
|
||||||
case DATA_SARTHARION:
|
|
||||||
return m_uiSartharionGUID;
|
|
||||||
case DATA_TENEBRON:
|
|
||||||
return m_uiTenebronGUID;
|
|
||||||
case DATA_SHADRON:
|
|
||||||
return m_uiShadronGUID;
|
|
||||||
case DATA_VESPERON:
|
|
||||||
return m_uiVesperonGUID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ObjectGuid::Empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override
|
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override
|
||||||
@@ -84,7 +63,7 @@ public:
|
|||||||
// Gonna Go When the Volcano Blows (25 player) (2048)
|
// Gonna Go When the Volcano Blows (25 player) (2048)
|
||||||
case 7327:
|
case 7327:
|
||||||
{
|
{
|
||||||
Creature const* sartharion = instance->GetCreature(m_uiSartharionGUID);
|
Creature const* sartharion = GetCreature(DATA_SARTHARION);
|
||||||
return sartharion && !sartharion->AI()->GetData(source->GetGUID().GetCounter());
|
return sartharion && !sartharion->AI()->GetData(source->GetGUID().GetCounter());
|
||||||
}
|
}
|
||||||
// Less Is More (10 player) (624)
|
// Less Is More (10 player) (624)
|
||||||
@@ -108,7 +87,7 @@ public:
|
|||||||
// Twilight Assist (25 player) (2052)
|
// Twilight Assist (25 player) (2052)
|
||||||
case 7331:
|
case 7331:
|
||||||
{
|
{
|
||||||
Creature const* sartharion = instance->GetCreature(m_uiSartharionGUID);
|
Creature const* sartharion = GetCreature(DATA_SARTHARION);
|
||||||
return sartharion && sartharion->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 1;
|
return sartharion && sartharion->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 1;
|
||||||
}
|
}
|
||||||
// Twilight Duo (10 player) (2050)
|
// Twilight Duo (10 player) (2050)
|
||||||
@@ -116,7 +95,7 @@ public:
|
|||||||
// Twilight Duo (25 player) (2053)
|
// Twilight Duo (25 player) (2053)
|
||||||
case 7332:
|
case 7332:
|
||||||
{
|
{
|
||||||
Creature const* sartharion = instance->GetCreature(m_uiSartharionGUID);
|
Creature const* sartharion = GetCreature(DATA_SARTHARION);
|
||||||
return sartharion && sartharion->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 2;
|
return sartharion && sartharion->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 2;
|
||||||
}
|
}
|
||||||
// Twilight Zone (10 player) (2051)
|
// Twilight Zone (10 player) (2051)
|
||||||
@@ -124,12 +103,13 @@ public:
|
|||||||
// Twilight Zone (25 player) (2054)
|
// Twilight Zone (25 player) (2054)
|
||||||
case 7333:
|
case 7333:
|
||||||
{
|
{
|
||||||
Creature const* sartharion = instance->GetCreature(m_uiSartharionGUID);
|
Creature const* sartharion = GetCreature(DATA_SARTHARION);
|
||||||
return sartharion && sartharion->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 3;
|
return sartharion && sartharion->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 3;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoAction(int32 action) override
|
void DoAction(int32 action) override
|
||||||
@@ -140,7 +120,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (!m_uiPortalGUID)
|
if (!m_uiPortalGUID)
|
||||||
{
|
{
|
||||||
if (Creature* sartharion = instance->GetCreature(m_uiSartharionGUID))
|
if (Creature* sartharion = GetCreature(DATA_SARTHARION))
|
||||||
{
|
{
|
||||||
if (GameObject* portal = sartharion->SummonGameObject(GO_TWILIGHT_PORTAL, 3247.29f, 529.804f, 58.9595f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
|
if (GameObject* portal = sartharion->SummonGameObject(GO_TWILIGHT_PORTAL, 3247.29f, 529.804f, 58.9595f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
|
||||||
{
|
{
|
||||||
@@ -170,14 +150,33 @@ public:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ACTION_START_PATROL:
|
||||||
|
{
|
||||||
|
if (Creature* tenebron = GetCreature(DATA_TENEBRON))
|
||||||
|
{
|
||||||
|
if (tenebron->IsAlive() && GetBossState(DATA_TENEBRON) != DONE)
|
||||||
|
tenebron->AI()->DoAction(ACTION_START_PATROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Creature* shadron = GetCreature(DATA_SHADRON))
|
||||||
|
{
|
||||||
|
if (shadron->IsAlive() && GetBossState(DATA_SHADRON) != DONE)
|
||||||
|
shadron->AI()->DoAction(ACTION_START_PATROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Creature* vesperon = GetCreature(DATA_VESPERON))
|
||||||
|
{
|
||||||
|
if (vesperon->IsAlive() && GetBossState(DATA_VESPERON) != DONE)
|
||||||
|
vesperon->AI()->DoAction(ACTION_START_PATROL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ObjectGuid m_uiSartharionGUID;
|
|
||||||
ObjectGuid m_uiTenebronGUID;
|
|
||||||
ObjectGuid m_uiShadronGUID;
|
|
||||||
ObjectGuid m_uiVesperonGUID;
|
|
||||||
ObjectGuid m_uiPortalGUID;
|
ObjectGuid m_uiPortalGUID;
|
||||||
uint8 portalCount;
|
uint8 portalCount;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ enum OSActions
|
|||||||
// Portal
|
// Portal
|
||||||
ACTION_CLEAR_PORTAL = -1,
|
ACTION_CLEAR_PORTAL = -1,
|
||||||
ACTION_ADD_PORTAL = -2,
|
ACTION_ADD_PORTAL = -2,
|
||||||
|
|
||||||
|
// Dragon patrol
|
||||||
|
ACTION_START_PATROL = -3,
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class AI, class T>
|
template <class AI, class T>
|
||||||
|
|||||||
Reference in New Issue
Block a user