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

View File

@@ -58,26 +58,6 @@ enum Says
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
{
public:
@@ -85,9 +65,7 @@ public:
struct boss_akilzonAI : public BossAI
{
boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZON)
{
}
boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZON) { }
void Reset() override
{
@@ -97,32 +75,103 @@ public:
CloudGUID.Clear();
CycloneGUID.Clear();
for (uint8 i = 0; i < 8; ++i)
BirdGUIDs[i].Clear();
StormCount = 0;
isRaining = false;
SetWeather(WEATHER_STATE_FINE, 0.0f);
me->m_Events.KillAllEvents(false);
}
void JustEngagedWith(Unit* /*who*/) override
{
events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 20000)); // 10 to 20 seconds (bosskillers)
events.ScheduleEvent(EVENT_GUST_OF_WIND, urand(20000, 30000)); // 20 to 30 seconds(bosskillers)
events.ScheduleEvent(EVENT_CALL_LIGHTNING, urand(10000, 20000)); // totaly random timer. can't find any info on this
events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 60000); // 60 seconds(bosskillers)
events.ScheduleEvent(EVENT_RAIN, urand(47000, 52000));
events.ScheduleEvent(EVENT_ENRAGE, 10 * MINUTE * IN_MILLISECONDS); // 10 minutes till enrage(bosskillers)
ScheduleTimedEvent(10s, 20s, [&]{
Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
if (!target)
target = me->GetVictim();
if (target)
{
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);
//DoZoneInCombat();
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
_JustDied();
me->m_Events.KillAllEvents(false);
}
void KilledUnit(Unit* who) override
@@ -133,18 +182,14 @@ public:
void SetWeather(uint32 weather, float grade)
{
Map* map = me->GetMap();
if (!map->IsDungeon())
return;
WorldPacket data(SMSG_WEATHER, (4 + 4 + 4));
data << uint32(weather) << float(grade) << uint8(0);
map->SendToPlayers(&data);
me->GetMap()->SetZoneWeather(me->GetZoneId(), WeatherState(weather), grade);
}
void HandleStormSequence(Unit* Cloud) // 1: begin, 2-9: tick, 10: end
{
if (!Cloud)
return;
if (StormCount < 10 && StormCount > 1)
{
// deal damage
@@ -159,9 +204,9 @@ public:
Cell::VisitAllObjects(me, searcher, SIZE_OF_GRIDS);
// 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))
Cloud->CastCustomSpell(target, SPELL_ZAP, &bp0, nullptr, nullptr, true, 0, 0, me->GetGUID());
@@ -192,158 +237,58 @@ public:
if (StormCount > 10)
{
StormCount = 0; // finish
events.ScheduleEvent(EVENT_SUMMON_EAGLES, 5000);
me->m_Events.AddEventAtOffset([&] {
SummonEagles();
}, 5s);
me->InterruptNonMeleeSpells(false);
CloudGUID.Clear();
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);
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())
return;
Talk(SAY_SUMMON);
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:
{
Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
if (!target)
target = me->GetVictim();
if (target)
{
TargetGUID = target->GetGUID();
DoCast(target, SPELL_STATIC_DISRUPTION, false);
me->SetInFront(me->GetVictim());
}
/*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f;
SDisruptAOEVisual_Timer = 1000 + std::floor(dist / 30 * 1000.0f);*/
events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 18000));
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;
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);
}
;
if (Creature* creature = me->SummonCreature(NPC_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0))
{
creature->AddThreat(me->GetVictim(), 1.0f);
creature->AI()->AttackStart(me->GetVictim());
BirdGUIDs[i] = creature->GetGUID();
}
}
}
DoMeleeAttackIfReady();
}
private: