mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-24 14:16:31 +00:00
Merge branch 'master' into Playerbot
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include "CreatureScript.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "ScriptedCreature.h"
|
||||
@@ -85,6 +86,8 @@ enum qruseoftheAshtongue
|
||||
QUEST_RUSE_OF_THE_ASHTONGUE = 10946,
|
||||
};
|
||||
|
||||
const float INNER_CIRCLE_RADIUS = 60.0f;
|
||||
|
||||
struct boss_alar : public BossAI
|
||||
{
|
||||
|
||||
@@ -109,6 +112,7 @@ struct boss_alar : public BossAI
|
||||
_baseAttackOverride = false;
|
||||
_spawnPhoenixes = false;
|
||||
_platform = 0;
|
||||
_noMelee = false;
|
||||
_platformRoll = 0;
|
||||
_noQuillTimes = 0;
|
||||
_platformMoveRepeatTimer = 16s;
|
||||
@@ -135,7 +139,7 @@ struct boss_alar : public BossAI
|
||||
if (_noQuillTimes++ > 0)
|
||||
{
|
||||
me->SetOrientation(alarPoints[_platform].GetOrientation());
|
||||
SpawnPhoenixes(1, me);
|
||||
SpawnPhoenixes(1, me, false);
|
||||
}
|
||||
me->GetMotionMaster()->MovePoint(POINT_PLATFORM, alarPoints[_platform], false, true);
|
||||
_platform = (_platform+1)%4;
|
||||
@@ -191,6 +195,7 @@ struct boss_alar : public BossAI
|
||||
ScheduleUniqueTimedEvent(16001ms, [&]{
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
_noMelee = false;
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
_platform = POINT_MIDDLE;
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
@@ -201,6 +206,7 @@ struct boss_alar : public BossAI
|
||||
|
||||
void PretendToDie(Creature* creature)
|
||||
{
|
||||
_noMelee = true;
|
||||
scheduler.CancelAll();
|
||||
creature->InterruptNonMeleeSpells(true);
|
||||
creature->RemoveAllAuras();
|
||||
@@ -229,11 +235,11 @@ struct boss_alar : public BossAI
|
||||
me->SummonCreature(NPC_FLAME_PATCH, *target, TEMPSUMMON_TIMED_DESPAWN, 2 * MINUTE * IN_MILLISECONDS);
|
||||
}
|
||||
}, 30s);
|
||||
ScheduleTimedEvent(30s, [&]
|
||||
ScheduleTimedEvent(50s, [&]
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(POINT_DIVE, alarPoints[POINT_DIVE], false, true);
|
||||
scheduler.DelayAll(15s);
|
||||
}, 30s);
|
||||
}, 50s);
|
||||
ScheduleUniqueTimedEvent(10min, [&]
|
||||
{
|
||||
DoCastSelf(SPELL_BERSERK);
|
||||
@@ -241,24 +247,33 @@ struct boss_alar : public BossAI
|
||||
ScheduleMainSpellAttack(0s);
|
||||
}
|
||||
|
||||
void SpawnPhoenixes(uint8 count, Unit* targetToSpawnAt)
|
||||
void SpawnPhoenixes(uint8 count, Unit* targetToSpawnAt, bool onPosition)
|
||||
{
|
||||
if (targetToSpawnAt)
|
||||
{
|
||||
for (uint8 i = 0; i < count; ++i)
|
||||
{
|
||||
me->SummonCreature(NPC_EMBER_OF_ALAR, *targetToSpawnAt, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 6000);
|
||||
if (onPosition)
|
||||
{
|
||||
Position spawnPosition = DeterminePhoenixPosition(targetToSpawnAt->GetPosition());
|
||||
me->SummonCreature(NPC_EMBER_OF_ALAR, spawnPosition, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 6000);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SummonCreature(NPC_EMBER_OF_ALAR, *targetToSpawnAt, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 6000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoDiveBomb()
|
||||
{
|
||||
_noMelee = true;
|
||||
scheduler.Schedule(2s, [this](TaskContext)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 10.0f, true))
|
||||
{
|
||||
SpawnPhoenixes(2, target);
|
||||
SpawnPhoenixes(2, target, true);
|
||||
}
|
||||
}).Schedule(6s, [this](TaskContext)
|
||||
{
|
||||
@@ -267,6 +282,7 @@ struct boss_alar : public BossAI
|
||||
}).Schedule(10s, [this](TaskContext)
|
||||
{
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
_noMelee = false;
|
||||
});
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 90.0f, true))
|
||||
{
|
||||
@@ -341,10 +357,61 @@ struct boss_alar : public BossAI
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
scheduler.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_noMelee)
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
Position DeterminePhoenixPosition(Position playerPosition)
|
||||
{
|
||||
// set finalPosition to playerPosition in case the fraction fails
|
||||
Position finalPosition = playerPosition;
|
||||
float playerXPosition = playerPosition.GetPositionX();
|
||||
float playerYPosition = playerPosition.GetPositionY();
|
||||
float centreXPosition = alarPoints[POINT_MIDDLE].GetPositionX();
|
||||
float centreYPosition = alarPoints[POINT_MIDDLE].GetPositionY();
|
||||
float deltaX = std::abs(playerXPosition-centreXPosition);
|
||||
float deltaY = std::abs(playerYPosition-centreYPosition);
|
||||
int8 signMultiplier[2] = {1, 1};
|
||||
// if fraction has x position 0.0f we get nan as a result
|
||||
if (float playerFraction = deltaX/deltaY)
|
||||
{
|
||||
// player angle based on delta X and delta Y
|
||||
float playerAngle = std::atan(playerFraction);
|
||||
float phoenixDeltaYPosition = std::cos(playerAngle)*INNER_CIRCLE_RADIUS;
|
||||
float phoenixDeltaXPosition = std::sin(playerAngle)*INNER_CIRCLE_RADIUS;
|
||||
// as calculations are absolute values we have to multiply in the end
|
||||
// should be negative if player position was further down than centre
|
||||
if (playerXPosition < centreXPosition)
|
||||
signMultiplier[0] = -1;
|
||||
if (playerYPosition < centreYPosition)
|
||||
signMultiplier[1] = -1;
|
||||
// phoenix position based on set distance
|
||||
finalPosition = {centreXPosition+signMultiplier[0]*phoenixDeltaXPosition, centreYPosition+signMultiplier[1]*phoenixDeltaYPosition, 0.0f, 0.0f};
|
||||
}
|
||||
return finalPosition;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _canAttackCooldown;
|
||||
bool _baseAttackOverride;
|
||||
bool _spawnPhoenixes;
|
||||
bool _noMelee;
|
||||
uint8 _platform;
|
||||
uint8 _platformRoll;
|
||||
uint8 _noQuillTimes;
|
||||
|
||||
@@ -23,12 +23,10 @@
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SUMMON1 = 1,
|
||||
SAY_SUMMON2 = 2,
|
||||
SAY_KILL = 3,
|
||||
SAY_DEATH = 4,
|
||||
SAY_VOIDA = 5,
|
||||
SAY_VOIDB = 6
|
||||
SAY_SUMMON = 1,
|
||||
SAY_KILL = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_VOID = 4
|
||||
};
|
||||
|
||||
enum Spells
|
||||
@@ -59,7 +57,13 @@ enum Misc
|
||||
|
||||
struct boss_high_astromancer_solarian : public BossAI
|
||||
{
|
||||
boss_high_astromancer_solarian(Creature* creature) : BossAI(creature, DATA_ASTROMANCER) { }
|
||||
boss_high_astromancer_solarian(Creature* creature) : BossAI(creature, DATA_ASTROMANCER)
|
||||
{
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -68,6 +72,8 @@ struct boss_high_astromancer_solarian : public BossAI
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
ScheduleHealthCheckEvent(20, [&]{
|
||||
Talk(SAY_VOID);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
scheduler.CancelAll();
|
||||
me->ResumeChasingVictim();
|
||||
scheduler.Schedule(3s, [this](TaskContext context)
|
||||
@@ -116,7 +122,7 @@ struct boss_high_astromancer_solarian : public BossAI
|
||||
scheduler.Schedule(3650ms, [this](TaskContext context)
|
||||
{
|
||||
me->GetMotionMaster()->Clear();
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true))
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true, true, -SPELL_WRATH_OF_THE_ASTROMANCER))
|
||||
{
|
||||
DoCast(target, SPELL_ARCANE_MISSILES);
|
||||
}
|
||||
@@ -138,11 +144,11 @@ struct boss_high_astromancer_solarian : public BossAI
|
||||
}).Schedule(52100ms, [this](TaskContext context)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
Talk(SAY_SUMMON);
|
||||
me->SetModelVisible(false);
|
||||
scheduler.DelayAll(21s);
|
||||
scheduler.Schedule(6s, [this](TaskContext)
|
||||
{
|
||||
Talk(SAY_SUMMON1);
|
||||
summons.DoForAllSummons([&](WorldObject* summon)
|
||||
{
|
||||
if (Creature* light = summon->ToCreature())
|
||||
@@ -164,7 +170,6 @@ struct boss_high_astromancer_solarian : public BossAI
|
||||
}).Schedule(20s, [this](TaskContext)
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
Talk(SAY_SUMMON2);
|
||||
summons.DoForAllSummons([&](WorldObject* summon)
|
||||
{
|
||||
if (Creature* light = summon->ToCreature())
|
||||
|
||||
@@ -963,7 +963,7 @@ struct npc_telonicus : public ScriptedAI
|
||||
DoCastVictim(SPELL_BOMB);
|
||||
}, 3600ms, 7100ms);
|
||||
ScheduleTimedEvent(13250ms, [&]{
|
||||
DoCastRandomTarget(SPELL_CONFLAGRATION, 0, 100.0f);
|
||||
DoCastRandomTarget(SPELL_REMOTE_TOY, 0, 100.0f);
|
||||
}, 15750ms);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user