mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 09:17:18 +00:00
fix(Scripts/AQ): Rewrite bug trio fight (#11565)
* fix(Core/AQ): Rewrite bug trio fight * update sql to newest * with a comment * fix build * finish? * build * add evade boundary
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
--
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_vem_knockback', 'spell_vem_vengeance');
|
||||
DELETE FROM `spell_script_names` WHERE `spell_id` = 18670; -- Delete the current script to prevent stacking.
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(18670, 'spell_vem_knockback'),
|
||||
(25790, 'spell_vem_vengeance');
|
||||
|
||||
UPDATE `creature_template` SET `unit_flags` = `unit_flags`|33554432, `flags_extra` = `flags_extra`|128 WHERE `entry` = 15933;
|
||||
|
||||
DELETE FROM `creature_template_addon` WHERE `entry` = 15933;
|
||||
INSERT INTO `creature_template_addon` (`entry`,`auras`) VALUES
|
||||
(15933, '25786 26575');
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` IN (15511, 15543, 15544);
|
||||
INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
|
||||
(15511, 0, 0, '%s is devoured!', 16, 0, 100, 0, 0, 0, 11115, 0, 'Lord Kri - EMOTE_DEVOURED'),
|
||||
(15543, 0, 0, '%s is devoured!', 16, 0, 100, 0, 0, 0, 11115, 0, 'Princess Yauj - EMOTE_DEVOURED'),
|
||||
(15544, 0, 0, '%s is devoured!', 16, 0, 100, 0, 0, 0, 11115, 0, 'Vem - EMOTE_DEVOURED');
|
||||
@@ -15,330 +15,446 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_kri, boss_yauj, boss_vem : The Bug Trio
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CLEAVE = 26350,
|
||||
SPELL_TOXIC_VOLLEY = 25812,
|
||||
SPELL_POISON_CLOUD = 38718, //Only Spell with right dmg.
|
||||
SPELL_ENRAGE = 34624, //Changed cause 25790 is cast on gamers too. Same prob with old explosion of twin emperors.
|
||||
SPELL_BLOODY_DEATH = 25770,
|
||||
SPELL_FULL_HEAL = 17683,
|
||||
|
||||
SPELL_CHARGE = 26561,
|
||||
SPELL_KNOCKBACK = 26027,
|
||||
// Kri
|
||||
SPELL_CLEAVE = 26350,
|
||||
SPELL_THRASH = 3391,
|
||||
SPELL_TOXIC_VOLLEY = 25812,
|
||||
SPELL_POISON_CLOUD = 26590,
|
||||
|
||||
SPELL_HEAL = 25807,
|
||||
SPELL_FEAR = 19408
|
||||
// Vem
|
||||
SPELL_CHARGE = 26561,
|
||||
SPELL_KNOCKBACK = 18670,
|
||||
SPELL_KNOCKDOWN = 19128,
|
||||
SPELL_VENGEANCE = 25790,
|
||||
|
||||
// Yauj
|
||||
SPELL_HEAL = 25807,
|
||||
SPELL_FEAR = 26580,
|
||||
SPELL_RAVAGE = 3242,
|
||||
SPELL_DISPEL = 25808,
|
||||
|
||||
NPC_YAUJ_BROOD = 15621
|
||||
};
|
||||
|
||||
class boss_kri : public CreatureScript
|
||||
enum Misc
|
||||
{
|
||||
public:
|
||||
boss_kri() : CreatureScript("boss_kri") { }
|
||||
ACTION_CONSUME = 0,
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTempleOfAhnQirajAI<boss_kriAI>(creature);
|
||||
}
|
||||
EMOTE_DEVOURED = 0,
|
||||
|
||||
struct boss_kriAI : public ScriptedAI
|
||||
{
|
||||
boss_kriAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
POINT_CONSUME = 0,
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Cleave_Timer;
|
||||
uint32 ToxicVolley_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool VemDead;
|
||||
bool Death;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Cleave_Timer = urand(4000, 8000);
|
||||
ToxicVolley_Timer = urand(6000, 12000);
|
||||
Check_Timer = 2000;
|
||||
|
||||
VemDead = false;
|
||||
Death = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
||||
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
|
||||
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
}
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Cleave_Timer
|
||||
if (Cleave_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
Cleave_Timer = urand(5000, 12000);
|
||||
}
|
||||
else Cleave_Timer -= diff;
|
||||
|
||||
//ToxicVolley_Timer
|
||||
if (ToxicVolley_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_TOXIC_VOLLEY);
|
||||
ToxicVolley_Timer = urand(10000, 15000);
|
||||
}
|
||||
else ToxicVolley_Timer -= diff;
|
||||
|
||||
if (!HealthAbovePct(5) && !Death)
|
||||
{
|
||||
DoCastVictim(SPELL_POISON_CLOUD);
|
||||
Death = true;
|
||||
}
|
||||
|
||||
if (!VemDead)
|
||||
{
|
||||
//Checking if Vem is dead. If yes we will enrage.
|
||||
if (Check_Timer <= diff)
|
||||
{
|
||||
if (instance->GetData(DATA_VEMISDEAD))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
VemDead = true;
|
||||
}
|
||||
Check_Timer = 2000;
|
||||
}
|
||||
else Check_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
VEM_WAYPOINT_PATH = 876030
|
||||
};
|
||||
|
||||
class boss_vem : public CreatureScript
|
||||
const Position resetPoint = { -8582.0f, 2047.0f, -1.62f }; // Taken from CMangos
|
||||
|
||||
struct boss_bug_trio : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_vem() : CreatureScript("boss_vem") { }
|
||||
boss_bug_trio(Creature* creature) : BossAI(creature, DATA_BUG_TRIO) { Reset(); }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
bool CheckInRoom() override
|
||||
{
|
||||
return GetTempleOfAhnQirajAI<boss_vemAI>(creature);
|
||||
if (me->GetExactDist2d(resetPoint) <= 10.f)
|
||||
{
|
||||
EnterEvadeMode(EVADE_REASON_BOUNDARY);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct boss_vemAI : public ScriptedAI
|
||||
void EnterCombatWithTrio(Unit* who)
|
||||
{
|
||||
boss_vemAI(Creature* creature) : ScriptedAI(creature)
|
||||
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM)))
|
||||
if (vem->GetGUID() != me->GetGUID())
|
||||
vem->GetAI()->AttackStart(who);
|
||||
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
|
||||
if (kri->GetGUID() != me->GetGUID())
|
||||
kri->GetAI()->AttackStart(who);
|
||||
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ)))
|
||||
if (yauj->GetGUID() != me->GetGUID())
|
||||
yauj->GetAI()->AttackStart(who);
|
||||
}
|
||||
|
||||
void EvadeAllBosses(EvadeReason why)
|
||||
{
|
||||
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM)))
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
if (vem->GetGUID() != me->GetGUID())
|
||||
{
|
||||
if (vem->IsAlive() && !vem->IsInEvadeMode())
|
||||
vem->AI()->EnterEvadeMode(why);
|
||||
else
|
||||
vem->Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Charge_Timer;
|
||||
uint32 KnockBack_Timer;
|
||||
uint32 Enrage_Timer;
|
||||
|
||||
bool Enraged;
|
||||
|
||||
void Reset() override
|
||||
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
|
||||
{
|
||||
Charge_Timer = urand(15000, 27000);
|
||||
KnockBack_Timer = urand(8000, 20000);
|
||||
Enrage_Timer = 120000;
|
||||
|
||||
Enraged = false;
|
||||
if (kri->GetGUID() != me->GetGUID())
|
||||
{
|
||||
if (kri->IsAlive() && !kri->IsInEvadeMode())
|
||||
kri->AI()->EnterEvadeMode(why);
|
||||
else
|
||||
kri->Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ)))
|
||||
{
|
||||
instance->SetData(DATA_VEM_DEATH, 0);
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
||||
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
if (yauj->GetGUID() != me->GetGUID())
|
||||
{
|
||||
if (yauj->IsAlive() && !yauj->IsInEvadeMode())
|
||||
yauj->AI()->EnterEvadeMode(why);
|
||||
else
|
||||
yauj->Respawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action != ACTION_CONSUME || dying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
}
|
||||
isEating = true;
|
||||
me->SetSpeed(MOVE_RUN, 45.f/7.f); // From sniffs
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void MovementInform(uint32 type, uint32 /*id*/) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->SetSpeed(MOVE_RUN, 15.f/7.f); // From sniffs
|
||||
DoCastSelf(SPELL_FULL_HEAL, true);
|
||||
DoResetThreat();
|
||||
isEating = false;
|
||||
|
||||
_scheduler.Schedule(4s, [this](TaskContext /*context*/)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (Unit* target = me->GetVictim())
|
||||
{
|
||||
me->GetMotionMaster()->MoveChase(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
BossAI::EnterEvadeMode(why);
|
||||
EvadeAllBosses(why);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
_scheduler.CancelAll();
|
||||
dying = false;
|
||||
isEating = false;
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 0);
|
||||
me->SetSpeed(MOVE_RUN, 15.f / 7.f); // From sniffs
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
|
||||
if (me->GetEntry() == NPC_VEM)
|
||||
{
|
||||
me->GetMotionMaster()->MovePath(VEM_WAYPOINT_PATH, true);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() || isEating || !CheckInRoom())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(1, damage) && instance->GetData(DATA_BUG_TRIO_DEATH) < 2 && who->GetGUID() != me->GetGUID())
|
||||
{
|
||||
damage = 0;
|
||||
if (isEating)
|
||||
return;
|
||||
|
||||
//Charge_Timer
|
||||
if (Charge_Timer <= diff)
|
||||
_scheduler.CancelAll();
|
||||
me->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
|
||||
DoFinalSpell();
|
||||
|
||||
// Move the other bugs to this bug position
|
||||
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM)))
|
||||
{
|
||||
Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
|
||||
if (target)
|
||||
if (vem->GetGUID() != me->GetGUID())
|
||||
{
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
//me->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true, 1);
|
||||
AttackStart(target);
|
||||
vem->AI()->DoAction(ACTION_CONSUME);
|
||||
vem->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
|
||||
}
|
||||
|
||||
Charge_Timer = urand(8000, 16000);
|
||||
}
|
||||
else Charge_Timer -= diff;
|
||||
|
||||
//KnockBack_Timer
|
||||
if (KnockBack_Timer <= diff)
|
||||
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
|
||||
{
|
||||
DoCastVictim(SPELL_KNOCKBACK);
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(me->GetVictim(), -80);
|
||||
KnockBack_Timer = urand(15000, 25000);
|
||||
if (kri->GetGUID() != me->GetGUID())
|
||||
{
|
||||
kri->AI()->DoAction(ACTION_CONSUME);
|
||||
kri->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
|
||||
}
|
||||
}
|
||||
else KnockBack_Timer -= diff;
|
||||
|
||||
//Enrage_Timer
|
||||
if (!Enraged && Enrage_Timer <= diff)
|
||||
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ)))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
if (yauj->GetGUID() != me->GetGUID())
|
||||
{
|
||||
yauj->AI()->DoAction(ACTION_CONSUME);
|
||||
yauj->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
|
||||
}
|
||||
}
|
||||
else Charge_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
_scheduler.Schedule(4s, [this](TaskContext /*context*/)
|
||||
{
|
||||
if (!me->IsInEvadeMode())
|
||||
{
|
||||
DoCastSelf(SPELL_BLOODY_DEATH, true);
|
||||
Talk(EMOTE_DEVOURED);
|
||||
me->DespawnOrUnsummon(1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void DoFinalSpell()
|
||||
{
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_KRI:
|
||||
DoCastSelf(SPELL_POISON_CLOUD, true);
|
||||
break;
|
||||
case NPC_VEM:
|
||||
DoCastSelf(SPELL_VENGEANCE, true);
|
||||
break;
|
||||
case NPC_YAUJ:
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
{
|
||||
Position randomPos;
|
||||
me->GetRandomContactPoint(me, randomPos.m_positionX, randomPos.m_positionY, randomPos.m_positionZ);
|
||||
if (Creature* summon = me->SummonCreature(NPC_YAUJ_BROOD, randomPos))
|
||||
DoZoneInCombat(summon);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
if (killer->GetGUID() == me->GetGUID())
|
||||
{
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
TaskScheduler _scheduler;
|
||||
bool dying;
|
||||
bool isEating;
|
||||
};
|
||||
|
||||
class boss_yauj : public CreatureScript
|
||||
struct boss_kri : public boss_bug_trio
|
||||
{
|
||||
public:
|
||||
boss_yauj() : CreatureScript("boss_yauj") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_kri(Creature* creature) : boss_bug_trio(creature)
|
||||
{
|
||||
return GetTempleOfAhnQirajAI<boss_yaujAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_yaujAI : public ScriptedAI
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
boss_yaujAI(Creature* creature) : ScriptedAI(creature)
|
||||
EnterCombatWithTrio(who);
|
||||
|
||||
_scheduler.Schedule(4s, 8s, [this](TaskContext context)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Heal_Timer;
|
||||
uint32 Fear_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool VemDead;
|
||||
|
||||
void Reset() override
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
context.Repeat(5s, 12s);
|
||||
})
|
||||
.Schedule(6s, 30s, [this](TaskContext context)
|
||||
{
|
||||
Heal_Timer = urand(25000, 40000);
|
||||
Fear_Timer = urand(12000, 24000);
|
||||
Check_Timer = 2000;
|
||||
|
||||
VemDead = false;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
DoCastVictim(SPELL_TOXIC_VOLLEY);
|
||||
context.Repeat(10s, 25s);
|
||||
})
|
||||
.Schedule(6s, [this](TaskContext context)
|
||||
{
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
||||
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
DoCastVictim(SPELL_THRASH);
|
||||
context.Repeat(2s, 6s);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
struct boss_vem : public boss_bug_trio
|
||||
{
|
||||
boss_vem(Creature* creature) : boss_bug_trio(creature)
|
||||
{
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
EnterCombatWithTrio(who);
|
||||
|
||||
_scheduler.Schedule(15s, 27s, [this](TaskContext context)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, [this](Unit* target) -> bool
|
||||
{
|
||||
if (Creature* Summoned = me->SummonCreature(15621, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000))
|
||||
Summoned->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
if (me->IsWithinMeleeRange(target) || target == me->GetVictim())
|
||||
return false;
|
||||
if (!me->IsWithinLOS(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()))
|
||||
return false;
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
return true;
|
||||
}))
|
||||
{
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
}
|
||||
context.Repeat(8s, 16s);
|
||||
})
|
||||
.Schedule(10s, 20s, [this](TaskContext context)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
DoCastVictim(SPELL_KNOCKBACK);
|
||||
context.Repeat(10s, 20s);
|
||||
})
|
||||
.Schedule(5s, 8s, [this](TaskContext context)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Fear_Timer
|
||||
if (Fear_Timer <= diff)
|
||||
DoCastVictim(SPELL_KNOCKDOWN);
|
||||
context.Repeat(15s, 20s);
|
||||
})
|
||||
.Schedule(1s, [this](TaskContext context)
|
||||
{
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) == 2 && !me->HasAura(SPELL_VENGEANCE)) // Vem is the only one left.
|
||||
{
|
||||
DoCastVictim(SPELL_FEAR);
|
||||
DoResetThreat();
|
||||
Fear_Timer = 20000;
|
||||
DoCastSelf(SPELL_VENGEANCE, true);
|
||||
}
|
||||
else Fear_Timer -= diff;
|
||||
context.Repeat(1s);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//Casting Heal to other twins or herself.
|
||||
if (Heal_Timer <= diff)
|
||||
struct boss_yauj : public boss_bug_trio
|
||||
{
|
||||
boss_yauj(Creature* creature) : boss_bug_trio(creature)
|
||||
{
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
EnterCombatWithTrio(who);
|
||||
|
||||
_scheduler.Schedule(20s, 30s, [this](TaskContext context)
|
||||
{
|
||||
if (me->GetHealthPct() <= 93.f)
|
||||
{
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
|
||||
DoCast(kri, SPELL_HEAL);
|
||||
break;
|
||||
case 1:
|
||||
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM)))
|
||||
DoCast(vem, SPELL_HEAL);
|
||||
break;
|
||||
case 2:
|
||||
DoCast(me, SPELL_HEAL);
|
||||
break;
|
||||
}
|
||||
|
||||
Heal_Timer = 15000 + rand() % 15000;
|
||||
DoCastSelf(SPELL_HEAL);
|
||||
}
|
||||
else Heal_Timer -= diff;
|
||||
|
||||
//Checking if Vem is dead. If yes we will enrage.
|
||||
if (Check_Timer <= diff)
|
||||
else if (Unit* friendly = DoSelectLowestHpFriendly(100.f))
|
||||
{
|
||||
if (!VemDead)
|
||||
{
|
||||
if (instance->GetData(DATA_VEMISDEAD))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
VemDead = true;
|
||||
}
|
||||
}
|
||||
Check_Timer = 2000;
|
||||
DoCast(friendly, SPELL_HEAL);
|
||||
}
|
||||
else Check_Timer -= diff;
|
||||
context.Repeat(10s, 30s);
|
||||
})
|
||||
.Schedule(12s, 24s, [this](TaskContext context)
|
||||
{
|
||||
DoCastAOE(SPELL_FEAR);
|
||||
DoResetThreat();
|
||||
context.Repeat(20s);
|
||||
})
|
||||
.Schedule(12s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_RAVAGE);
|
||||
context.Repeat(10s, 15s);
|
||||
})
|
||||
.Schedule(10s, 30s, [this](TaskContext context)
|
||||
{
|
||||
std::list<Creature*> targets = DoFindFriendlyCC(50.f);
|
||||
if (!targets.empty())
|
||||
{
|
||||
if (Creature* target = *(targets.begin()))
|
||||
me->CastSpell(target, SPELL_DISPEL);
|
||||
}
|
||||
context.Repeat(10s, 15s);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
class spell_vem_knockback : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_vem_knockback);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (Unit* target = GetHitUnit())
|
||||
{
|
||||
if (Creature* cCaster = GetCaster()->ToCreature())
|
||||
{
|
||||
cCaster->getThreatMgr().modifyThreatPercent(target, -80);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_vem_knockback::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_vem_vengeance : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_vem_vengeance);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if([&](WorldObject const* target) -> bool
|
||||
{
|
||||
return target->GetEntry() != NPC_YAUJ && target->GetEntry() != NPC_VEM && target->GetEntry() != NPC_KRI;
|
||||
});
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_vem_vengeance::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_bug_trio()
|
||||
{
|
||||
new boss_kri();
|
||||
new boss_vem();
|
||||
new boss_yauj();
|
||||
RegisterCreatureAI(boss_kri);
|
||||
RegisterCreatureAI(boss_vem);
|
||||
RegisterCreatureAI(boss_yauj);
|
||||
RegisterSpellScript(spell_vem_knockback);
|
||||
RegisterSpellScript(spell_vem_vengeance);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
ObjectGuid SkeramGUID;
|
||||
ObjectGuid VemGUID;
|
||||
ObjectGuid KriGUID;
|
||||
ObjectGuid YaujGUID;
|
||||
ObjectGuid VeklorGUID;
|
||||
ObjectGuid VeknilashGUID;
|
||||
ObjectGuid ViscidusGUID;
|
||||
@@ -88,6 +89,9 @@ public:
|
||||
case NPC_KRI:
|
||||
KriGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_YAUJ:
|
||||
YaujGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VEKLOR:
|
||||
VeklorGUID = creature->GetGUID();
|
||||
break;
|
||||
@@ -106,11 +110,6 @@ public:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_VEMISDEAD:
|
||||
if (IsBossDied[0])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case DATA_VEKLORISDEAD:
|
||||
if (IsBossDied[1])
|
||||
return 1;
|
||||
@@ -140,6 +139,8 @@ public:
|
||||
return VemGUID;
|
||||
case DATA_KRI:
|
||||
return KriGUID;
|
||||
case DATA_YAUJ:
|
||||
return YaujGUID;
|
||||
case DATA_VEKLOR:
|
||||
return VeklorGUID;
|
||||
case DATA_VEKNILASH:
|
||||
@@ -155,12 +156,11 @@ public:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_VEM_DEATH:
|
||||
IsBossDied[0] = true;
|
||||
break;
|
||||
|
||||
case DATA_BUG_TRIO_DEATH:
|
||||
++BugTrioDeathCount;
|
||||
if (data != 0)
|
||||
++BugTrioDeathCount;
|
||||
else
|
||||
BugTrioDeathCount = 0;
|
||||
break;
|
||||
|
||||
case DATA_VEKLOR_DEATH:
|
||||
|
||||
@@ -27,8 +27,8 @@ enum DataTypes
|
||||
DATA_SKERAM = 1,
|
||||
DATA_KRI = 2,
|
||||
DATA_VEM = 3,
|
||||
DATA_VEMISDEAD = 4,
|
||||
DATA_VEM_DEATH = 5,
|
||||
DATA_YAUJ = 4,
|
||||
DATA_BUG_TRIO = 5,
|
||||
DATA_VEKLOR = 6,
|
||||
DATA_VEKLORISDEAD = 7,
|
||||
DATA_VEKLOR_DEATH = 8,
|
||||
@@ -60,6 +60,7 @@ enum Creatures
|
||||
NPC_SKERAM = 15263,
|
||||
NPC_VEM = 15544,
|
||||
NPC_KRI = 15511,
|
||||
NPC_YAUJ = 15543,
|
||||
NPC_VEKLOR = 15276,
|
||||
NPC_VEKNILASH = 15275,
|
||||
NPC_OURO = 15517,
|
||||
|
||||
Reference in New Issue
Block a user