mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Scripts/TK: Update remaining scripts to new register model 2 (#27768)
(cherry picked from commit 93735ae3bd)
This commit is contained in:
@@ -104,483 +104,449 @@ uint32 const flameQuillsSpells[] =
|
||||
34316
|
||||
};
|
||||
|
||||
class boss_alar : public CreatureScript
|
||||
struct boss_alar : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_alar() : CreatureScript("boss_alar") { }
|
||||
boss_alar(Creature* creature) : BossAI(creature, DATA_ALAR)
|
||||
{
|
||||
Initialize();
|
||||
DefaultMoveSpeedRate = creature->GetSpeedRate(MOVE_RUN);
|
||||
DiveBomb_Timer = 0;
|
||||
MeltArmor_Timer = 0;
|
||||
Charge_Timer = 0;
|
||||
FlamePatch_Timer = 0;
|
||||
}
|
||||
|
||||
struct boss_alarAI : public BossAI
|
||||
void Initialize()
|
||||
{
|
||||
Berserk_Timer = 1200000;
|
||||
Platforms_Move_Timer = 0;
|
||||
|
||||
Phase1 = true;
|
||||
WaitEvent = WE_NONE;
|
||||
WaitTimer = 0;
|
||||
AfterMoving = false;
|
||||
ForceMove = false;
|
||||
ForceTimer = 5000;
|
||||
|
||||
cur_wp = 4;
|
||||
}
|
||||
|
||||
WaitEventType WaitEvent;
|
||||
uint32 WaitTimer;
|
||||
|
||||
bool AfterMoving;
|
||||
|
||||
uint32 Platforms_Move_Timer;
|
||||
uint32 DiveBomb_Timer;
|
||||
uint32 MeltArmor_Timer;
|
||||
uint32 Charge_Timer;
|
||||
uint32 FlamePatch_Timer;
|
||||
uint32 Berserk_Timer;
|
||||
|
||||
float DefaultMoveSpeedRate;
|
||||
|
||||
bool Phase1;
|
||||
bool ForceMove;
|
||||
uint32 ForceTimer;
|
||||
|
||||
int8 cur_wp;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
_Reset();
|
||||
|
||||
me->SetDisplayId(me->GetNativeDisplayId());
|
||||
me->SetSpeedRate(MOVE_RUN, DefaultMoveSpeedRate);
|
||||
//me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10);
|
||||
//me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10);
|
||||
me->SetDisableGravity(true);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
me->SetDisableGravity(true); // after enterevademode will be set walk movement
|
||||
me->setActive(true);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (summon->GetEntry() == CREATURE_EMBER_OF_ALAR)
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
summon->AI()->AttackStart(target);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
if (Phase1)
|
||||
AttackStartNoMove(who);
|
||||
else
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*killer*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && Phase1)
|
||||
{
|
||||
boss_alarAI(Creature* creature) : BossAI(creature, DATA_ALAR)
|
||||
damage = 0;
|
||||
if (!WaitEvent)
|
||||
{
|
||||
Initialize();
|
||||
DefaultMoveSpeedRate = creature->GetSpeedRate(MOVE_RUN);
|
||||
DiveBomb_Timer = 0;
|
||||
MeltArmor_Timer = 0;
|
||||
Charge_Timer = 0;
|
||||
FlamePatch_Timer = 0;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
Berserk_Timer = 1200000;
|
||||
Platforms_Move_Timer = 0;
|
||||
|
||||
Phase1 = true;
|
||||
WaitEvent = WE_NONE;
|
||||
WaitEvent = WE_DIE;
|
||||
WaitTimer = 0;
|
||||
AfterMoving = false;
|
||||
ForceMove = false;
|
||||
me->SetHealth(0);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
me->RemoveAllAuras();
|
||||
me->AddUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->AttackStop();
|
||||
me->SetTarget(ObjectGuid::Empty);
|
||||
me->SetSpeedRate(MOVE_RUN, 5.0f);
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MovePoint(0, waypoint[5][0], waypoint[5][1], waypoint[5][2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_DIVE_BOMB_VISUAL)
|
||||
{
|
||||
me->SetDisplayId(11686);
|
||||
//me->SendUpdateObjectToAllExcept(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 /*id*/) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE)
|
||||
{
|
||||
WaitTimer = 1;
|
||||
AfterMoving = true;
|
||||
ForceMove = false;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsEngaged())
|
||||
return;
|
||||
|
||||
if (Berserk_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_BERSERK, true);
|
||||
Berserk_Timer = 60000;
|
||||
}
|
||||
else
|
||||
Berserk_Timer -= diff;
|
||||
|
||||
if (ForceMove)
|
||||
{
|
||||
if (ForceTimer <= diff)
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]);
|
||||
ForceTimer = 5000;
|
||||
|
||||
cur_wp = 4;
|
||||
}
|
||||
else
|
||||
ForceTimer -= diff;
|
||||
|
||||
WaitEventType WaitEvent;
|
||||
uint32 WaitTimer;
|
||||
|
||||
bool AfterMoving;
|
||||
|
||||
uint32 Platforms_Move_Timer;
|
||||
uint32 DiveBomb_Timer;
|
||||
uint32 MeltArmor_Timer;
|
||||
uint32 Charge_Timer;
|
||||
uint32 FlamePatch_Timer;
|
||||
uint32 Berserk_Timer;
|
||||
|
||||
float DefaultMoveSpeedRate;
|
||||
|
||||
bool Phase1;
|
||||
bool ForceMove;
|
||||
uint32 ForceTimer;
|
||||
|
||||
int8 cur_wp;
|
||||
|
||||
void Reset() override
|
||||
}
|
||||
if (WaitEvent)
|
||||
{
|
||||
if (WaitTimer)
|
||||
{
|
||||
Initialize();
|
||||
_Reset();
|
||||
|
||||
me->SetDisplayId(me->GetNativeDisplayId());
|
||||
me->SetSpeedRate(MOVE_RUN, DefaultMoveSpeedRate);
|
||||
//me->SetBoundingRadius(10);
|
||||
//me->SetCombatReach(10);
|
||||
me->SetDisableGravity(true);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
me->SetDisableGravity(true); // after enterevademode will be set walk movement
|
||||
me->setActive(true);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (summon->GetEntry() == CREATURE_EMBER_OF_ALAR)
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
summon->AI()->AttackStart(target);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
if (Phase1)
|
||||
AttackStartNoMove(who);
|
||||
else
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*killer*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && Phase1)
|
||||
if (WaitTimer <= diff)
|
||||
{
|
||||
damage = 0;
|
||||
if (!WaitEvent)
|
||||
if (AfterMoving)
|
||||
{
|
||||
WaitEvent = WE_DIE;
|
||||
WaitTimer = 0;
|
||||
me->SetHealth(0);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
me->RemoveAllAuras();
|
||||
me->AddUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->AttackStop();
|
||||
me->SetTarget(ObjectGuid::Empty);
|
||||
me->SetSpeedRate(MOVE_RUN, 5.0f);
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MovePoint(0, waypoint[5][0], waypoint[5][1], waypoint[5][2]);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
AfterMoving = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_DIVE_BOMB_VISUAL)
|
||||
{
|
||||
me->SetDisplayId(11686);
|
||||
//me->SendUpdateObjectToAllExcept(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 /*id*/) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE)
|
||||
{
|
||||
WaitTimer = 1;
|
||||
AfterMoving = true;
|
||||
ForceMove = false;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsEngaged())
|
||||
return;
|
||||
|
||||
if (Berserk_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_BERSERK, true);
|
||||
Berserk_Timer = 60000;
|
||||
}
|
||||
else
|
||||
Berserk_Timer -= diff;
|
||||
|
||||
if (ForceMove)
|
||||
{
|
||||
if (ForceTimer <= diff)
|
||||
switch (WaitEvent)
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]);
|
||||
ForceTimer = 5000;
|
||||
}
|
||||
else
|
||||
ForceTimer -= diff;
|
||||
|
||||
}
|
||||
if (WaitEvent)
|
||||
{
|
||||
if (WaitTimer)
|
||||
{
|
||||
if (WaitTimer <= diff)
|
||||
{
|
||||
if (AfterMoving)
|
||||
{
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
AfterMoving = false;
|
||||
}
|
||||
|
||||
switch (WaitEvent)
|
||||
{
|
||||
case WE_PLATFORM:
|
||||
Platforms_Move_Timer = 30000 + rand32() % 5000;
|
||||
break;
|
||||
case WE_QUILL:
|
||||
DoCast(me, SPELL_FLAME_QUILLS, true);
|
||||
Platforms_Move_Timer = 1;
|
||||
WaitTimer = 10000;
|
||||
WaitEvent = WE_DUMMY;
|
||||
return;
|
||||
case WE_DIE:
|
||||
ForceMove = false;
|
||||
me->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
WaitTimer = 5000;
|
||||
WaitEvent = WE_REVIVE;
|
||||
return;
|
||||
case WE_REVIVE:
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->SetFullHealth();
|
||||
me->SetSpeedRate(MOVE_RUN, DefaultMoveSpeedRate);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
DoZoneInCombat();
|
||||
DoCast(me, SPELL_REBIRTH, true);
|
||||
MeltArmor_Timer = 60000;
|
||||
Charge_Timer = 7000;
|
||||
DiveBomb_Timer = 40000 + rand32() % 5000;
|
||||
FlamePatch_Timer = 30000;
|
||||
Phase1 = false;
|
||||
break;
|
||||
case WE_METEOR:
|
||||
DoCast(me, SPELL_DIVE_BOMB_VISUAL, false);
|
||||
WaitEvent = WE_DIVE;
|
||||
WaitTimer = 4000;
|
||||
return;
|
||||
case WE_DIVE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_DIVE_BOMB_VISUAL);
|
||||
DoCast(target, SPELL_DIVE_BOMB, true);
|
||||
float dist = 3.0f;
|
||||
if (me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f))
|
||||
dist = 5.0f;
|
||||
WaitTimer = 1000 + uint32(floor(dist / 80 * 1000.0f));
|
||||
me->UpdatePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f);
|
||||
me->StopMoving();
|
||||
WaitEvent = WE_LAND;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
case WE_LAND:
|
||||
WaitEvent = WE_SUMMON;
|
||||
WaitTimer = 2000;
|
||||
return;
|
||||
case WE_SUMMON:
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SetBoundingRadius(10);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetDisplayId(me->GetNativeDisplayId());
|
||||
DoCast(me, SPELL_REBIRTH_2, true);
|
||||
break;
|
||||
case WE_DUMMY:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
WaitEvent = WE_NONE;
|
||||
WaitTimer = 0;
|
||||
}
|
||||
else
|
||||
WaitTimer -= diff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Phase1)
|
||||
{
|
||||
if (!me->IsThreatened())
|
||||
{
|
||||
EnterEvadeMode();
|
||||
case WE_PLATFORM:
|
||||
Platforms_Move_Timer = 30000 + rand32() % 5000;
|
||||
break;
|
||||
case WE_QUILL:
|
||||
DoCast(me, SPELL_FLAME_QUILLS, true);
|
||||
Platforms_Move_Timer = 1;
|
||||
WaitTimer = 10000;
|
||||
WaitEvent = WE_DUMMY;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Platforms_Move_Timer <= diff)
|
||||
{
|
||||
if (cur_wp == 4)
|
||||
{
|
||||
cur_wp = 0;
|
||||
WaitEvent = WE_PLATFORM;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (urand(0, 4)) // next platform
|
||||
{
|
||||
DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
if (cur_wp == 3)
|
||||
cur_wp = 0;
|
||||
else
|
||||
++cur_wp;
|
||||
WaitEvent = WE_PLATFORM;
|
||||
}
|
||||
else // flame quill
|
||||
{
|
||||
cur_wp = 4;
|
||||
WaitEvent = WE_QUILL;
|
||||
}
|
||||
}
|
||||
ForceMove = true;
|
||||
ForceTimer = 5000;
|
||||
me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]);
|
||||
WaitTimer = 0;
|
||||
case WE_DIE:
|
||||
ForceMove = false;
|
||||
me->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
WaitTimer = 5000;
|
||||
WaitEvent = WE_REVIVE;
|
||||
return;
|
||||
}
|
||||
else
|
||||
Platforms_Move_Timer -= diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Charge_Timer <= diff)
|
||||
{
|
||||
Unit* target= SelectTarget(SelectTargetMethod::Random, 1, 100, true);
|
||||
if (target)
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
Charge_Timer = 30000;
|
||||
}
|
||||
else
|
||||
Charge_Timer -= diff;
|
||||
|
||||
if (MeltArmor_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_MELT_ARMOR);
|
||||
case WE_REVIVE:
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->SetFullHealth();
|
||||
me->SetSpeedRate(MOVE_RUN, DefaultMoveSpeedRate);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
DoZoneInCombat();
|
||||
DoCast(me, SPELL_REBIRTH, true);
|
||||
MeltArmor_Timer = 60000;
|
||||
}
|
||||
else
|
||||
MeltArmor_Timer -= diff;
|
||||
|
||||
if (DiveBomb_Timer <= diff)
|
||||
{
|
||||
me->AttackStop();
|
||||
me->GetMotionMaster()->MovePoint(6, waypoint[4][0], waypoint[4][1], waypoint[4][2]);
|
||||
me->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetBoundingRadius(50);
|
||||
WaitEvent = WE_METEOR;
|
||||
WaitTimer = 0;
|
||||
Charge_Timer = 7000;
|
||||
DiveBomb_Timer = 40000 + rand32() % 5000;
|
||||
FlamePatch_Timer = 30000;
|
||||
Phase1 = false;
|
||||
break;
|
||||
case WE_METEOR:
|
||||
DoCast(me, SPELL_DIVE_BOMB_VISUAL, false);
|
||||
WaitEvent = WE_DIVE;
|
||||
WaitTimer = 4000;
|
||||
return;
|
||||
}
|
||||
else
|
||||
DiveBomb_Timer -= diff;
|
||||
|
||||
if (FlamePatch_Timer <= diff)
|
||||
{
|
||||
case WE_DIVE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
Creature* Summoned = me->SummonCreature(CREATURE_FLAME_PATCH_ALAR, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 2min);
|
||||
if (Summoned)
|
||||
{
|
||||
Summoned->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
Summoned->SetObjectScale(Summoned->GetObjectScale() * 2.5f);
|
||||
Summoned->SetDisplayId(11686);
|
||||
Summoned->SetFaction(me->GetFaction());
|
||||
Summoned->SetLevel(me->GetLevel());
|
||||
Summoned->CastSpell(Summoned, SPELL_FLAME_PATCH, false);
|
||||
}
|
||||
me->RemoveAurasDueToSpell(SPELL_DIVE_BOMB_VISUAL);
|
||||
DoCast(target, SPELL_DIVE_BOMB, true);
|
||||
float dist = 3.0f;
|
||||
if (me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f))
|
||||
dist = 5.0f;
|
||||
WaitTimer = 1000 + uint32(floor(dist / 80 * 1000.0f));
|
||||
me->UpdatePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f);
|
||||
me->StopMoving();
|
||||
WaitEvent = WE_LAND;
|
||||
return;
|
||||
}
|
||||
FlamePatch_Timer = 30000;
|
||||
}
|
||||
else
|
||||
FlamePatch_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void DoMeleeAttackIfReady()
|
||||
{
|
||||
if (me->isAttackReady() && !me->IsNonMeleeSpellCast(false))
|
||||
{
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Unit* target = me->SelectNearestTargetInAttackDistance(5))
|
||||
AttackStart(target);
|
||||
else
|
||||
{
|
||||
DoCast(me, SPELL_FLAME_BUFFET, true);
|
||||
me->setAttackTimer(BASE_ATTACK, 1500);
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
case WE_LAND:
|
||||
WaitEvent = WE_SUMMON;
|
||||
WaitTimer = 2000;
|
||||
return;
|
||||
case WE_SUMMON:
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SetBoundingRadius(10);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetDisplayId(me->GetNativeDisplayId());
|
||||
DoCast(me, SPELL_REBIRTH_2, true);
|
||||
break;
|
||||
case WE_DUMMY:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
WaitEvent = WE_NONE;
|
||||
WaitTimer = 0;
|
||||
}
|
||||
else
|
||||
WaitTimer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTheEyeAI<boss_alarAI>(creature);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
class npc_ember_of_alar : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ember_of_alar() : CreatureScript("npc_ember_of_alar") { }
|
||||
|
||||
struct npc_ember_of_alarAI : public ScriptedAI
|
||||
if (Phase1)
|
||||
{
|
||||
npc_ember_of_alarAI(Creature* creature) : ScriptedAI(creature)
|
||||
if (!me->IsThreatened())
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
creature->SetDisableGravity(true);
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
if (Platforms_Move_Timer <= diff)
|
||||
{
|
||||
toDie = false;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
bool toDie;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* killer, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && killer != me && !toDie)
|
||||
if (cur_wp == 4)
|
||||
{
|
||||
damage = 0;
|
||||
DoCast(me, SPELL_EMBER_BLAST, true);
|
||||
me->SetDisplayId(11686);
|
||||
me->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
if (instance->GetBossState(DATA_ALAR) == IN_PROGRESS)
|
||||
cur_wp = 0;
|
||||
WaitEvent = WE_PLATFORM;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (urand(0, 4)) // next platform
|
||||
{
|
||||
if (Unit* Alar = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_ALAR)))
|
||||
{
|
||||
int32 AlarHealth = int32(Alar->GetHealth()) - int32(Alar->CountPctFromMaxHealth(3));
|
||||
if (AlarHealth > 0)
|
||||
Alar->SetHealth(AlarHealth);
|
||||
else
|
||||
Alar->SetHealth(1);
|
||||
}
|
||||
DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
if (cur_wp == 3)
|
||||
cur_wp = 0;
|
||||
else
|
||||
++cur_wp;
|
||||
WaitEvent = WE_PLATFORM;
|
||||
}
|
||||
else // flame quill
|
||||
{
|
||||
cur_wp = 4;
|
||||
WaitEvent = WE_QUILL;
|
||||
}
|
||||
toDie = true;
|
||||
}
|
||||
ForceMove = true;
|
||||
ForceTimer = 5000;
|
||||
me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]);
|
||||
WaitTimer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (toDie)
|
||||
{
|
||||
me->KillSelf();
|
||||
//me->SetVisibility(VISIBILITY_OFF);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTheEyeAI<npc_ember_of_alarAI>(creature);
|
||||
else
|
||||
Platforms_Move_Timer -= diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Charge_Timer <= diff)
|
||||
{
|
||||
Unit* target= SelectTarget(SelectTargetMethod::Random, 1, 100, true);
|
||||
if (target)
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
Charge_Timer = 30000;
|
||||
}
|
||||
else
|
||||
Charge_Timer -= diff;
|
||||
|
||||
if (MeltArmor_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_MELT_ARMOR);
|
||||
MeltArmor_Timer = 60000;
|
||||
}
|
||||
else
|
||||
MeltArmor_Timer -= diff;
|
||||
|
||||
if (DiveBomb_Timer <= diff)
|
||||
{
|
||||
me->AttackStop();
|
||||
me->GetMotionMaster()->MovePoint(6, waypoint[4][0], waypoint[4][1], waypoint[4][2]);
|
||||
me->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetBoundingRadius(50);
|
||||
WaitEvent = WE_METEOR;
|
||||
WaitTimer = 0;
|
||||
DiveBomb_Timer = 40000 + rand32() % 5000;
|
||||
return;
|
||||
}
|
||||
else
|
||||
DiveBomb_Timer -= diff;
|
||||
|
||||
if (FlamePatch_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
Creature* Summoned = me->SummonCreature(CREATURE_FLAME_PATCH_ALAR, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 2min);
|
||||
if (Summoned)
|
||||
{
|
||||
Summoned->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
Summoned->SetObjectScale(Summoned->GetObjectScale() * 2.5f);
|
||||
Summoned->SetDisplayId(11686);
|
||||
Summoned->SetFaction(me->GetFaction());
|
||||
Summoned->SetLevel(me->GetLevel());
|
||||
Summoned->CastSpell(Summoned, SPELL_FLAME_PATCH, false);
|
||||
}
|
||||
}
|
||||
FlamePatch_Timer = 30000;
|
||||
}
|
||||
else
|
||||
FlamePatch_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void DoMeleeAttackIfReady()
|
||||
{
|
||||
if (me->isAttackReady() && !me->IsNonMeleeSpellCast(false))
|
||||
{
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Unit* target = me->SelectNearestTargetInAttackDistance(5))
|
||||
AttackStart(target);
|
||||
else
|
||||
{
|
||||
DoCast(me, SPELL_FLAME_BUFFET, true);
|
||||
me->setAttackTimer(BASE_ATTACK, 1500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class npc_flame_patch_alar : public CreatureScript
|
||||
struct npc_ember_of_alar : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_flame_patch_alar() : CreatureScript("npc_flame_patch_alar") { }
|
||||
npc_ember_of_alar(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
creature->SetDisableGravity(true);
|
||||
}
|
||||
|
||||
struct npc_flame_patch_alarAI : public ScriptedAI
|
||||
void Initialize()
|
||||
{
|
||||
toDie = false;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
bool toDie;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* killer, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && killer != me && !toDie)
|
||||
{
|
||||
npc_flame_patch_alarAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
void Reset() override { }
|
||||
void JustEngagedWith(Unit* /*who*/) override { }
|
||||
void AttackStart(Unit* /*who*/) override { }
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override { }
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTheEyeAI<npc_flame_patch_alarAI>(creature);
|
||||
damage = 0;
|
||||
DoCast(me, SPELL_EMBER_BLAST, true);
|
||||
me->SetDisplayId(11686);
|
||||
me->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
if (instance->GetBossState(DATA_ALAR) == IN_PROGRESS)
|
||||
{
|
||||
if (Unit* Alar = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_ALAR)))
|
||||
{
|
||||
int32 AlarHealth = int32(Alar->GetHealth()) - int32(Alar->CountPctFromMaxHealth(3));
|
||||
if (AlarHealth > 0)
|
||||
Alar->SetHealth(AlarHealth);
|
||||
else
|
||||
Alar->SetHealth(1);
|
||||
}
|
||||
}
|
||||
toDie = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (toDie)
|
||||
{
|
||||
me->KillSelf();
|
||||
//me->SetVisibility(VISIBILITY_OFF);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
struct npc_flame_patch_alar : public ScriptedAI
|
||||
{
|
||||
npc_flame_patch_alar(Creature* creature) : ScriptedAI(creature) { }
|
||||
void Reset() override { }
|
||||
void JustEngagedWith(Unit* /*who*/) override { }
|
||||
void AttackStart(Unit* /*who*/) override { }
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override { }
|
||||
};
|
||||
|
||||
// 34229 - Flame Quills
|
||||
@@ -615,8 +581,8 @@ class spell_alar_flame_quills : public AuraScript
|
||||
|
||||
void AddSC_boss_alar()
|
||||
{
|
||||
new boss_alar();
|
||||
new npc_ember_of_alar();
|
||||
new npc_flame_patch_alar();
|
||||
RegisterTheEyeCreatureAI(boss_alar);
|
||||
RegisterTheEyeCreatureAI(npc_ember_of_alar);
|
||||
RegisterTheEyeCreatureAI(npc_flame_patch_alar);
|
||||
RegisterSpellScript(spell_alar_flame_quills);
|
||||
}
|
||||
|
||||
@@ -90,456 +90,421 @@ const float PORTAL_Z = 17.005f;
|
||||
static float SolarianPos[4] = {432.909f, -373.424f, 17.9608f, 1.06421f};
|
||||
*/
|
||||
|
||||
class boss_high_astromancer_solarian : public CreatureScript
|
||||
struct boss_high_astromancer_solarian : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_high_astromancer_solarian(Creature* creature) : BossAI(creature, DATA_SOLARIAN)
|
||||
{
|
||||
Initialize();
|
||||
|
||||
boss_high_astromancer_solarian() : CreatureScript("boss_high_astromancer_solarian") { }
|
||||
defaultarmor = creature->GetArmor();
|
||||
memset(Portals, 0, sizeof(Portals));
|
||||
}
|
||||
|
||||
struct boss_high_astromancer_solarianAI : public BossAI
|
||||
void Initialize()
|
||||
{
|
||||
ArcaneMissiles_Timer = 2000;
|
||||
m_uiWrathOfTheAstromancer_Timer = 15000;
|
||||
BlindingLight_Timer = 41000;
|
||||
Fear_Timer = 20000;
|
||||
VoidBolt_Timer = 10000;
|
||||
Phase1_Timer = 50000;
|
||||
Phase2_Timer = 10s;
|
||||
Phase3_Timer = 15s;
|
||||
AppearDelay_Timer = 2s;
|
||||
BlindingLight = false;
|
||||
AppearDelay = false;
|
||||
Wrath_Timer = 20000 + rand32() % 5000;//twice in phase one
|
||||
Phase = 1;
|
||||
}
|
||||
|
||||
uint8 Phase;
|
||||
|
||||
uint32 ArcaneMissiles_Timer;
|
||||
uint32 m_uiWrathOfTheAstromancer_Timer;
|
||||
uint32 BlindingLight_Timer;
|
||||
uint32 Fear_Timer;
|
||||
uint32 VoidBolt_Timer;
|
||||
uint32 Phase1_Timer;
|
||||
Milliseconds Phase2_Timer;
|
||||
Milliseconds Phase3_Timer;
|
||||
Milliseconds AppearDelay_Timer;
|
||||
uint32 defaultarmor;
|
||||
uint32 Wrath_Timer;
|
||||
|
||||
float Portals[3][3];
|
||||
|
||||
bool AppearDelay;
|
||||
bool BlindingLight;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
_Reset();
|
||||
me->SetArmor(defaultarmor, 0);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetVisible(true);
|
||||
me->SetDisplayId(MODEL_HUMAN);
|
||||
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->SetDisplayId(MODEL_HUMAN);
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
me->CallForHelp(120.0f);
|
||||
}
|
||||
|
||||
void SummonMinion(uint32 entry, float x, float y, float z)
|
||||
{
|
||||
Creature* Summoned = me->SummonCreature(entry, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
if (Summoned)
|
||||
{
|
||||
boss_high_astromancer_solarianAI(Creature* creature) : BossAI(creature, DATA_SOLARIAN)
|
||||
{
|
||||
Initialize();
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
Summoned->AI()->AttackStart(target);
|
||||
|
||||
defaultarmor = creature->GetArmor();
|
||||
memset(Portals, 0, sizeof(Portals));
|
||||
}
|
||||
summons.Summon(Summoned);
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
float Portal_X(float radius)
|
||||
{
|
||||
if (urand(0, 1))
|
||||
radius = -radius;
|
||||
|
||||
return radius * (float)(rand32() % 100) / 100.0f + CENTER_X;
|
||||
}
|
||||
|
||||
float Portal_Y(float x, float radius)
|
||||
{
|
||||
float z = RAND(1.0f, -1.0f);
|
||||
|
||||
return (z*std::sqrt(radius*radius - (x - CENTER_X)*(x - CENTER_X)) + CENTER_Y);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
if (AppearDelay)
|
||||
{
|
||||
me->StopMoving();
|
||||
me->AttackStop();
|
||||
if (AppearDelay_Timer <= Milliseconds(diff))
|
||||
{
|
||||
ArcaneMissiles_Timer = 2000;
|
||||
m_uiWrathOfTheAstromancer_Timer = 15000;
|
||||
BlindingLight_Timer = 41000;
|
||||
Fear_Timer = 20000;
|
||||
VoidBolt_Timer = 10000;
|
||||
Phase1_Timer = 50000;
|
||||
Phase2_Timer = 10s;
|
||||
Phase3_Timer = 15s;
|
||||
AppearDelay_Timer = 2s;
|
||||
BlindingLight = false;
|
||||
AppearDelay = false;
|
||||
Wrath_Timer = 20000 + rand32() % 5000;//twice in phase one
|
||||
Phase = 1;
|
||||
if (Phase == 2)
|
||||
{
|
||||
me->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetVisible(false);
|
||||
}
|
||||
AppearDelay_Timer = 2s;
|
||||
}
|
||||
|
||||
uint8 Phase;
|
||||
|
||||
uint32 ArcaneMissiles_Timer;
|
||||
uint32 m_uiWrathOfTheAstromancer_Timer;
|
||||
uint32 BlindingLight_Timer;
|
||||
uint32 Fear_Timer;
|
||||
uint32 VoidBolt_Timer;
|
||||
uint32 Phase1_Timer;
|
||||
Milliseconds Phase2_Timer;
|
||||
Milliseconds Phase3_Timer;
|
||||
Milliseconds AppearDelay_Timer;
|
||||
uint32 defaultarmor;
|
||||
uint32 Wrath_Timer;
|
||||
|
||||
float Portals[3][3];
|
||||
|
||||
bool AppearDelay;
|
||||
bool BlindingLight;
|
||||
|
||||
void Reset() override
|
||||
else
|
||||
AppearDelay_Timer -= Milliseconds(diff);
|
||||
}
|
||||
if (Phase == 1)
|
||||
{
|
||||
if (BlindingLight_Timer <= diff)
|
||||
{
|
||||
Initialize();
|
||||
_Reset();
|
||||
me->SetArmor(defaultarmor, 0);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetVisible(true);
|
||||
me->SetDisplayId(MODEL_HUMAN);
|
||||
|
||||
BlindingLight = true;
|
||||
BlindingLight_Timer = 45000;
|
||||
}
|
||||
else
|
||||
BlindingLight_Timer -= diff;
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
if (Wrath_Timer <= diff)
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100, true))
|
||||
DoCast(target, SPELL_WRATH_OF_THE_ASTROMANCER, true);
|
||||
Wrath_Timer = 20000 + rand32() % 5000;
|
||||
}
|
||||
else
|
||||
Wrath_Timer -= diff;
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
if (ArcaneMissiles_Timer <= diff)
|
||||
{
|
||||
me->SetDisplayId(MODEL_HUMAN);
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
me->CallForHelp(120.0f);
|
||||
}
|
||||
|
||||
void SummonMinion(uint32 entry, float x, float y, float z)
|
||||
{
|
||||
Creature* Summoned = me->SummonCreature(entry, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
if (Summoned)
|
||||
if (BlindingLight)
|
||||
{
|
||||
DoCastVictim(SPELL_BLINDING_LIGHT);
|
||||
BlindingLight = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
Summoned->AI()->AttackStart(target);
|
||||
{
|
||||
if (!me->HasInArc(2.5f, target))
|
||||
target = me->GetVictim();
|
||||
|
||||
summons.Summon(Summoned);
|
||||
DoCast(target, SPELL_ARCANE_MISSILES);
|
||||
}
|
||||
}
|
||||
ArcaneMissiles_Timer = 3000;
|
||||
}
|
||||
else
|
||||
ArcaneMissiles_Timer -= diff;
|
||||
|
||||
float Portal_X(float radius)
|
||||
if (m_uiWrathOfTheAstromancer_Timer <= diff)
|
||||
{
|
||||
if (urand(0, 1))
|
||||
radius = -radius;
|
||||
|
||||
return radius * (float)(rand32() % 100) / 100.0f + CENTER_X;
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
//Target the tank ?
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
|
||||
{
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
DoCast(target, SPELL_WRATH_OF_THE_ASTROMANCER);
|
||||
m_uiWrathOfTheAstromancer_Timer = 25000;
|
||||
}
|
||||
else
|
||||
m_uiWrathOfTheAstromancer_Timer = 1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiWrathOfTheAstromancer_Timer -= diff;
|
||||
|
||||
float Portal_Y(float x, float radius)
|
||||
//Phase1_Timer
|
||||
if (Phase1_Timer <= diff)
|
||||
{
|
||||
float z = RAND(1.0f, -1.0f);
|
||||
|
||||
return (z*std::sqrt(radius*radius - (x - CENTER_X)*(x - CENTER_X)) + CENTER_Y);
|
||||
Phase = 2;
|
||||
Phase1_Timer = 50000;
|
||||
//After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind.
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->UpdatePosition(CENTER_X, CENTER_Y, CENTER_Z, CENTER_O);
|
||||
for (uint8 i = 0; i <= 2; ++i)
|
||||
{
|
||||
if (!i)
|
||||
{
|
||||
Portals[i][0] = Portal_X(SMALL_PORTAL_RADIUS);
|
||||
Portals[i][1] = Portal_Y(Portals[i][0], SMALL_PORTAL_RADIUS);
|
||||
Portals[i][2] = CENTER_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
Portals[i][0] = Portal_X(LARGE_PORTAL_RADIUS);
|
||||
Portals[i][1] = Portal_Y(Portals[i][0], LARGE_PORTAL_RADIUS);
|
||||
Portals[i][2] = PORTAL_Z;
|
||||
}
|
||||
}
|
||||
if ((std::abs(Portals[2][0] - Portals[1][0]) < 7) && (std::abs(Portals[2][1] - Portals[1][1]) < 7))
|
||||
{
|
||||
int i = 1;
|
||||
if (std::abs(CENTER_X + 26.0f - Portals[2][0]) < 7)
|
||||
i = -1;
|
||||
Portals[2][0] = Portals[2][0] + 7 * i;
|
||||
Portals[2][1] = Portal_Y(Portals[2][0], LARGE_PORTAL_RADIUS);
|
||||
}
|
||||
for (int i = 0; i <= 2; ++i)
|
||||
{
|
||||
if (Creature* Summoned = me->SummonCreature(NPC_ASTROMANCER_SOLARIAN_SPOTLIGHT, Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O, TEMPSUMMON_TIMED_DESPAWN, Phase2_Timer + Phase3_Timer + AppearDelay_Timer + 1700ms))
|
||||
{
|
||||
Summoned->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
Summoned->CastSpell(Summoned, SPELL_SPOTLIGHT, false);
|
||||
}
|
||||
}
|
||||
AppearDelay = true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
if (AppearDelay)
|
||||
{
|
||||
me->StopMoving();
|
||||
me->AttackStop();
|
||||
if (AppearDelay_Timer <= Milliseconds(diff))
|
||||
{
|
||||
AppearDelay = false;
|
||||
if (Phase == 2)
|
||||
{
|
||||
me->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetVisible(false);
|
||||
}
|
||||
AppearDelay_Timer = 2s;
|
||||
}
|
||||
else
|
||||
AppearDelay_Timer -= Milliseconds(diff);
|
||||
}
|
||||
if (Phase == 1)
|
||||
{
|
||||
if (BlindingLight_Timer <= diff)
|
||||
{
|
||||
BlindingLight = true;
|
||||
BlindingLight_Timer = 45000;
|
||||
}
|
||||
else
|
||||
BlindingLight_Timer -= diff;
|
||||
|
||||
if (Wrath_Timer <= diff)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100, true))
|
||||
DoCast(target, SPELL_WRATH_OF_THE_ASTROMANCER, true);
|
||||
Wrath_Timer = 20000 + rand32() % 5000;
|
||||
}
|
||||
else
|
||||
Wrath_Timer -= diff;
|
||||
|
||||
if (ArcaneMissiles_Timer <= diff)
|
||||
{
|
||||
if (BlindingLight)
|
||||
{
|
||||
DoCastVictim(SPELL_BLINDING_LIGHT);
|
||||
BlindingLight = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
if (!me->HasInArc(2.5f, target))
|
||||
target = me->GetVictim();
|
||||
|
||||
DoCast(target, SPELL_ARCANE_MISSILES);
|
||||
}
|
||||
}
|
||||
ArcaneMissiles_Timer = 3000;
|
||||
}
|
||||
else
|
||||
ArcaneMissiles_Timer -= diff;
|
||||
|
||||
if (m_uiWrathOfTheAstromancer_Timer <= diff)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
//Target the tank ?
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
|
||||
{
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
DoCast(target, SPELL_WRATH_OF_THE_ASTROMANCER);
|
||||
m_uiWrathOfTheAstromancer_Timer = 25000;
|
||||
}
|
||||
else
|
||||
m_uiWrathOfTheAstromancer_Timer = 1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiWrathOfTheAstromancer_Timer -= diff;
|
||||
|
||||
//Phase1_Timer
|
||||
if (Phase1_Timer <= diff)
|
||||
{
|
||||
Phase = 2;
|
||||
Phase1_Timer = 50000;
|
||||
//After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind.
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->UpdatePosition(CENTER_X, CENTER_Y, CENTER_Z, CENTER_O);
|
||||
for (uint8 i = 0; i <= 2; ++i)
|
||||
{
|
||||
if (!i)
|
||||
{
|
||||
Portals[i][0] = Portal_X(SMALL_PORTAL_RADIUS);
|
||||
Portals[i][1] = Portal_Y(Portals[i][0], SMALL_PORTAL_RADIUS);
|
||||
Portals[i][2] = CENTER_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
Portals[i][0] = Portal_X(LARGE_PORTAL_RADIUS);
|
||||
Portals[i][1] = Portal_Y(Portals[i][0], LARGE_PORTAL_RADIUS);
|
||||
Portals[i][2] = PORTAL_Z;
|
||||
}
|
||||
}
|
||||
if ((std::abs(Portals[2][0] - Portals[1][0]) < 7) && (std::abs(Portals[2][1] - Portals[1][1]) < 7))
|
||||
{
|
||||
int i = 1;
|
||||
if (std::abs(CENTER_X + 26.0f - Portals[2][0]) < 7)
|
||||
i = -1;
|
||||
Portals[2][0] = Portals[2][0] + 7 * i;
|
||||
Portals[2][1] = Portal_Y(Portals[2][0], LARGE_PORTAL_RADIUS);
|
||||
}
|
||||
for (int i = 0; i <= 2; ++i)
|
||||
{
|
||||
if (Creature* Summoned = me->SummonCreature(NPC_ASTROMANCER_SOLARIAN_SPOTLIGHT, Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O, TEMPSUMMON_TIMED_DESPAWN, Phase2_Timer + Phase3_Timer + AppearDelay_Timer + 1700ms))
|
||||
{
|
||||
Summoned->AddUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
Summoned->CastSpell(Summoned, SPELL_SPOTLIGHT, false);
|
||||
}
|
||||
}
|
||||
AppearDelay = true;
|
||||
}
|
||||
else
|
||||
Phase1_Timer -= diff;
|
||||
}
|
||||
else if (Phase == 2)
|
||||
{
|
||||
//10 seconds after Solarian disappears, 12 mobs spawn out of the three portals.
|
||||
me->AttackStop();
|
||||
me->StopMoving();
|
||||
if (Phase2_Timer <= Milliseconds(diff))
|
||||
{
|
||||
Phase = 3;
|
||||
for (int i=0; i <= 2; ++i)
|
||||
for (int j=1; j <= 4; j++)
|
||||
SummonMinion(NPC_SOLARIUM_AGENT, Portals[i][0], Portals[i][1], Portals[i][2]);
|
||||
|
||||
Talk(SAY_SUMMON1);
|
||||
Phase2_Timer = 10s;
|
||||
}
|
||||
else
|
||||
Phase2_Timer -= Milliseconds(diff);
|
||||
}
|
||||
else if (Phase == 3)
|
||||
{
|
||||
me->AttackStop();
|
||||
me->StopMoving();
|
||||
//Check Phase3_Timer
|
||||
if (Phase3_Timer <= Milliseconds(diff))
|
||||
{
|
||||
Phase = 1;
|
||||
//15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals.
|
||||
int i = rand32() % 3;
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->UpdatePosition(Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O);
|
||||
|
||||
for (int j=0; j <= 2; j++)
|
||||
if (j != i)
|
||||
SummonMinion(NPC_SOLARIUM_PRIEST, Portals[j][0], Portals[j][1], Portals[j][2]);
|
||||
|
||||
me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetVisible(true);
|
||||
|
||||
Talk(SAY_SUMMON2);
|
||||
AppearDelay = true;
|
||||
Phase3_Timer = 15s;
|
||||
}
|
||||
else
|
||||
Phase3_Timer -= Milliseconds(diff);
|
||||
}
|
||||
else if (Phase == 4)
|
||||
{
|
||||
//Fear_Timer
|
||||
if (Fear_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_FEAR);
|
||||
Fear_Timer = 20000;
|
||||
}
|
||||
else
|
||||
Fear_Timer -= diff;
|
||||
//VoidBolt_Timer
|
||||
if (VoidBolt_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_VOID_BOLT);
|
||||
VoidBolt_Timer = 10000;
|
||||
}
|
||||
else
|
||||
VoidBolt_Timer -= diff;
|
||||
}
|
||||
|
||||
//When Solarian reaches 20% she will transform into a huge void walker.
|
||||
if (Phase != 4 && me->HealthBelowPct(20))
|
||||
{
|
||||
Phase = 4;
|
||||
//To make sure she wont be invisible or not selecatble
|
||||
me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetVisible(true);
|
||||
Talk(SAY_VOIDA);
|
||||
Talk(SAY_VOIDB);
|
||||
me->SetArmor(WV_ARMOR, 0);
|
||||
me->SetDisplayId(MODEL_VOIDWALKER);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTheEyeAI<boss_high_astromancer_solarianAI>(creature);
|
||||
else
|
||||
Phase1_Timer -= diff;
|
||||
}
|
||||
else if (Phase == 2)
|
||||
{
|
||||
//10 seconds after Solarian disappears, 12 mobs spawn out of the three portals.
|
||||
me->AttackStop();
|
||||
me->StopMoving();
|
||||
if (Phase2_Timer <= Milliseconds(diff))
|
||||
{
|
||||
Phase = 3;
|
||||
for (int i=0; i <= 2; ++i)
|
||||
for (int j=1; j <= 4; j++)
|
||||
SummonMinion(NPC_SOLARIUM_AGENT, Portals[i][0], Portals[i][1], Portals[i][2]);
|
||||
|
||||
Talk(SAY_SUMMON1);
|
||||
Phase2_Timer = 10s;
|
||||
}
|
||||
else
|
||||
Phase2_Timer -= Milliseconds(diff);
|
||||
}
|
||||
else if (Phase == 3)
|
||||
{
|
||||
me->AttackStop();
|
||||
me->StopMoving();
|
||||
//Check Phase3_Timer
|
||||
if (Phase3_Timer <= Milliseconds(diff))
|
||||
{
|
||||
Phase = 1;
|
||||
//15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals.
|
||||
int i = rand32() % 3;
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->UpdatePosition(Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O);
|
||||
|
||||
for (int j=0; j <= 2; j++)
|
||||
if (j != i)
|
||||
SummonMinion(NPC_SOLARIUM_PRIEST, Portals[j][0], Portals[j][1], Portals[j][2]);
|
||||
|
||||
me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetVisible(true);
|
||||
|
||||
Talk(SAY_SUMMON2);
|
||||
AppearDelay = true;
|
||||
Phase3_Timer = 15s;
|
||||
}
|
||||
else
|
||||
Phase3_Timer -= Milliseconds(diff);
|
||||
}
|
||||
else if (Phase == 4)
|
||||
{
|
||||
//Fear_Timer
|
||||
if (Fear_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_FEAR);
|
||||
Fear_Timer = 20000;
|
||||
}
|
||||
else
|
||||
Fear_Timer -= diff;
|
||||
//VoidBolt_Timer
|
||||
if (VoidBolt_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_VOID_BOLT);
|
||||
VoidBolt_Timer = 10000;
|
||||
}
|
||||
else
|
||||
VoidBolt_Timer -= diff;
|
||||
}
|
||||
|
||||
//When Solarian reaches 20% she will transform into a huge void walker.
|
||||
if (Phase != 4 && me->HealthBelowPct(20))
|
||||
{
|
||||
Phase = 4;
|
||||
//To make sure she wont be invisible or not selecatble
|
||||
me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
|
||||
me->SetVisible(true);
|
||||
Talk(SAY_VOIDA);
|
||||
Talk(SAY_VOIDB);
|
||||
me->SetArmor(WV_ARMOR, 0);
|
||||
me->SetDisplayId(MODEL_VOIDWALKER);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
class npc_solarium_priest : public CreatureScript
|
||||
struct npc_solarium_priest : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_solarium_priest(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
npc_solarium_priest() : CreatureScript("npc_solarium_priest") { }
|
||||
void Initialize()
|
||||
{
|
||||
healTimer = 9000;
|
||||
holysmiteTimer = 1;
|
||||
aoesilenceTimer = 15000;
|
||||
}
|
||||
|
||||
struct npc_solarium_priestAI : public ScriptedAI
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 healTimer;
|
||||
uint32 holysmiteTimer;
|
||||
uint32 aoesilenceTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override { }
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (healTimer <= diff)
|
||||
{
|
||||
npc_solarium_priestAI(Creature* creature) : ScriptedAI(creature)
|
||||
Unit* target = nullptr;
|
||||
switch (urand(0, 1))
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
case 0:
|
||||
target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_SOLARIAN));
|
||||
break;
|
||||
case 1:
|
||||
target = me;
|
||||
break;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, SPELL_SOLARIUM_GREAT_HEAL);
|
||||
healTimer = 9000;
|
||||
holysmiteTimer = 1;
|
||||
aoesilenceTimer = 15000;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 healTimer;
|
||||
uint32 holysmiteTimer;
|
||||
uint32 aoesilenceTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override { }
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (healTimer <= diff)
|
||||
{
|
||||
Unit* target = nullptr;
|
||||
switch (urand(0, 1))
|
||||
{
|
||||
case 0:
|
||||
target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_SOLARIAN));
|
||||
break;
|
||||
case 1:
|
||||
target = me;
|
||||
break;
|
||||
}
|
||||
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, SPELL_SOLARIUM_GREAT_HEAL);
|
||||
healTimer = 9000;
|
||||
}
|
||||
}
|
||||
else
|
||||
healTimer -= diff;
|
||||
|
||||
if (holysmiteTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SOLARIUM_HOLY_SMITE);
|
||||
holysmiteTimer = 4000;
|
||||
}
|
||||
else
|
||||
holysmiteTimer -= diff;
|
||||
|
||||
if (aoesilenceTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SOLARIUM_ARCANE_TORRENT);
|
||||
aoesilenceTimer = 13000;
|
||||
}
|
||||
else
|
||||
aoesilenceTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTheEyeAI<npc_solarium_priestAI>(creature);
|
||||
}
|
||||
else
|
||||
healTimer -= diff;
|
||||
|
||||
if (holysmiteTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SOLARIUM_HOLY_SMITE);
|
||||
holysmiteTimer = 4000;
|
||||
}
|
||||
else
|
||||
holysmiteTimer -= diff;
|
||||
|
||||
if (aoesilenceTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SOLARIUM_ARCANE_TORRENT);
|
||||
aoesilenceTimer = 13000;
|
||||
}
|
||||
else
|
||||
aoesilenceTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
// 42783 - Wrath of the Astromancer
|
||||
class spell_astromancer_wrath_of_the_astromancer : public SpellScriptLoader
|
||||
class spell_astromancer_wrath_of_the_astromancer : public AuraScript
|
||||
{
|
||||
public:
|
||||
spell_astromancer_wrath_of_the_astromancer() : SpellScriptLoader("spell_astromancer_wrath_of_the_astromancer") { }
|
||||
PrepareAuraScript(spell_astromancer_wrath_of_the_astromancer);
|
||||
|
||||
class spell_astromancer_wrath_of_the_astromancer_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_astromancer_wrath_of_the_astromancer_AuraScript);
|
||||
bool Validate(SpellInfo const* spellInfo) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_WRATH_OF_THE_ASTROMANCER_DOT })
|
||||
&& spellInfo->GetEffects().size() > EFFECT_1;
|
||||
}
|
||||
|
||||
bool Validate(SpellInfo const* spellInfo) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_WRATH_OF_THE_ASTROMANCER_DOT })
|
||||
&& spellInfo->GetEffects().size() > EFFECT_1;
|
||||
}
|
||||
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
// Final heal only on duration end
|
||||
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
|
||||
return;
|
||||
|
||||
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
// Final heal only on duration end
|
||||
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
|
||||
return;
|
||||
Unit* target = GetUnitOwner();
|
||||
target->CastSpell(target, GetEffectInfo(EFFECT_1).CalcValue(), false);
|
||||
}
|
||||
|
||||
Unit* target = GetUnitOwner();
|
||||
target->CastSpell(target, GetEffectInfo(EFFECT_1).CalcValue(), false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_astromancer_wrath_of_the_astromancer_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_astromancer_wrath_of_the_astromancer_AuraScript();
|
||||
}
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_astromancer_wrath_of_the_astromancer::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_high_astromancer_solarian()
|
||||
{
|
||||
new boss_high_astromancer_solarian();
|
||||
new npc_solarium_priest();
|
||||
new spell_astromancer_wrath_of_the_astromancer();
|
||||
RegisterTheEyeCreatureAI(boss_high_astromancer_solarian);
|
||||
RegisterTheEyeCreatureAI(npc_solarium_priest);
|
||||
RegisterSpellScript(spell_astromancer_wrath_of_the_astromancer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user