refactor(Scripts/EoE): Modernize scripts (#24634)

This commit is contained in:
Andrew
2026-02-10 00:27:18 -03:00
committed by GitHub
parent 1c5c28b6f8
commit 4c1e559f54
3 changed files with 402 additions and 479 deletions

View File

@@ -17,6 +17,7 @@
#include "CombatAI.h"
#include "CreatureScript.h"
#include "GameObjectAI.h"
#include "GameObjectScript.h"
#include "MoveSplineInit.h"
#include "Opcodes.h"
@@ -177,7 +178,6 @@ enum Phases
#define MAX_NEXUS_LORDS DUNGEON_MODE(2, 4)
#define MAX_SCIONS_OF_ETERNITY DUNGEON_MODE(4, 8)
#define AREA_EYE_OF_ETERNITY 4500
enum MalygosLightOverrides
{
@@ -211,6 +211,7 @@ struct boss_malygos : public BossAI
IntroCounter = 0;
bLockHealthCheck = false;
SetInvincibility(true);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED);
me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE);
@@ -222,72 +223,70 @@ struct boss_malygos : public BossAI
void MovementInform(uint32 type, uint32 id) override
{
if (type == POINT_MOTION_TYPE)
{
switch (id)
{
case MI_POINT_INTRO_SIDE_0:
case MI_POINT_INTRO_SIDE_1:
case MI_POINT_INTRO_SIDE_2:
case MI_POINT_INTRO_SIDE_3:
{
float angle = me->GetOrientation();
float dist = 75.0f;
if (Creature* c = me->SummonCreature(NPC_PORTAL, me->GetPositionX() + cos(angle) * dist, me->GetPositionY() + std::sin(angle) * dist, me->GetPositionZ(), FourSidesPos[id].GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 13000))
me->CastSpell(c, SPELL_PORTAL_BEAM, false);
timer2 = INTRO_MOVEMENT_INTERVAL - 10000;
}
break;
if (type != POINT_MOTION_TYPE)
return;
case MI_POINT_INTRO_CENTER_AIR:
events.RescheduleEvent(EVENT_INTRO_LAND, 0ms, 1);
break;
case MI_POINT_VORTEX_CENTER:
if (Creature* c = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 15000))
c->CastSpell(c, SPELL_VORTEX_VISUAL, true);
events.RescheduleEvent(EVENT_START_VORTEX_REAL, 1s, 1);
break;
case MI_POINT_CENTER_GROUND_PH_2:
events.RescheduleEvent(EVENT_START_PHASE_2_FLY_UP, 0ms, 1);
break;
case MI_POINT_CIRCLE_OUTSIDE_PH_2:
events.RescheduleEvent(EVENT_RESUME_FLYING_CIRCLES_PH_2, 0ms, 1);
break;
case MI_POINT_SURGE_OF_POWER_CENTER:
events.RescheduleEvent(EVENT_SURGE_OF_POWER_WARNING, 0ms, 1);
break;
case MI_POINT_INTRO_LAND:
me->SetDisableGravity(false);
events.RescheduleEvent(EVENT_START_FIGHT, 0ms, 1);
break;
case MI_POINT_VORTEX_TAKEOFF:
events.RescheduleEvent(EVENT_VORTEX_FLY_TO_CENTER, 0ms, 1);
break;
case MI_POINT_VORTEX_LAND:
me->SetDisableGravity(false);
events.RescheduleEvent(EVENT_VORTEX_LAND_1, 0ms, 1);
break;
case MI_POINT_CENTER_AIR_PH_2:
me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_ARCANE_RUNES, 5s);
break;
case MI_POINT_PH_3_FIGHT_POSITION:
events.RescheduleEvent(EVENT_START_PHASE_3, 6s, 1);
break;
}
switch (id)
{
case MI_POINT_INTRO_SIDE_0:
case MI_POINT_INTRO_SIDE_1:
case MI_POINT_INTRO_SIDE_2:
case MI_POINT_INTRO_SIDE_3:
{
float angle = me->GetOrientation();
float dist = 75.0f;
if (Creature* c = me->SummonCreature(NPC_PORTAL, me->GetPositionX() + cos(angle) * dist, me->GetPositionY() + std::sin(angle) * dist, me->GetPositionZ(), FourSidesPos[id].GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 13000))
me->CastSpell(c, SPELL_PORTAL_BEAM, false);
timer2 = INTRO_MOVEMENT_INTERVAL - 10000;
}
break;
case MI_POINT_INTRO_CENTER_AIR:
events.RescheduleEvent(EVENT_INTRO_LAND, 0ms, 1);
break;
case MI_POINT_VORTEX_CENTER:
if (Creature* c = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 15000))
c->CastSpell(c, SPELL_VORTEX_VISUAL, true);
events.RescheduleEvent(EVENT_START_VORTEX_REAL, 1s, 1);
break;
case MI_POINT_CENTER_GROUND_PH_2:
events.RescheduleEvent(EVENT_START_PHASE_2_FLY_UP, 0ms, 1);
break;
case MI_POINT_CIRCLE_OUTSIDE_PH_2:
events.RescheduleEvent(EVENT_RESUME_FLYING_CIRCLES_PH_2, 0ms, 1);
break;
case MI_POINT_SURGE_OF_POWER_CENTER:
events.RescheduleEvent(EVENT_SURGE_OF_POWER_WARNING, 0ms, 1);
break;
case MI_POINT_INTRO_LAND:
me->SetDisableGravity(false);
events.RescheduleEvent(EVENT_START_FIGHT, 0ms, 1);
break;
case MI_POINT_VORTEX_TAKEOFF:
events.RescheduleEvent(EVENT_VORTEX_FLY_TO_CENTER, 0ms, 1);
break;
case MI_POINT_VORTEX_LAND:
me->SetDisableGravity(false);
events.RescheduleEvent(EVENT_VORTEX_LAND_1, 0ms, 1);
break;
case MI_POINT_CENTER_AIR_PH_2:
me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_ARCANE_RUNES, 5s);
break;
case MI_POINT_PH_3_FIGHT_POSITION:
events.RescheduleEvent(EVENT_START_PHASE_3, 6s, 1);
break;
}
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
if (spell->Id == SPELL_POWER_SPARK_MALYGOS_BUFF)
{
if (!bLockHealthCheck)
{
Talk(SAY_BUFFED_BY_SPARK);
}
else
me->RemoveAura(SPELL_POWER_SPARK_MALYGOS_BUFF);
}
if (spell->Id != SPELL_POWER_SPARK_MALYGOS_BUFF)
return;
if (!bLockHealthCheck)
Talk(SAY_BUFFED_BY_SPARK);
else
me->RemoveAura(SPELL_POWER_SPARK_MALYGOS_BUFF);
}
void JustEngagedWith(Unit* /*who*/) override
@@ -317,13 +316,9 @@ struct boss_malygos : public BossAI
}
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override
{
if (damage >= me->GetHealth() && !me->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) // allow dying only in phase 3!
{
damage = 0;
return;
}
BossAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask);
if (!bLockHealthCheck && me->HealthBelowPctDamaged(50, damage))
{
@@ -351,7 +346,6 @@ struct boss_malygos : public BossAI
case EVENT_BERSERK:
me->CastSpell(me, SPELL_BERSERK, true);
Talk(EMOTE_BERSERK);
break;
case EVENT_INTRO_MOVE_CENTER:
{
@@ -368,10 +362,8 @@ struct boss_malygos : public BossAI
break;
}
case EVENT_INTRO_LAND:
{
me->GetMotionMaster()->MovePoint(MI_POINT_INTRO_LAND, me->GetPositionX(), me->GetPositionY(), CenterPos.GetPositionZ(), FORCED_MOVEMENT_RUN, 0.f, 0.f, true, true, MOTION_SLOT_ACTIVE, AnimTier::Ground);
break;
}
case EVENT_START_FIGHT:
{
instance->SetData(DATA_HIDE_IRIS_AND_PORTAL, 0);
@@ -406,7 +398,7 @@ struct boss_malygos : public BossAI
c->CastSpell(c, SPELL_PORTAL_BEAM, false);
if (Creature* c = me->SummonCreature(NPC_POWER_SPARK, FourSidesPos[random], TEMPSUMMON_MANUAL_DESPAWN, 0))
{
c->AI()->DoAction(1);
c->AI()->DoAction(ACTION_POWER_SPARK_FOLLOW);
c->AI()->Talk(EMOTE_POWER_SPARK);
}
@@ -418,7 +410,7 @@ struct boss_malygos : public BossAI
bLockHealthCheck = true;
Talk(SAY_MAGIC_BLAST);
EntryCheckPredicate pred(NPC_POWER_SPARK);
summons.DoAction(2, pred); // stop following
summons.DoAction(ACTION_POWER_SPARK_STOP, pred);
me->SetUnitFlag(UNIT_FLAG_PACIFIED);
me->SendMeleeAttackStop(me->GetVictim());
@@ -452,52 +444,49 @@ struct boss_malygos : public BossAI
{
vp->SetDisableGravity(true);
Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
if (!PlayerList.IsEmpty())
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
if (Player* pPlayer = i->GetSource())
me->GetMap()->DoForAllPlayers([&](Player* pPlayer)
{
if (!pPlayer->IsAlive() || pPlayer->IsGameMaster())
return;
Position plrpos;
float playerAngle = CenterPos.GetAngle(pPlayer);
plrpos.m_positionX = CenterPos.GetPositionX() + cos(playerAngle) * 5.0f;
plrpos.m_positionY = CenterPos.GetPositionY() + std::sin(playerAngle) * 5.0f;
plrpos.m_positionZ = CenterPos.GetPositionZ() + 18.0f;
plrpos.SetOrientation(plrpos.GetAngle(&CenterPos));
if (Creature* c = me->SummonCreature(NPC_VORTEX, plrpos, TEMPSUMMON_TIMED_DESPAWN, 15000))
{
pPlayer->CastSpell(pPlayer, SPELL_FREEZE_ANIM, true);
pPlayer->CastSpell(c, SPELL_VORTEX_CONTROL_VEHICLE, true);
if (!pPlayer->GetVehicle()) // didn't work somehow, try again with a different way, if fails - break
{
if (!pPlayer->IsAlive() || pPlayer->IsGameMaster())
continue;
Position plrpos;
float playerAngle = CenterPos.GetAngle(pPlayer);
plrpos.m_positionX = CenterPos.GetPositionX() + cos(playerAngle) * 5.0f;
plrpos.m_positionY = CenterPos.GetPositionY() + std::sin(playerAngle) * 5.0f;
plrpos.m_positionZ = CenterPos.GetPositionZ() + 18.0f;
plrpos.SetOrientation(plrpos.GetAngle(&CenterPos));
if (Creature* c = me->SummonCreature(NPC_VORTEX, plrpos, TEMPSUMMON_TIMED_DESPAWN, 15000))
{
pPlayer->CastSpell(pPlayer, SPELL_FREEZE_ANIM, true);
pPlayer->CastSpell(c, SPELL_VORTEX_CONTROL_VEHICLE, true);
if (!pPlayer->GetVehicle()) // didn't work somehow, try again with a different way, if fails - break
{
pPlayer->EnterVehicle(c, 0);
if (!pPlayer->GetVehicle())
continue;
}
//pPlayer->ClearUnitState(UNIT_STATE_ONVEHICLE);
Movement::MoveSplineInit init(pPlayer); // TODO: has to be removed and handled with vehicle exit and vehicle enter code
init.MoveTo(CenterPos.GetPositionX(), CenterPos.GetPositionY(), CenterPos.GetPositionZ());
init.SetFacing(pPlayer->GetOrientation());
init.SetTransportExit();
init.Launch();
pPlayer->SetUnitMovementFlags(MOVEMENTFLAG_NONE);
pPlayer->SetDisableGravity(true);
WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);
data << pPlayer->GetPackGUID();
pPlayer->SendMessageToSet(&data, true);
sScriptMgr->AnticheatSetUnderACKmount(pPlayer);
pPlayer->SetGuidValue(PLAYER_FARSIGHT, vp->GetGUID());
c->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
pPlayer->EnterVehicle(c, 0);
if (!pPlayer->GetVehicle())
return;
}
//pPlayer->ClearUnitState(UNIT_STATE_ONVEHICLE);
Movement::MoveSplineInit init(pPlayer); // TODO: has to be removed and handled with vehicle exit and vehicle enter code
init.MoveTo(CenterPos.GetPositionX(), CenterPos.GetPositionY(), CenterPos.GetPositionZ());
init.SetFacing(pPlayer->GetOrientation());
init.SetTransportExit();
init.Launch();
pPlayer->SetUnitMovementFlags(MOVEMENTFLAG_NONE);
pPlayer->SetDisableGravity(true);
WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);
data << pPlayer->GetPackGUID();
pPlayer->SendMessageToSet(&data, true);
sScriptMgr->AnticheatSetUnderACKmount(pPlayer);
pPlayer->SetGuidValue(PLAYER_FARSIGHT, vp->GetGUID());
c->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
});
}
events.RescheduleEvent(EVENT_VORTEX_LAND_0, 11s, 1);
@@ -505,19 +494,14 @@ struct boss_malygos : public BossAI
}
case EVENT_VORTEX_LAND_0:
me->GetMotionMaster()->MovePoint(MI_POINT_VORTEX_LAND, CenterPos, FORCED_MOVEMENT_RUN, 0.f, true, true, AnimTier::Ground);
break;
case EVENT_VORTEX_LAND_1:
{
bLockHealthCheck = false;
EntryCheckPredicate pred(NPC_POWER_SPARK);
summons.DoAction(1, pred); // resume following
summons.DoAction(ACTION_POWER_SPARK_FOLLOW, pred);
me->RemoveUnitFlag(UNIT_FLAG_PACIFIED);
if (Unit* target = me->GetVictim())
{
AttackStart(target);
me->GetMotionMaster()->MoveChase(target);
}
me->ResumeChasingVictim();
events.RescheduleEvent(EVENT_START_VORTEX_0, 60s, 1);
break;
}
@@ -533,7 +517,6 @@ struct boss_malygos : public BossAI
events.CancelEventGroup(1); // don't cancel berserk (group 0)
break;
case EVENT_START_PHASE_2_FLY_UP:
{
me->SendMeleeAttackStop(me->GetVictim());
me->GetMotionMaster()->MoveIdle();
me->DisableSpline();
@@ -541,7 +524,6 @@ struct boss_malygos : public BossAI
me->GetMotionMaster()->MovePoint(MI_POINT_CENTER_AIR_PH_2, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 32.0f, FORCED_MOVEMENT_RUN, 0.f, 0.f, true, true, MOTION_SLOT_ACTIVE, AnimTier::Fly);
events.RescheduleEvent(EVENT_START_PHASE_2_MOVE_TO_SIDE, 22s + 500ms, 1);
break;
}
case EVENT_START_PHASE_2_MOVE_TO_SIDE:
Talk(SAY_PHASE_2);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED);
@@ -559,7 +541,7 @@ struct boss_malygos : public BossAI
if (Creature* c = me->SummonCreature(NPC_NEXUS_LORD, *disk, TEMPSUMMON_MANUAL_DESPAWN, 0))
{
c->EnterVehicle(disk, 0);
disk->AI()->DoAction(1); // start moving
disk->AI()->DoAction(ACTION_DISK_START_MOVING);
}
}
for (int i = 0; i < MAX_SCIONS_OF_ETERNITY; i++)
@@ -570,7 +552,7 @@ struct boss_malygos : public BossAI
if (Creature* c = me->SummonCreature(NPC_SCION_OF_ETERNITY, *disk, TEMPSUMMON_MANUAL_DESPAWN, 0))
{
c->EnterVehicle(disk, 0);
disk->AI()->DoAction(1); // start moving
disk->AI()->DoAction(ACTION_DISK_START_MOVING);
}
}
@@ -628,7 +610,6 @@ struct boss_malygos : public BossAI
me->SetTarget();
break;
case EVENT_CHECK_TRASH_DEAD:
{
if (me->FindNearestCreature(NPC_SCION_OF_ETERNITY, 250.0f, true) || me->FindNearestCreature(NPC_NEXUS_LORD, 250.0f, true))
events.Repeat(3s);
else
@@ -646,8 +627,7 @@ struct boss_malygos : public BossAI
events.RescheduleEvent(EVENT_LIGHT_DIMENSION_CHANGE, 1s, 1);
events.RescheduleEvent(EVENT_DESTROY_PLATFORM_0, 10s, 1);
}
}
break;
break;
case EVENT_LIGHT_DIMENSION_CHANGE:
me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_CHANGE_DIMENSIONS, 2s);
break;
@@ -687,6 +667,7 @@ struct boss_malygos : public BossAI
break;
case EVENT_START_PHASE_3:
events.SetPhase(PHASE_THREE);
SetInvincibility(false);
me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_OBSCURE_ARCANE_RUNES, 1s);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetUnitFlag(UNIT_FLAG_PACIFIED | UNIT_FLAG_DISABLE_MOVE);
@@ -800,18 +781,17 @@ struct boss_malygos : public BossAI
#define VORTEX_DEFAULT_DIFF 250
#define VORTEX_TRAVEL_TIME 3000
//#define VORTEX_RADIUS 25.0f
struct npc_vortex_ride : public VehicleAI
{
npc_vortex_ride(Creature* pCreature) : VehicleAI(pCreature)
{
VORTEX_RADIUS = urand(22, 28);
vortexRadius = urand(22, 28);
float h = urand(15, 30);
float angle = CenterPos.GetAngle(me);
Position pos;
pos.m_positionX = CenterPos.GetPositionX() + VORTEX_RADIUS * cos(angle);
pos.m_positionY = CenterPos.GetPositionY() + VORTEX_RADIUS * std::sin(angle);
pos.m_positionX = CenterPos.GetPositionX() + vortexRadius * cos(angle);
pos.m_positionY = CenterPos.GetPositionY() + vortexRadius * std::sin(angle);
pos.m_positionZ = CenterPos.GetPositionZ() + h;
pos.SetOrientation(pos.GetAngle(&CenterPos));
me->SetPosition(pos);
@@ -823,29 +803,26 @@ struct npc_vortex_ride : public VehicleAI
uint32 timer;
uint32 despawnTimer;
bool bUpdatedFlying;
float VORTEX_RADIUS;
float vortexRadius;
void PassengerBoarded(Unit* pass, int8 /*seat*/, bool apply) override
{
if (pass && !apply && pass->IsPlayer())
{
Player* plr = pass->ToPlayer();
float speed = plr->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1.0f * 0.001f);
plr->SetDisableGravity(false); // packet only would lead to issues elsewhere
plr->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), speed);
plr->RemoveAura(SPELL_FREEZE_ANIM);
plr->SetGuidValue(PLAYER_FARSIGHT, ObjectGuid::Empty);
if (!pass || apply || !pass->IsPlayer())
return;
sScriptMgr->AnticheatSetCanFlybyServer(plr, false);
sScriptMgr->AnticheatSetUnderACKmount(plr);
}
Player* plr = pass->ToPlayer();
float speed = plr->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1.0f * 0.001f);
plr->SetDisableGravity(false); // packet only would lead to issues elsewhere
plr->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), speed);
plr->RemoveAura(SPELL_FREEZE_ANIM);
plr->SetGuidValue(PLAYER_FARSIGHT, ObjectGuid::Empty);
sScriptMgr->AnticheatSetCanFlybyServer(plr, false);
sScriptMgr->AnticheatSetUnderACKmount(plr);
}
void UpdateAI(uint32 diff) override
{
/* here: if player has some aura that should make him exit vehicle (eg. ice block) -> exit
or make it another way (dunno how) */
if (despawnTimer <= diff)
{
despawnTimer = 0;
@@ -865,21 +842,23 @@ struct npc_vortex_ride : public VehicleAI
float newangle = angle + 2 * M_PI / ((float)VORTEX_TRAVEL_TIME / VORTEX_DEFAULT_DIFF);
if (newangle >= 2 * M_PI)
newangle -= 2 * M_PI;
float newx = CenterPos.GetPositionX() + VORTEX_RADIUS * cos(newangle);
float newy = CenterPos.GetPositionY() + VORTEX_RADIUS * std::sin(newangle);
float newx = CenterPos.GetPositionX() + vortexRadius * cos(newangle);
float newy = CenterPos.GetPositionY() + vortexRadius * std::sin(newangle);
float arcangle = me->GetAngle(newx, newy);
float dist = 2 * me->GetDistance2d(newx, newy);
if (me->GetVehicleKit()) if (Unit* pass = me->GetVehicleKit()->GetPassenger(0)) if (Player* plr = pass->ToPlayer())
{
if (!bUpdatedFlying && timer)
{
bUpdatedFlying = true;
plr->SetDisableGravity(true);
}
if (me->GetVehicleKit())
if (Unit* pass = me->GetVehicleKit()->GetPassenger(0))
if (Player* plr = pass->ToPlayer())
{
if (!bUpdatedFlying && timer)
{
bUpdatedFlying = true;
plr->SetDisableGravity(true);
}
plr->SendMonsterMove(me->GetPositionX() + dist * cos(arcangle), me->GetPositionY() + dist * std::sin(arcangle), me->GetPositionZ(), VORTEX_DEFAULT_DIFF * 2, SPLINEFLAG_FLYING);
me->Relocate(newx, newy);
}
plr->SendMonsterMove(me->GetPositionX() + dist * cos(arcangle), me->GetPositionY() + dist * std::sin(arcangle), me->GetPositionZ(), VORTEX_DEFAULT_DIFF * 2, SPLINEFLAG_FLYING);
me->Relocate(newx, newy);
}
timer = (diff - timer <= VORTEX_DEFAULT_DIFF) ? VORTEX_DEFAULT_DIFF - (diff - timer) : 0;
}
@@ -910,10 +889,10 @@ struct npc_power_spark : public NullCreatureAI
{
switch (param)
{
case 1:
case ACTION_POWER_SPARK_FOLLOW:
MoveTimer = 1;
break;
case 2:
case ACTION_POWER_SPARK_STOP:
MoveTimer = 0;
me->GetMotionMaster()->MoveIdle();
me->DisableSpline();
@@ -924,21 +903,21 @@ struct npc_power_spark : public NullCreatureAI
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (damage >= me->GetHealth())
{
damage = 0;
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
{
MoveTimer = 0;
me->GetMotionMaster()->MoveIdle();
me->DisableSpline();
me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), CenterPos.GetPositionZ(), FORCED_MOVEMENT_NONE, 100.0f);
me->ReplaceAllUnitFlags(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
me->RemoveAura(SPELL_POWER_SPARK_VISUAL);
me->CastSpell(me, SPELL_POWER_SPARK_GROUND_BUFF, true);
me->DespawnOrUnsummon(60s);
}
}
if (damage < me->GetHealth())
return;
damage = 0;
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
return;
MoveTimer = 0;
me->GetMotionMaster()->MoveIdle();
me->DisableSpline();
me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), CenterPos.GetPositionZ(), FORCED_MOVEMENT_NONE, 100.0f);
me->ReplaceAllUnitFlags(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
me->RemoveAura(SPELL_POWER_SPARK_VISUAL);
me->CastSpell(me, SPELL_POWER_SPARK_GROUND_BUFF, true);
me->DespawnOrUnsummon(60s);
}
void UpdateAI(uint32 diff) override
@@ -981,22 +960,24 @@ struct npc_nexus_lord : public ScriptedAI
npc_nexus_lord(Creature* pCreature) : ScriptedAI(pCreature)
{
me->SetReactState(REACT_PASSIVE);
pInstance = me->GetInstanceScript();
timer = 0;
events.Reset();
events.RescheduleEvent(EVENT_TELEPORT_VISUAL, 0ms);
me->CastSpell(me, SPELL_TELEPORT_VISUAL, true);
}
InstanceScript* pInstance;
EventMap events;
uint16 timer;
void JustEngagedWith(Unit* /*who*/) override
{
DoZoneInCombat();
events.Reset();
events.RescheduleEvent(EVENT_NEXUS_LORD_ARCANE_SHOCK, 3s, 10s);
events.RescheduleEvent(EVENT_NEXUS_LORD_HASTE, 8s, 14s);
ScheduleTimedEvent(3s, 10s, [&]
{
if (Unit* victim = me->GetVictim())
me->CastSpell(victim, SPELL_ARCANE_SHOCK);
}, 10s, 15s);
ScheduleTimedEvent(8s, 14s, [&]
{
me->CastSpell(me, SPELL_HASTE);
}, 20s, 30s);
}
void AttackStart(Unit* victim) override
@@ -1025,28 +1006,10 @@ struct npc_nexus_lord : public ScriptedAI
timer -= diff;
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
scheduler.Update(diff, [this]
{
case 0:
break;
case EVENT_TELEPORT_VISUAL:
me->CastSpell(me, SPELL_TELEPORT_VISUAL, true);
break;
case EVENT_NEXUS_LORD_ARCANE_SHOCK:
if (Unit* victim = me->GetVictim())
me->CastSpell(victim, SPELL_ARCANE_SHOCK);
events.Repeat(10s, 15s);
break;
case EVENT_NEXUS_LORD_HASTE:
me->CastSpell(me, SPELL_HASTE);
events.Repeat(20s, 30s);
break;
}
return me->HasUnitState(UNIT_STATE_CASTING);
});
DoMeleeAttackIfReady();
}
@@ -1063,53 +1026,27 @@ struct npc_scion_of_eternity : public ScriptedAI
npc_scion_of_eternity(Creature* pCreature) : ScriptedAI(pCreature)
{
me->SetReactState(REACT_PASSIVE);
pInstance = me->GetInstanceScript();
events.Reset();
events.RescheduleEvent(EVENT_TELEPORT_VISUAL, 0ms);
events.RescheduleEvent(EVENT_SCION_OF_ETERNITY_ARCANE_BARRAGE, 20s, 25s);
}
InstanceScript* pInstance;
EventMap events;
void UpdateAI(uint32 diff) override
{
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case 0:
break;
case EVENT_TELEPORT_VISUAL:
me->CastSpell(me, SPELL_TELEPORT_VISUAL, true);
break;
case EVENT_SCION_OF_ETERNITY_ARCANE_BARRAGE:
me->CastSpell(me, SPELL_TELEPORT_VISUAL, true);
ScheduleTimedEvent(20s, 25s, [&]
{
GuidVector guids;
Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
if (!PlayerList.IsEmpty())
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
if (Player* pPlayer = i->GetSource())
{
if (pPlayer->IsAlive())
{
if (!pPlayer->GetVehicle())
{
guids.push_back(pPlayer->GetGUID());
}
}
}
me->GetMap()->DoForAllPlayers([&](Player* pPlayer)
{
if (pPlayer->IsAlive() && !pPlayer->GetVehicle())
guids.push_back(pPlayer->GetGUID());
});
if (!guids.empty())
if (Player* plr = ObjectAccessor::GetPlayer(*me, guids.at(urand(0, guids.size() - 1))))
me->CastSpell(plr, SPELL_SCION_ARCANE_BARRAGE);
}, 5s, 8s);
}
events.Repeat(5s, 8s);
}
break;
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff, [this]
{
return me->HasUnitState(UNIT_STATE_CASTING);
});
}
void JustDied(Unit* killer) override
@@ -1130,11 +1067,9 @@ struct npc_hover_disk : public VehicleAI
{
npc_hover_disk(Creature* pCreature) : VehicleAI(pCreature)
{
pInstance = me->GetInstanceScript();
events.Reset();
}
InstanceScript* pInstance;
EventMap events;
void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) override
@@ -1209,7 +1144,7 @@ struct npc_hover_disk : public VehicleAI
{
switch (param)
{
case 1: // move to next point
case ACTION_DISK_START_MOVING:
if (Vehicle* v = me->GetVehicleKit())
if (Unit* pass = v->GetPassenger(0))
switch (pass->GetEntry())
@@ -1248,7 +1183,7 @@ struct npc_hover_disk : public VehicleAI
case 0:
break;
case EVENT_DISK_MOVE_NEXT_POINT:
DoAction(1);
DoAction(ACTION_DISK_START_MOVING);
break;
}
}
@@ -1261,48 +1196,37 @@ struct npc_alexstrasza : public ScriptedAI
{
npc_alexstrasza(Creature* pCreature) : ScriptedAI(pCreature)
{
events.Reset();
events.ScheduleEvent(1, 9s);
me->SetCanFly(true);
me->SetDisableGravity(true);
}
EventMap events;
ScheduleUniqueTimedEvent(9s, [&]
{
me->CastSpell(AlexstraszaGiftPos.GetPositionX(), AlexstraszaGiftPos.GetPositionY(), AlexstraszaGiftPos.GetPositionZ(), SPELL_ALEXSTRASZA_GIFT, true);
if (GameObject* chest = me->SummonGameObject(ALEXSTRASZA_GIFT, AlexstraszaGiftPos.GetPositionX(), AlexstraszaGiftPos.GetPositionY(), AlexstraszaGiftPos.GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
chest->SetLootRecipient(me->GetMap());
if (GameObject* heart = me->SummonGameObject(HEART_OF_MAGIC, HeartOfMagicPos.GetPositionX(), HeartOfMagicPos.GetPositionY(), HeartOfMagicPos.GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
heart->SetLootRecipient(me->GetMap());
Talk(SAY_ALEXSTRASZA_ONE);
ScheduleUniqueTimedEvent(6s, [&]
{
Talk(SAY_ALEXSTRASZA_TWO);
ScheduleUniqueTimedEvent(5s, [&]
{
Talk(SAY_ALEXSTRASZA_THREE);
ScheduleUniqueTimedEvent(22s, [&]
{
Talk(SAY_ALEXSTRASZA_FOUR);
}, EVENT_ALEXSTRASZA_SAY_FOUR);
}, EVENT_ALEXSTRASZA_SAY_THREE);
}, EVENT_ALEXSTRASZA_SAY_TWO);
}, EVENT_ALEXSTRASZA_GIFT);
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
switch (events.ExecuteEvent())
{
case 0:
break;
case 1:
me->CastSpell(773.98f, 1285.97f, 266.254f, SPELL_ALEXSTRASZA_GIFT, true);
if (GameObject* chest = me->SummonGameObject(ALEXSTRASZA_GIFT, 773.98f, 1285.97f, 266.254f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
{
chest->SetLootRecipient(me->GetMap());
}
if (GameObject* heart = me->SummonGameObject(HEART_OF_MAGIC, 773.98f, 1275.97f, 266.254f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
{
heart->SetLootRecipient(me->GetMap());
}
Talk(SAY_ALEXSTRASZA_ONE);
events.RescheduleEvent(2, 6s);
break;
case 2:
Talk(SAY_ALEXSTRASZA_TWO);
events.RescheduleEvent(3, 5s);
break;
case 3:
Talk(SAY_ALEXSTRASZA_THREE);
events.RescheduleEvent(4, 22s);
break;
case 4:
Talk(SAY_ALEXSTRASZA_FOUR);
break;
}
scheduler.Update(diff);
}
void MoveInLineOfSight(Unit* /*who*/) override {}
@@ -1315,14 +1239,14 @@ struct npc_eoe_wyrmrest_skytalon : public VehicleAI
void IsSummonedBy(WorldObject* summoner) override
{
if (summoner && summoner->IsPlayer())
{
ObjectGuid summonerGUID = summoner->GetGUID();
me->m_Events.AddEventAtOffset([summonerGUID, this] {
if (Player* rider = ObjectAccessor::GetPlayer(*me, summonerGUID))
DoCast(rider, SPELL_RIDE_RED_DRAGON, true);
}, 2s);
}
if (!summoner || !summoner->IsPlayer())
return;
ObjectGuid summonerGUID = summoner->GetGUID();
me->m_Events.AddEventAtOffset([summonerGUID, this] {
if (Player* rider = ObjectAccessor::GetPlayer(*me, summonerGUID))
DoCast(rider, SPELL_RIDE_RED_DRAGON, true);
}, 2s);
}
void PassengerBoarded(Unit* pass, int8 /*seat*/, bool apply) override
@@ -1346,17 +1270,13 @@ struct npc_eoe_wyrmrest_skytalon : public VehicleAI
}
};
class go_the_focusing_iris : public GameObjectScript
struct go_the_focusing_iris : public GameObjectAI
{
public:
go_the_focusing_iris() : GameObjectScript("go_the_focusing_iris") { }
go_the_focusing_iris(GameObject* go) : GameObjectAI(go) { }
bool OnGossipHello(Player* user, GameObject* go) override
bool GossipHello(Player* /*user*/, bool /*reportUse*/) override
{
if (!user || !go)
return true;
if (InstanceScript* pInstance = go->GetInstanceScript())
if (InstanceScript* pInstance = me->GetInstanceScript())
pInstance->SetData(DATA_IRIS_ACTIVATED, 0);
return true;
@@ -1455,7 +1375,7 @@ void AddSC_boss_malygos()
RegisterEoECreatureAI(npc_power_spark);
RegisterEoECreatureAI(npc_vortex_ride);
RegisterEoECreatureAI(npc_alexstrasza);
new go_the_focusing_iris();
RegisterGameObjectAI(go_the_focusing_iris);
RegisterEoECreatureAI(npc_nexus_lord);
RegisterEoECreatureAI(npc_scion_of_eternity);
RegisterEoECreatureAI(npc_hover_disk);

View File

@@ -18,7 +18,6 @@
#ifndef DEF_EYE_OF_ETERNITY_H
#define DEF_EYE_OF_ETERNITY_H
#include "Chat.h"
#include "CreatureAIImpl.h"
#define DataHeader "EOE"
@@ -91,13 +90,29 @@ enum eAchiev
enum EoEMisc : uint32
{
EVENT_IRIS_ACTIVATED = 20158
AREA_EYE_OF_ETERNITY = 4500,
EVENT_IRIS_ACTIVATED = 20158,
PLATFORM_DESTROY_DAMAGE = 6500000,
INTRO_MOVEMENT_INTERVAL = 25000,
};
enum EoEActions
{
ACTION_POWER_SPARK_FOLLOW = 1,
ACTION_POWER_SPARK_STOP = 2,
ACTION_DISK_START_MOVING = 1,
};
enum AlexstraszaEvents
{
EVENT_ALEXSTRASZA_GIFT = 1,
EVENT_ALEXSTRASZA_SAY_TWO = 2,
EVENT_ALEXSTRASZA_SAY_THREE = 3,
EVENT_ALEXSTRASZA_SAY_FOUR = 4,
};
/*** POSITIONS/WAYPOINTS BELOW ***/
#define INTRO_MOVEMENT_INTERVAL 25000
const Position CenterPos = {754.395f, 1301.27f, 266.10f, 0.0f};
const Position FourSidesPos[] =
@@ -110,6 +125,9 @@ const Position FourSidesPos[] =
const Position Phase2NorthPos = {837.22f, 1301.676f, 296.10f, M_PI};
const Position AlexstraszaGiftPos = {773.98f, 1285.97f, 266.254f, 0.0f};
const Position HeartOfMagicPos = {773.98f, 1275.97f, 266.254f, 0.0f};
const uint32 MalygosIntroIntervals[] = {18000, 19000, 21000, 18000, 15000};
template <class AI, class T>

View File

@@ -21,193 +21,178 @@
#include "Vehicle.h"
#include "eye_of_eternity.h"
class instance_eye_of_eternity : public InstanceMapScript
struct instance_eye_of_eternity : public InstanceScript
{
public:
instance_eye_of_eternity() : InstanceMapScript("instance_eye_of_eternity", MAP_THE_EYE_OF_ETERNITY) { }
instance_eye_of_eternity(Map* pMap) : InstanceScript(pMap) { Initialize(); }
struct instance_eye_of_eternity_InstanceMapScript : public InstanceScript
ObjectGuid NPC_MalygosGUID;
ObjectGuid GO_IrisGUID;
ObjectGuid GO_ExitPortalGUID;
ObjectGuid GO_PlatformGUID;
bool bPokeAchiev;
void Initialize() override
{
instance_eye_of_eternity_InstanceMapScript(Map* pMap) : InstanceScript(pMap) { Initialize(); }
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
bPokeAchiev = false;
}
ObjectGuid NPC_MalygosGUID;
ObjectGuid GO_IrisGUID;
ObjectGuid GO_ExitPortalGUID;
ObjectGuid GO_PlatformGUID;
bool bPokeAchiev;
void OnPlayerEnter(Player* player) override
{
if (GetBossState(DATA_MALYGOS) != DONE)
return;
void Initialize() override
ProcessEvent(nullptr, EVENT_IRIS_ACTIVATED);
if (GameObject* go = instance->GetGameObject(GO_IrisGUID))
if (go->GetPhaseMask() != 2)
go->SetPhaseMask(2, true);
if (player && player->IsAlive())
player->CastSpell(player, SPELL_SUMMON_RED_DRAGON_BUDDY, true);
}
void OnCreatureCreate(Creature* creature) override
{
switch (creature->GetEntry())
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
bPokeAchiev = false;
case NPC_MALYGOS:
NPC_MalygosGUID = creature->GetGUID();
break;
}
}
void OnPlayerEnter(Player* player) override
void OnGameObjectCreate(GameObject* go) override
{
switch (go->GetEntry())
{
if (GetBossState(DATA_MALYGOS) == DONE)
{
// destroy platform, hide iris (actually ensure, done at loading, but doesn't always work
ProcessEvent(nullptr, EVENT_IRIS_ACTIVATED);
if (GameObject* go = instance->GetGameObject(GO_IrisGUID))
if (go->GetPhaseMask() != 2)
go->SetPhaseMask(2, true);
// no floor, so put players on drakes
if (player && player->IsAlive())
player->CastSpell(player, SPELL_SUMMON_RED_DRAGON_BUDDY, true);
}
}
void OnCreatureCreate(Creature* creature) override
{
switch (creature->GetEntry())
{
case NPC_MALYGOS:
NPC_MalygosGUID = creature->GetGUID();
break;
}
}
void OnGameObjectCreate(GameObject* go) override
{
switch (go->GetEntry())
{
case GO_IRIS_N:
case GO_IRIS_H:
GO_IrisGUID = go->GetGUID();
if (GetBossState(DATA_MALYGOS) == DONE)
go->SetPhaseMask(2, true);
break;
case GO_EXIT_PORTAL:
GO_ExitPortalGUID = go->GetGUID();
break;
case GO_NEXUS_PLATFORM:
GO_PlatformGUID = go->GetGUID();
if (GetBossState(DATA_MALYGOS) == DONE)
{
go->ModifyHealth(-6500000); // We have HP 6 million in the database... So we have to do at least that
go->EnableCollision(false);
}
break;
}
}
void SetData(uint32 type, uint32 /*data*/) override
{
switch (type)
{
case DATA_IRIS_ACTIVATED:
if (GetBossState(DATA_MALYGOS) == NOT_STARTED)
if (Creature* c = instance->GetCreature(NPC_MalygosGUID))
if (Player* plr = c->SelectNearestPlayer(250.0f))
c->AI()->AttackStart(plr);
break;
case DATA_SET_IRIS_INACTIVE:
if (GameObject* go = instance->GetGameObject(GO_IrisGUID))
{
HandleGameObject(GO_IrisGUID, true, go);
if (Creature* c = go->SummonCreature(NPC_WORLD_TRIGGER_LAOI, *go, TEMPSUMMON_TIMED_DESPAWN, 10000))
c->CastSpell(c, SPELL_IRIS_ACTIVATED, true);
}
break;
case DATA_HIDE_IRIS_AND_PORTAL:
if (GameObject* go = instance->GetGameObject(GO_IrisGUID))
go->SetPhaseMask(2, true);
if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID))
go->SetPhaseMask(2, true);
break;
}
}
bool SetBossState(uint32 type, EncounterState state) override
{
if (!InstanceScript::SetBossState(type, state))
return false;
if (type == DATA_MALYGOS)
{
switch (state)
case GO_IRIS_N:
case GO_IRIS_H:
GO_IrisGUID = go->GetGUID();
if (GetBossState(DATA_MALYGOS) == DONE)
go->SetPhaseMask(2, true);
break;
case GO_EXIT_PORTAL:
GO_ExitPortalGUID = go->GetGUID();
break;
case GO_NEXUS_PLATFORM:
GO_PlatformGUID = go->GetGUID();
if (GetBossState(DATA_MALYGOS) == DONE)
{
case NOT_STARTED:
bPokeAchiev = false;
if (GameObject* go = instance->GetGameObject(GO_IrisGUID))
{
go->SetPhaseMask(1, true);
HandleGameObject(GO_IrisGUID, false, go);
}
if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID))
go->SetPhaseMask(1, true);
if (GameObject* go = instance->GetGameObject(GO_PlatformGUID))
{
go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true);
go->EnableCollision(true);
}
break;
case IN_PROGRESS:
bPokeAchiev = (instance->GetPlayersCountExceptGMs() < (instance->GetSpawnMode() == 0 ? (uint32)9 : (uint32)21));
break;
case DONE:
bPokeAchiev = false;
if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID))
go->SetPhaseMask(1, true);
if (Creature* c = instance->GetCreature(NPC_MalygosGUID))
if (c->SummonCreature(NPC_ALEXSTRASZA, 798.0f, 1268.0f, 299.0f, 2.45f, TEMPSUMMON_TIMED_DESPAWN, 604800000))
break;
break;
default:
break;
go->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE));
go->EnableCollision(false);
}
}
return true;
break;
}
}
ObjectGuid GetGuidData(uint32 type) const override
{
switch (type)
{
case DATA_MALYGOS_GUID:
return NPC_MalygosGUID;
}
return ObjectGuid::Empty;
}
void ProcessEvent(WorldObject* /*unit*/, uint32 eventId) override
{
if (eventId == EVENT_IRIS_ACTIVATED)
if (GameObject* go = instance->GetGameObject(GO_PlatformGUID))
if (Creature* c = instance->GetCreature(NPC_MalygosGUID))
{
go->ModifyHealth(-6500000, c); // We have HP 6 million in the database... So we have to do at least that
go->EnableCollision(false);
}
}
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override
{
switch (criteria_id)
{
case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_10:
case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_25:
return bPokeAchiev;
case ACHIEV_CRITERIA_DENYIN_THE_SCION_10:
case ACHIEV_CRITERIA_DENYIN_THE_SCION_25:
return (source && source->GetVehicle() && source->GetVehicle()->GetVehicleInfo()->m_ID == 224);
}
return false;
}
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
void SetData(uint32 type, uint32 /*data*/) override
{
return new instance_eye_of_eternity_InstanceMapScript(map);
switch (type)
{
case DATA_IRIS_ACTIVATED:
if (GetBossState(DATA_MALYGOS) == NOT_STARTED)
if (Creature* c = instance->GetCreature(NPC_MalygosGUID))
if (Player* plr = c->SelectNearestPlayer(250.0f))
c->AI()->AttackStart(plr);
break;
case DATA_SET_IRIS_INACTIVE:
if (GameObject* go = instance->GetGameObject(GO_IrisGUID))
{
HandleGameObject(GO_IrisGUID, true, go);
if (Creature* c = go->SummonCreature(NPC_WORLD_TRIGGER_LAOI, *go, TEMPSUMMON_TIMED_DESPAWN, 10000))
c->CastSpell(c, SPELL_IRIS_ACTIVATED, true);
}
break;
case DATA_HIDE_IRIS_AND_PORTAL:
if (GameObject* go = instance->GetGameObject(GO_IrisGUID))
go->SetPhaseMask(2, true);
if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID))
go->SetPhaseMask(2, true);
break;
}
}
bool SetBossState(uint32 type, EncounterState state) override
{
if (!InstanceScript::SetBossState(type, state))
return false;
if (type == DATA_MALYGOS)
{
switch (state)
{
case NOT_STARTED:
bPokeAchiev = false;
if (GameObject* go = instance->GetGameObject(GO_IrisGUID))
{
go->SetPhaseMask(1, true);
HandleGameObject(GO_IrisGUID, false, go);
}
if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID))
go->SetPhaseMask(1, true);
if (GameObject* go = instance->GetGameObject(GO_PlatformGUID))
{
go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true);
go->EnableCollision(true);
}
break;
case IN_PROGRESS:
bPokeAchiev = (instance->GetPlayersCountExceptGMs() < (instance->GetSpawnMode() == 0 ? (uint32)9 : (uint32)21));
break;
case DONE:
bPokeAchiev = false;
if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID))
go->SetPhaseMask(1, true);
if (Creature* c = instance->GetCreature(NPC_MalygosGUID))
c->SummonCreature(NPC_ALEXSTRASZA, 798.0f, 1268.0f, 299.0f, 2.45f, TEMPSUMMON_MANUAL_DESPAWN);
break;
default:
break;
}
}
return true;
}
ObjectGuid GetGuidData(uint32 type) const override
{
switch (type)
{
case DATA_MALYGOS_GUID:
return NPC_MalygosGUID;
}
return ObjectGuid::Empty;
}
void ProcessEvent(WorldObject* /*unit*/, uint32 eventId) override
{
if (eventId == EVENT_IRIS_ACTIVATED)
if (GameObject* go = instance->GetGameObject(GO_PlatformGUID))
if (Creature* c = instance->GetCreature(NPC_MalygosGUID))
{
go->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE), c);
go->EnableCollision(false);
}
}
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override
{
switch (criteria_id)
{
case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_10:
case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_25:
return bPokeAchiev;
case ACHIEV_CRITERIA_DENYIN_THE_SCION_10:
case ACHIEV_CRITERIA_DENYIN_THE_SCION_25:
return source && source->GetVehicle() && source->GetVehicle()->GetVehicleInfo()->m_ID == 224;
}
return false;
}
};
void AddSC_instance_eye_of_eternity()
{
new instance_eye_of_eternity();
RegisterInstanceScript(instance_eye_of_eternity, MAP_THE_EYE_OF_ETERNITY);
}