fix(Scripts/TempleOfAhnQiraj): Improve Sartura (#12577)

This commit is contained in:
Eddy Vega
2022-08-13 21:14:50 -06:00
committed by GitHub
parent 9fa35180ea
commit eb4f133865
3 changed files with 282 additions and 262 deletions
@@ -0,0 +1,7 @@
--
UPDATE `creature_formations` SET `dist`=5 WHERE `memberGUID` IN (87649,87650,87651);
DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=26084 AND `spell_effect`=25174 AND `type`=1;
INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES
(26084, 25174, 1, 'Battleguard Sartura - OnHit Whirlwind - Apply Sundering Cleave');
@@ -15,80 +15,88 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Sartura
SD%Complete: 95
SDComment:
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "SpellScript.h"
#include "ScriptedCreature.h" #include "ScriptedCreature.h"
#include "temple_of_ahnqiraj.h" #include "temple_of_ahnqiraj.h"
enum Sartura enum Says
{ {
SAY_AGGRO = 0, SAY_AGGRO = 0,
SAY_SLAY = 1, SAY_SLAY = 1,
SAY_DEATH = 2, SAY_DEATH = 2
SPELL_WHIRLWIND = 26083,
SPELL_ENRAGE = 8269,
SPELL_BERSERK = 27680,
//Guard Spell
SPELL_WHIRLWINDADD = 26038,
SPELL_KNOCKBACK = 26027
}; };
class boss_sartura : public CreatureScript enum Spells
{ {
public: // Battleguard Sartura
boss_sartura() : CreatureScript("boss_sartura") { } SPELL_WHIRLWIND = 26083, // MechanicImmunity->Stunned (15sec)
SPELL_ENRAGE = 8269,
SPELL_BERSERK = 27680,
SPELL_SUNDERING_CLEAVE = 25174,
CreatureAI* GetAI(Creature* creature) const override // Sartura's Royal Guard
{ SPELL_GUARD_WHIRLWIND = 26038,
return GetTempleOfAhnQirajAI<boss_sarturaAI>(creature); SPELL_GUARD_KNOCKBACK = 26027
} };
struct boss_sarturaAI : public ScriptedAI enum events
{ {
boss_sarturaAI(Creature* creature) : ScriptedAI(creature) { } // Battleguard Sartura
EVENT_SARTURA_WHIRLWIND = 1,
EVENT_SARTURA_WHIRLWIND_RANDOM = 2,
EVENT_SARTURA_WHIRLWIND_END = 3,
EVENT_SPELL_BERSERK = 4,
EVENT_SARTURA_AGGRO_RESET = 5,
EVENT_SARTURA_AGGRO_RESET_END = 6,
uint32 WhirlWind_Timer; // Sartura's Royal Guard
uint32 WhirlWindRandom_Timer; EVENT_GUARD_WHIRLWIND = 7,
uint32 WhirlWindEnd_Timer; EVENT_GUARD_WHIRLWIND_RANDOM = 8,
uint32 AggroReset_Timer; EVENT_GUARD_WHIRLWIND_END = 9,
uint32 AggroResetEnd_Timer; EVENT_GUARD_KNOCKBACK = 10,
uint32 EnrageHard_Timer; EVENT_GUARD_AGGRO_RESET = 11,
EVENT_GUARD_AGGRO_RESET_END = 12
};
bool Enraged; struct boss_sartura : public BossAI
bool EnragedHard; {
bool WhirlWind; boss_sartura(Creature* creature) : BossAI(creature, DATA_SARTURA) {}
bool AggroReset;
void Reset() override void Reset() override
{ {
WhirlWind_Timer = 30000; _Reset();
WhirlWindRandom_Timer = urand(3000, 7000); whirlwind = false;
WhirlWindEnd_Timer = 15000; enraged = false;
AggroReset_Timer = urand(45000, 55000); berserked = false;
AggroResetEnd_Timer = 5000; aggroReset = false;
EnrageHard_Timer = 10 * 60000; MinionReset();
_savedTargetGUID.Clear();
WhirlWind = false; _savedTargetThreat = 0.f;
AggroReset = false;
Enraged = false;
EnragedHard = false;
} }
void EnterCombat(Unit* /*who*/) override void MinionReset()
{ {
std::list<Creature*> royalGuards;
me->GetCreaturesWithEntryInRange(royalGuards, 200.0f, NPC_SARTURA_ROYAL_GUARD);
for (Creature* minion : royalGuards)
{
minion->Respawn();
}
}
void EnterCombat(Unit* who) override
{
BossAI::EnterCombat(who);
Talk(SAY_AGGRO); Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND, 30000);
events.ScheduleEvent(EVENT_SARTURA_AGGRO_RESET, urand(45000, 55000));
events.ScheduleEvent(EVENT_SPELL_BERSERK, 10 * 60000);
} }
void JustDied(Unit* /*killer*/) override void JustDied(Unit* /*killer*/) override
{ {
_JustDied();
Talk(SAY_DEATH); Talk(SAY_DEATH);
} }
@@ -97,219 +105,224 @@ public:
Talk(SAY_SLAY); Talk(SAY_SLAY);
} }
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override
{
if (!enraged && HealthBelowPct(20))
{
DoCastSelf(SPELL_ENRAGE);
enraged = true;
}
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
if (spell->Id != SPELL_SUNDERING_CLEAVE)
return;
me->RemoveAura(SPELL_SUNDERING_CLEAVE);
}
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
//Return since we have no target
if (!UpdateVictim()) if (!UpdateVictim())
return; return;
if (WhirlWind) events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{ {
if (WhirlWindRandom_Timer <= diff) switch (eventId)
{
case EVENT_SARTURA_WHIRLWIND:
DoCastSelf(SPELL_WHIRLWIND, true);
whirlwind = true;
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND_RANDOM, urand(3000, 7000));
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND_END, 15000);
break;
case EVENT_SARTURA_WHIRLWIND_RANDOM:
if (whirlwind == true)
{ {
//Attack random Gamers
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true)) if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
{ {
me->AddThreat(target, 1.0f); me->AddThreat(target, 1.0f);
me->TauntApply(target); me->TauntApply(target);
AttackStart(target); AttackStart(target);
} }
WhirlWindRandom_Timer = urand(3000, 7000); events.RepeatEvent(urand(3000, 7000));
} }
else WhirlWindRandom_Timer -= diff; break;
case EVENT_SARTURA_WHIRLWIND_END:
if (WhirlWindEnd_Timer <= diff) events.CancelEvent(EVENT_SARTURA_WHIRLWIND_RANDOM);
whirlwind = false;
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND, urand(25000, 40000));
break;
case EVENT_SARTURA_AGGRO_RESET:
if (aggroReset == false)
{ {
WhirlWind = false; if (Unit* originalTarget = SelectTarget(SelectTargetMethod::Random, 0))
WhirlWind_Timer = urand(25000, 40000); {
_savedTargetGUID = originalTarget->GetGUID();
_savedTargetThreat = me->GetThreatMgr().getThreat(originalTarget);
me->GetThreatMgr().modifyThreatPercent(originalTarget, -100);
} }
else WhirlWindEnd_Timer -= diff; aggroReset = true;
events.ScheduleEvent(EVENT_SARTURA_AGGRO_RESET_END, 5000);
} }
else
if (!WhirlWind)
{ {
if (WhirlWind_Timer <= diff)
{
DoCast(me, SPELL_WHIRLWIND);
WhirlWind = true;
WhirlWindEnd_Timer = 15000;
}
else WhirlWind_Timer -= diff;
if (AggroReset_Timer <= diff)
{
//Attack random Gamers
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true)) if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
{ {
me->AddThreat(target, 1.0f); me->AddThreat(target, 1.0f);
me->TauntApply(target); me->TauntApply(target);
AttackStart(target); AttackStart(target);
} }
AggroReset = true;
AggroReset_Timer = urand(2000, 5000);
} }
else AggroReset_Timer -= diff; events.RepeatEvent(urand(1000, 2000));
break;
if (AggroReset) case EVENT_SARTURA_AGGRO_RESET_END:
events.CancelEvent(EVENT_SARTURA_AGGRO_RESET);
if (Unit* originalTarget = ObjectAccessor::GetUnit(*me, _savedTargetGUID))
{ {
if (AggroResetEnd_Timer <= diff) me->GetThreatMgr().addThreat(originalTarget, _savedTargetThreat);
_savedTargetGUID.Clear();
}
aggroReset = false;
events.RescheduleEvent(EVENT_SARTURA_AGGRO_RESET, urand(30000, 40000));
break;
case EVENT_SPELL_BERSERK:
if (!berserked)
{ {
AggroReset = false; DoCastSelf(SPELL_BERSERK);
AggroResetEnd_Timer = 5000; berserked = true;
AggroReset_Timer = urand(35000, 45000);
} }
else AggroResetEnd_Timer -= diff; break;
} default:
break;
//If she is 20% enrage
if (!Enraged)
{
if (!HealthAbovePct(20) && !me->IsNonMeleeSpellCast(false))
{
DoCast(me, SPELL_ENRAGE, true);
Enraged = true;
} }
} }
//After 10 minutes hard enrage
if (!EnragedHard)
{
if (EnrageHard_Timer <= diff)
{
DoCast(me, SPELL_BERSERK, true);
EnragedHard = true;
}
else EnrageHard_Timer -= diff;
}
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
}
}
}; };
private:
bool whirlwind;
bool enraged;
bool berserked;
bool aggroReset;
ObjectGuid _savedTargetGUID;
float _savedTargetThreat;
}; };
class npc_sartura_royal_guard : public CreatureScript struct npc_sartura_royal_guard : public ScriptedAI
{ {
public: npc_sartura_royal_guard(Creature* creature) : ScriptedAI(creature) {}
npc_sartura_royal_guard() : CreatureScript("npc_sartura_royal_guard") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetTempleOfAhnQirajAI<npc_sartura_royal_guardAI>(creature);
}
struct npc_sartura_royal_guardAI : public ScriptedAI
{
npc_sartura_royal_guardAI(Creature* creature) : ScriptedAI(creature) { }
uint32 WhirlWind_Timer;
uint32 WhirlWindRandom_Timer;
uint32 WhirlWindEnd_Timer;
uint32 AggroReset_Timer;
uint32 AggroResetEnd_Timer;
uint32 KnockBack_Timer;
bool WhirlWind;
bool AggroReset;
void Reset() override void Reset() override
{ {
WhirlWind_Timer = 30000; events.Reset();
WhirlWindRandom_Timer = urand(3000, 7000); whirlwind = false;
WhirlWindEnd_Timer = 15000; aggroReset = false;
AggroReset_Timer = urand(45000, 55000); _savedTargetGUID.Clear();
AggroResetEnd_Timer = 5000; _savedTargetThreat = 0.f;
KnockBack_Timer = 10000;
WhirlWind = false;
AggroReset = false;
} }
void EnterCombat(Unit* /*who*/) override void EnterCombat(Unit* /*who*/) override
{ {
events.ScheduleEvent(EVENT_GUARD_WHIRLWIND, 30000);
events.ScheduleEvent(EVENT_GUARD_AGGRO_RESET, urand(45000, 55000));
events.ScheduleEvent(EVENT_GUARD_KNOCKBACK, 10000);
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
if (spell->Id != SPELL_SUNDERING_CLEAVE)
return;
me->RemoveAura(SPELL_SUNDERING_CLEAVE);
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
//Return since we have no target
if (!UpdateVictim()) if (!UpdateVictim())
return; return;
if (!WhirlWind && WhirlWind_Timer <= diff) events.Update(diff);
{
DoCast(me, SPELL_WHIRLWINDADD);
WhirlWind = true;
WhirlWind_Timer = urand(25000, 40000);
WhirlWindEnd_Timer = 15000;
}
else WhirlWind_Timer -= diff;
if (WhirlWind) while (uint32 eventid = events.ExecuteEvent())
{ {
if (WhirlWindRandom_Timer <= diff) switch (eventid)
{
case EVENT_GUARD_WHIRLWIND:
DoCastSelf(SPELL_GUARD_WHIRLWIND);
whirlwind = true;
events.ScheduleEvent(EVENT_GUARD_WHIRLWIND_RANDOM, urand(3000, 7000));
events.ScheduleEvent(EVENT_GUARD_WHIRLWIND_END, 15000);
break;
case EVENT_GUARD_WHIRLWIND_RANDOM:
if (whirlwind == true)
{ {
//Attack random Gamers
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true)) if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
{ {
me->AddThreat(target, 1.0f); me->AddThreat(target, 1.0f);
me->TauntApply(target); me->TauntApply(target);
AttackStart(target); AttackStart(target);
} }
events.RepeatEvent(urand(3000, 7000));
WhirlWindRandom_Timer = urand(3000, 7000);
} }
else WhirlWindRandom_Timer -= diff; break;
case EVENT_GUARD_WHIRLWIND_END:
if (WhirlWindEnd_Timer <= diff) events.CancelEvent(EVENT_GUARD_WHIRLWIND_RANDOM);
whirlwind = false;
events.ScheduleEvent(EVENT_GUARD_WHIRLWIND, urand(25000, 40000));
break;
case EVENT_GUARD_AGGRO_RESET:
if (aggroReset == true)
{ {
WhirlWind = false; if (Unit* originalTarget = SelectTarget(SelectTargetMethod::Random, 0))
{
_savedTargetGUID = originalTarget->GetGUID();
_savedTargetThreat = me->GetThreatMgr().getThreat(originalTarget);
me->GetThreatMgr().modifyThreatPercent(originalTarget, -100);
} }
else WhirlWindEnd_Timer -= diff; aggroReset = true;
events.ScheduleEvent(EVENT_GUARD_AGGRO_RESET_END, 5000);
} }
else
if (!WhirlWind)
{ {
if (AggroReset_Timer <= diff)
{
//Attack random Gamers
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true)) if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
{ {
me->AddThreat(target, 1.0f); me->AddThreat(target, 1.0f);
me->TauntApply(target); me->TauntApply(target);
AttackStart(target); AttackStart(target);
} }
AggroReset = true;
AggroReset_Timer = urand(2000, 5000);
} }
else AggroReset_Timer -= diff; events.RepeatEvent(urand(1000, 2000));
break;
if (KnockBack_Timer <= diff) case EVENT_GUARD_AGGRO_RESET_END:
events.CancelEvent(EVENT_GUARD_AGGRO_RESET);
if (Unit* originalTarget = ObjectAccessor::GetUnit(*me, _savedTargetGUID))
{ {
DoCast(me, SPELL_WHIRLWINDADD); me->GetThreatMgr().addThreat(originalTarget, _savedTargetThreat);
KnockBack_Timer = urand(10000, 20000); _savedTargetGUID.Clear();
} }
else KnockBack_Timer -= diff; aggroReset = false;
events.RescheduleEvent(EVENT_GUARD_AGGRO_RESET, urand(30000, 40000));
break;
case EVENT_GUARD_KNOCKBACK:
DoCastVictim(SPELL_GUARD_KNOCKBACK);
events.RepeatEvent(urand(10000, 20000));
break;
} }
if (AggroReset)
{
if (AggroResetEnd_Timer <= diff)
{
AggroReset = false;
AggroResetEnd_Timer = 5000;
AggroReset_Timer = urand(30000, 40000);
} }
else AggroResetEnd_Timer -= diff;
}
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
}; private:
bool whirlwind;
bool aggroReset;
ObjectGuid _savedTargetGUID;
float _savedTargetThreat;
}; };
void AddSC_boss_sartura() void AddSC_boss_sartura()
{ {
new boss_sartura(); RegisterTempleOfAhnQirajCreatureAI(boss_sartura);
new npc_sartura_royal_guard(); RegisterTempleOfAhnQirajCreatureAI(npc_sartura_royal_guard);
} }
@@ -56,7 +56,7 @@ enum Creatures
NPC_GIANT_EYE_TENTACLE = 15334, NPC_GIANT_EYE_TENTACLE = 15334,
NPC_FLESH_TENTACLE = 15802, NPC_FLESH_TENTACLE = 15802,
NPC_GIANT_PORTAL = 15910, NPC_GIANT_PORTAL = 15910,
NPC_SARTURA_ROYAL_GUARD = 15984,
NPC_VISCIDUS = 15299, NPC_VISCIDUS = 15299,
NPC_GLOB_OF_VISCIDUS = 15667, NPC_GLOB_OF_VISCIDUS = 15667,