fix(Scripts/ZulAman): Fix Akilzon not spawning eagles and update script (#20493)

* fix(Scripts/ZulAman): Fix Akilzon not spawning eagles and update script

* Update boss_akilzon.cpp
This commit is contained in:
Andrew
2024-11-10 08:41:46 -03:00
committed by GitHub
parent 8904a13304
commit e2be8fb296
2 changed files with 129 additions and 180 deletions
@@ -0,0 +1,4 @@
--
DELETE FROM `creature_template_movement` WHERE `CreatureId` = 24858;
INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Flight`) VALUES
(24858, 1, 1);
@@ -58,26 +58,6 @@ enum Says
constexpr auto NPC_SOARING_EAGLE = 24858; constexpr auto NPC_SOARING_EAGLE = 24858;
//enum Misc
//{
// SE_LOC_X_MAX = 400,
// SE_LOC_X_MIN = 335,
// SE_LOC_Y_MAX = 1435,
// SE_LOC_Y_MIN = 1370
//};
enum Events
{
EVENT_STATIC_DISRUPTION = 1,
EVENT_GUST_OF_WIND = 2,
EVENT_CALL_LIGHTNING = 3,
EVENT_ELECTRICAL_STORM = 4,
EVENT_RAIN = 5,
EVENT_SUMMON_EAGLES = 6,
EVENT_STORM_SEQUENCE = 7,
EVENT_ENRAGE = 8
};
class boss_akilzon : public CreatureScript class boss_akilzon : public CreatureScript
{ {
public: public:
@@ -85,9 +65,7 @@ public:
struct boss_akilzonAI : public BossAI struct boss_akilzonAI : public BossAI
{ {
boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZON) boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZON) { }
{
}
void Reset() override void Reset() override
{ {
@@ -97,32 +75,103 @@ public:
CloudGUID.Clear(); CloudGUID.Clear();
CycloneGUID.Clear(); CycloneGUID.Clear();
for (uint8 i = 0; i < 8; ++i)
BirdGUIDs[i].Clear();
StormCount = 0; StormCount = 0;
isRaining = false; isRaining = false;
SetWeather(WEATHER_STATE_FINE, 0.0f); SetWeather(WEATHER_STATE_FINE, 0.0f);
me->m_Events.KillAllEvents(false);
} }
void JustEngagedWith(Unit* /*who*/) override void JustEngagedWith(Unit* /*who*/) override
{ {
events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 20000)); // 10 to 20 seconds (bosskillers) ScheduleTimedEvent(10s, 20s, [&]{
events.ScheduleEvent(EVENT_GUST_OF_WIND, urand(20000, 30000)); // 20 to 30 seconds(bosskillers) Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
events.ScheduleEvent(EVENT_CALL_LIGHTNING, urand(10000, 20000)); // totaly random timer. can't find any info on this if (!target)
events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 60000); // 60 seconds(bosskillers) target = me->GetVictim();
events.ScheduleEvent(EVENT_RAIN, urand(47000, 52000)); if (target)
events.ScheduleEvent(EVENT_ENRAGE, 10 * MINUTE * IN_MILLISECONDS); // 10 minutes till enrage(bosskillers) {
TargetGUID = target->GetGUID();
DoCast(target, SPELL_STATIC_DISRUPTION, false);
me->SetInFront(me->GetVictim());
}
}, 10s, 18s);
ScheduleTimedEvent(20s, 30s, [&] {
Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
if (!target)
target = me->GetVictim();
if (target)
DoCast(target, SPELL_GUST_OF_WIND);
}, 20s, 30s);
ScheduleTimedEvent(10s, 20s, [&] {
DoCastVictim(SPELL_CALL_LIGHTNING);
}, 12s, 17s);
ScheduleTimedEvent(1min, [&] {
Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50, true);
if (!target)
{
EnterEvadeMode();
return;
}
target->CastSpell(target, 44007, true); // cloud visual
DoCast(target, SPELL_ELECTRICAL_STORM, false); // storm cyclon + visual
float x, y, z;
target->GetPosition(x, y, z);
Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ() + 16, 0, 15000);
if (Cloud)
{
target->GetMotionMaster()->MoveJump(Cloud->GetPosition(), 1.0f, 1.0f);
CloudGUID = Cloud->GetGUID();
Cloud->SetDisableGravity(true);
Cloud->StopMoving();
Cloud->SetObjectScale(1.0f);
Cloud->SetFaction(FACTION_FRIENDLY);
Cloud->SetMaxHealth(9999999);
Cloud->SetHealth(9999999);
Cloud->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->m_Events.AddEventAtOffset([&, Cloud] {
HandleStormSequence(Cloud);
}, 3s);
}
StormCount = 1;
me->m_Events.AddEventAtOffset([&] {
if (!isRaining)
{
SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f);
isRaining = true;
}
}, Seconds(urand(47, 52)));
}, 1min);
ScheduleTimedEvent(47s, 52s, [&] {
if (!isRaining)
{
SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f);
isRaining = true;
}
}, 47s, 52s);
me->m_Events.AddEventAtOffset([&] {
Talk(SAY_ENRAGE);
DoCastSelf(SPELL_BERSERK, true);
}, 10min);
Talk(SAY_AGGRO); Talk(SAY_AGGRO);
//DoZoneInCombat();
} }
void JustDied(Unit* /*killer*/) override void JustDied(Unit* /*killer*/) override
{ {
Talk(SAY_DEATH); Talk(SAY_DEATH);
_JustDied(); _JustDied();
me->m_Events.KillAllEvents(false);
} }
void KilledUnit(Unit* who) override void KilledUnit(Unit* who) override
@@ -133,18 +182,14 @@ public:
void SetWeather(uint32 weather, float grade) void SetWeather(uint32 weather, float grade)
{ {
Map* map = me->GetMap(); me->GetMap()->SetZoneWeather(me->GetZoneId(), WeatherState(weather), grade);
if (!map->IsDungeon())
return;
WorldPacket data(SMSG_WEATHER, (4 + 4 + 4));
data << uint32(weather) << float(grade) << uint8(0);
map->SendToPlayers(&data);
} }
void HandleStormSequence(Unit* Cloud) // 1: begin, 2-9: tick, 10: end void HandleStormSequence(Unit* Cloud) // 1: begin, 2-9: tick, 10: end
{ {
if (!Cloud)
return;
if (StormCount < 10 && StormCount > 1) if (StormCount < 10 && StormCount > 1)
{ {
// deal damage // deal damage
@@ -159,9 +204,9 @@ public:
Cell::VisitAllObjects(me, searcher, SIZE_OF_GRIDS); Cell::VisitAllObjects(me, searcher, SIZE_OF_GRIDS);
// deal damage // deal damage
for (std::list<Unit*>::const_iterator i = tempUnitMap.begin(); i != tempUnitMap.end(); ++i) for (auto const& target : tempUnitMap)
{ {
if (Unit* target = (*i)) if (target)
{ {
if (Cloud && !Cloud->IsWithinDist(target, 6, false)) if (Cloud && !Cloud->IsWithinDist(target, 6, false))
Cloud->CastCustomSpell(target, SPELL_ZAP, &bp0, nullptr, nullptr, true, 0, 0, me->GetGUID()); Cloud->CastCustomSpell(target, SPELL_ZAP, &bp0, nullptr, nullptr, true, 0, 0, me->GetGUID());
@@ -192,158 +237,58 @@ public:
if (StormCount > 10) if (StormCount > 10)
{ {
StormCount = 0; // finish StormCount = 0; // finish
events.ScheduleEvent(EVENT_SUMMON_EAGLES, 5000);
me->m_Events.AddEventAtOffset([&] {
SummonEagles();
}, 5s);
me->InterruptNonMeleeSpells(false); me->InterruptNonMeleeSpells(false);
CloudGUID.Clear(); CloudGUID.Clear();
if (Cloud) if (Cloud)
Unit::DealDamage(Cloud, Cloud, Cloud->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); Cloud->KillSelf();
SetWeather(WEATHER_STATE_FINE, 0.0f); SetWeather(WEATHER_STATE_FINE, 0.0f);
isRaining = false; isRaining = false;
} }
events.ScheduleEvent(EVENT_STORM_SEQUENCE, 1000);
me->m_Events.AddEventAtOffset([&] {
Unit* target = ObjectAccessor::GetUnit(*me, CloudGUID);
if (!target || !target->IsAlive())
return;
else if (Unit* Cyclone = ObjectAccessor::GetUnit(*me, CycloneGUID))
Cyclone->CastSpell(target, SPELL_SAND_STORM, true); // keep casting or...
HandleStormSequence(target);
}, 1s);
} }
void UpdateAI(uint32 diff) override void SummonEagles()
{ {
if (!UpdateVictim()) Talk(SAY_SUMMON);
return;
events.Update(diff); float x, y, z;
me->GetPosition(x, y, z);
while (uint32 eventId = events.ExecuteEvent()) for (uint8 i = 0; i < 8; ++i)
{ {
switch (eventId) Unit* bird = ObjectAccessor::GetUnit(*me, BirdGUIDs[i]);
if (!bird) //they despawned on die
{ {
case EVENT_STATIC_DISRUPTION: if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{ {
Unit* target = SelectTarget(SelectTargetMethod::Random, 1); x = target->GetPositionX() + irand(-10, 10);
if (!target) y = target->GetPositionY() + irand(-10, 10);
target = me->GetVictim(); z = target->GetPositionZ() + urand(16, 20);
if (target) if (z > 95)
{ z = 95.0f - urand(0, 5);
TargetGUID = target->GetGUID(); }
DoCast(target, SPELL_STATIC_DISRUPTION, false); ;
me->SetInFront(me->GetVictim()); if (Creature* creature = me->SummonCreature(NPC_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0))
} {
/*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f; creature->AddThreat(me->GetVictim(), 1.0f);
SDisruptAOEVisual_Timer = 1000 + std::floor(dist / 30 * 1000.0f);*/ creature->AI()->AttackStart(me->GetVictim());
events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 18000)); BirdGUIDs[i] = creature->GetGUID();
break; }
}
case EVENT_GUST_OF_WIND:
{
Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
if (!target)
target = me->GetVictim();
if (target)
DoCast(target, SPELL_GUST_OF_WIND);
events.ScheduleEvent(EVENT_GUST_OF_WIND, urand(20000, 30000));
break;
}
case EVENT_CALL_LIGHTNING:
DoCastVictim(SPELL_CALL_LIGHTNING);
events.ScheduleEvent(EVENT_CALL_LIGHTNING, urand(12000, 17000)); // totaly random timer. can't find any info on this
break;
case EVENT_ELECTRICAL_STORM:
{
Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50, true);
if (!target)
{
EnterEvadeMode();
return;
}
target->CastSpell(target, 44007, true); // cloud visual
DoCast(target, SPELL_ELECTRICAL_STORM, false); // storm cyclon + visual
float x, y, z;
target->GetPosition(x, y, z);
/// @todo: fix it in correct way, that causes player to can fly until logout
/*
if (target)
{
target->SetDisableGravity(true);
target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0);
}
*/
Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ() + 16, 0, 15000);
if (Cloud)
{
CloudGUID = Cloud->GetGUID();
Cloud->SetDisableGravity(true);
Cloud->StopMoving();
Cloud->SetObjectScale(1.0f);
Cloud->SetFaction(FACTION_FRIENDLY);
Cloud->SetMaxHealth(9999999);
Cloud->SetHealth(9999999);
Cloud->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
StormCount = 1;
events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 60000); // 60 seconds(bosskillers)
events.ScheduleEvent(EVENT_RAIN, urand(47000, 52000));
break;
}
case EVENT_RAIN:
if (!isRaining)
{
SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f);
isRaining = true;
}
else
events.ScheduleEvent(EVENT_RAIN, 1000);
break;
case EVENT_STORM_SEQUENCE:
{
Unit* target = ObjectAccessor::GetUnit(*me, CloudGUID);
if (!target || !target->IsAlive())
{
EnterEvadeMode();
return;
}
else if (Unit* Cyclone = ObjectAccessor::GetUnit(*me, CycloneGUID))
Cyclone->CastSpell(target, SPELL_SAND_STORM, true); // keep casting or...
HandleStormSequence(target);
break;
}
case EVENT_SUMMON_EAGLES:
Talk(SAY_SUMMON);
float x, y, z;
me->GetPosition(x, y, z);
for (uint8 i = 0; i < 8; ++i)
{
Unit* bird = ObjectAccessor::GetUnit(*me, BirdGUIDs[i]);
if (!bird) //they despawned on die
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
x = target->GetPositionX() + irand(-10, 10);
y = target->GetPositionY() + irand(-10, 10);
z = target->GetPositionZ() + urand(16, 20);
if (z > 95)
z = 95.0f - urand(0, 5);
}
Creature* creature = me->SummonCreature(NPC_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
if (creature)
{
creature->AddThreat(me->GetVictim(), 1.0f);
creature->AI()->AttackStart(me->GetVictim());
BirdGUIDs[i] = creature->GetGUID();
}
}
}
break;
case EVENT_ENRAGE:
Talk(SAY_ENRAGE);
DoCast(me, SPELL_BERSERK, true);
events.ScheduleEvent(EVENT_ENRAGE, 600000);
break;
default:
break;
} }
} }
DoMeleeAttackIfReady();
} }
private: private: