mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-27 22:16:11 +00:00
refactor(Scripts/EoE): Modernize scripts (#24634)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user