mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-08 15:58:04 +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/>.
|
* 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 "ScriptMgr.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
|
#include "SpellScript.h"
|
||||||
#include "temple_of_ahnqiraj.h"
|
#include "temple_of_ahnqiraj.h"
|
||||||
|
#include "TaskScheduler.h"
|
||||||
|
|
||||||
enum Spells
|
enum Spells
|
||||||
{
|
{
|
||||||
SPELL_CLEAVE = 26350,
|
SPELL_BLOODY_DEATH = 25770,
|
||||||
SPELL_TOXIC_VOLLEY = 25812,
|
SPELL_FULL_HEAL = 17683,
|
||||||
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_CHARGE = 26561,
|
// Kri
|
||||||
SPELL_KNOCKBACK = 26027,
|
SPELL_CLEAVE = 26350,
|
||||||
|
SPELL_THRASH = 3391,
|
||||||
|
SPELL_TOXIC_VOLLEY = 25812,
|
||||||
|
SPELL_POISON_CLOUD = 26590,
|
||||||
|
|
||||||
SPELL_HEAL = 25807,
|
// Vem
|
||||||
SPELL_FEAR = 19408
|
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:
|
ACTION_CONSUME = 0,
|
||||||
boss_kri() : CreatureScript("boss_kri") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
EMOTE_DEVOURED = 0,
|
||||||
{
|
|
||||||
return GetTempleOfAhnQirajAI<boss_kriAI>(creature);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct boss_kriAI : public ScriptedAI
|
POINT_CONSUME = 0,
|
||||||
{
|
|
||||||
boss_kriAI(Creature* creature) : ScriptedAI(creature)
|
|
||||||
{
|
|
||||||
instance = creature->GetInstanceScript();
|
|
||||||
}
|
|
||||||
|
|
||||||
InstanceScript* instance;
|
VEM_WAYPOINT_PATH = 876030
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_vem : public CreatureScript
|
const Position resetPoint = { -8582.0f, 2047.0f, -1.62f }; // Taken from CMangos
|
||||||
|
|
||||||
|
struct boss_bug_trio : public BossAI
|
||||||
{
|
{
|
||||||
public:
|
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;
|
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
|
||||||
|
|
||||||
uint32 Charge_Timer;
|
|
||||||
uint32 KnockBack_Timer;
|
|
||||||
uint32 Enrage_Timer;
|
|
||||||
|
|
||||||
bool Enraged;
|
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
{
|
||||||
Charge_Timer = urand(15000, 27000);
|
if (kri->GetGUID() != me->GetGUID())
|
||||||
KnockBack_Timer = urand(8000, 20000);
|
{
|
||||||
Enrage_Timer = 120000;
|
if (kri->IsAlive() && !kri->IsInEvadeMode())
|
||||||
|
kri->AI()->EnterEvadeMode(why);
|
||||||
Enraged = false;
|
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 (yauj->GetGUID() != me->GetGUID())
|
||||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
{
|
||||||
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
|
if (yauj->IsAlive() && !yauj->IsInEvadeMode())
|
||||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
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
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
if (!UpdateVictim())
|
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;
|
return;
|
||||||
|
|
||||||
//Charge_Timer
|
_scheduler.CancelAll();
|
||||||
if (Charge_Timer <= diff)
|
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 (vem->GetGUID() != me->GetGUID())
|
||||||
if (target)
|
|
||||||
{
|
{
|
||||||
DoCast(target, SPELL_CHARGE);
|
vem->AI()->DoAction(ACTION_CONSUME);
|
||||||
//me->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true, 1);
|
vem->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
|
||||||
AttackStart(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Charge_Timer = urand(8000, 16000);
|
|
||||||
}
|
}
|
||||||
else Charge_Timer -= diff;
|
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
|
||||||
|
|
||||||
//KnockBack_Timer
|
|
||||||
if (KnockBack_Timer <= diff)
|
|
||||||
{
|
{
|
||||||
DoCastVictim(SPELL_KNOCKBACK);
|
if (kri->GetGUID() != me->GetGUID())
|
||||||
if (DoGetThreat(me->GetVictim()))
|
{
|
||||||
DoModifyThreatPercent(me->GetVictim(), -80);
|
kri->AI()->DoAction(ACTION_CONSUME);
|
||||||
KnockBack_Timer = urand(15000, 25000);
|
kri->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else KnockBack_Timer -= diff;
|
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ)))
|
||||||
|
|
||||||
//Enrage_Timer
|
|
||||||
if (!Enraged && Enrage_Timer <= diff)
|
|
||||||
{
|
{
|
||||||
DoCast(me, SPELL_ENRAGE);
|
if (yauj->GetGUID() != me->GetGUID())
|
||||||
Enraged = true;
|
{
|
||||||
|
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_kri(Creature* creature) : boss_bug_trio(creature)
|
||||||
boss_yauj() : CreatureScript("boss_yauj") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
{
|
||||||
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();
|
DoCastVictim(SPELL_CLEAVE);
|
||||||
}
|
context.Repeat(5s, 12s);
|
||||||
|
})
|
||||||
InstanceScript* instance;
|
.Schedule(6s, 30s, [this](TaskContext context)
|
||||||
|
|
||||||
uint32 Heal_Timer;
|
|
||||||
uint32 Fear_Timer;
|
|
||||||
uint32 Check_Timer;
|
|
||||||
|
|
||||||
bool VemDead;
|
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
{
|
||||||
Heal_Timer = urand(25000, 40000);
|
DoCastVictim(SPELL_TOXIC_VOLLEY);
|
||||||
Fear_Timer = urand(12000, 24000);
|
context.Repeat(10s, 25s);
|
||||||
Check_Timer = 2000;
|
})
|
||||||
|
.Schedule(6s, [this](TaskContext context)
|
||||||
VemDead = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
{
|
||||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
DoCastVictim(SPELL_THRASH);
|
||||||
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
|
context.Repeat(2s, 6s);
|
||||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (uint8 i = 0; i < 10; ++i)
|
struct boss_vem : public boss_bug_trio
|
||||||
{
|
{
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
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))
|
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||||
Summoned->AI()->AttackStart(target);
|
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)
|
||||||
{
|
{
|
||||||
}
|
DoCastVictim(SPELL_KNOCKBACK);
|
||||||
|
context.Repeat(10s, 20s);
|
||||||
void UpdateAI(uint32 diff) override
|
})
|
||||||
|
.Schedule(5s, 8s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
//Return since we have no target
|
DoCastVictim(SPELL_KNOCKDOWN);
|
||||||
if (!UpdateVictim())
|
context.Repeat(15s, 20s);
|
||||||
return;
|
})
|
||||||
|
.Schedule(1s, [this](TaskContext context)
|
||||||
//Fear_Timer
|
{
|
||||||
if (Fear_Timer <= diff)
|
if (instance->GetData(DATA_BUG_TRIO_DEATH) == 2 && !me->HasAura(SPELL_VENGEANCE)) // Vem is the only one left.
|
||||||
{
|
{
|
||||||
DoCastVictim(SPELL_FEAR);
|
DoCastSelf(SPELL_VENGEANCE, true);
|
||||||
DoResetThreat();
|
|
||||||
Fear_Timer = 20000;
|
|
||||||
}
|
}
|
||||||
else Fear_Timer -= diff;
|
context.Repeat(1s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//Casting Heal to other twins or herself.
|
struct boss_yauj : public boss_bug_trio
|
||||||
if (Heal_Timer <= diff)
|
{
|
||||||
|
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))
|
DoCastSelf(SPELL_HEAL);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
else Heal_Timer -= diff;
|
else if (Unit* friendly = DoSelectLowestHpFriendly(100.f))
|
||||||
|
|
||||||
//Checking if Vem is dead. If yes we will enrage.
|
|
||||||
if (Check_Timer <= diff)
|
|
||||||
{
|
{
|
||||||
if (!VemDead)
|
DoCast(friendly, SPELL_HEAL);
|
||||||
{
|
|
||||||
if (instance->GetData(DATA_VEMISDEAD))
|
|
||||||
{
|
|
||||||
DoCast(me, SPELL_ENRAGE);
|
|
||||||
VemDead = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Check_Timer = 2000;
|
|
||||||
}
|
}
|
||||||
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()
|
void AddSC_bug_trio()
|
||||||
{
|
{
|
||||||
new boss_kri();
|
RegisterCreatureAI(boss_kri);
|
||||||
new boss_vem();
|
RegisterCreatureAI(boss_vem);
|
||||||
new boss_yauj();
|
RegisterCreatureAI(boss_yauj);
|
||||||
|
RegisterSpellScript(spell_vem_knockback);
|
||||||
|
RegisterSpellScript(spell_vem_vengeance);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public:
|
|||||||
ObjectGuid SkeramGUID;
|
ObjectGuid SkeramGUID;
|
||||||
ObjectGuid VemGUID;
|
ObjectGuid VemGUID;
|
||||||
ObjectGuid KriGUID;
|
ObjectGuid KriGUID;
|
||||||
|
ObjectGuid YaujGUID;
|
||||||
ObjectGuid VeklorGUID;
|
ObjectGuid VeklorGUID;
|
||||||
ObjectGuid VeknilashGUID;
|
ObjectGuid VeknilashGUID;
|
||||||
ObjectGuid ViscidusGUID;
|
ObjectGuid ViscidusGUID;
|
||||||
@@ -88,6 +89,9 @@ public:
|
|||||||
case NPC_KRI:
|
case NPC_KRI:
|
||||||
KriGUID = creature->GetGUID();
|
KriGUID = creature->GetGUID();
|
||||||
break;
|
break;
|
||||||
|
case NPC_YAUJ:
|
||||||
|
YaujGUID = creature->GetGUID();
|
||||||
|
break;
|
||||||
case NPC_VEKLOR:
|
case NPC_VEKLOR:
|
||||||
VeklorGUID = creature->GetGUID();
|
VeklorGUID = creature->GetGUID();
|
||||||
break;
|
break;
|
||||||
@@ -106,11 +110,6 @@ public:
|
|||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case DATA_VEMISDEAD:
|
|
||||||
if (IsBossDied[0])
|
|
||||||
return 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATA_VEKLORISDEAD:
|
case DATA_VEKLORISDEAD:
|
||||||
if (IsBossDied[1])
|
if (IsBossDied[1])
|
||||||
return 1;
|
return 1;
|
||||||
@@ -140,6 +139,8 @@ public:
|
|||||||
return VemGUID;
|
return VemGUID;
|
||||||
case DATA_KRI:
|
case DATA_KRI:
|
||||||
return KriGUID;
|
return KriGUID;
|
||||||
|
case DATA_YAUJ:
|
||||||
|
return YaujGUID;
|
||||||
case DATA_VEKLOR:
|
case DATA_VEKLOR:
|
||||||
return VeklorGUID;
|
return VeklorGUID;
|
||||||
case DATA_VEKNILASH:
|
case DATA_VEKNILASH:
|
||||||
@@ -155,12 +156,11 @@ public:
|
|||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case DATA_VEM_DEATH:
|
|
||||||
IsBossDied[0] = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATA_BUG_TRIO_DEATH:
|
case DATA_BUG_TRIO_DEATH:
|
||||||
++BugTrioDeathCount;
|
if (data != 0)
|
||||||
|
++BugTrioDeathCount;
|
||||||
|
else
|
||||||
|
BugTrioDeathCount = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DATA_VEKLOR_DEATH:
|
case DATA_VEKLOR_DEATH:
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ enum DataTypes
|
|||||||
DATA_SKERAM = 1,
|
DATA_SKERAM = 1,
|
||||||
DATA_KRI = 2,
|
DATA_KRI = 2,
|
||||||
DATA_VEM = 3,
|
DATA_VEM = 3,
|
||||||
DATA_VEMISDEAD = 4,
|
DATA_YAUJ = 4,
|
||||||
DATA_VEM_DEATH = 5,
|
DATA_BUG_TRIO = 5,
|
||||||
DATA_VEKLOR = 6,
|
DATA_VEKLOR = 6,
|
||||||
DATA_VEKLORISDEAD = 7,
|
DATA_VEKLORISDEAD = 7,
|
||||||
DATA_VEKLOR_DEATH = 8,
|
DATA_VEKLOR_DEATH = 8,
|
||||||
@@ -60,6 +60,7 @@ enum Creatures
|
|||||||
NPC_SKERAM = 15263,
|
NPC_SKERAM = 15263,
|
||||||
NPC_VEM = 15544,
|
NPC_VEM = 15544,
|
||||||
NPC_KRI = 15511,
|
NPC_KRI = 15511,
|
||||||
|
NPC_YAUJ = 15543,
|
||||||
NPC_VEKLOR = 15276,
|
NPC_VEKLOR = 15276,
|
||||||
NPC_VEKNILASH = 15275,
|
NPC_VEKNILASH = 15275,
|
||||||
NPC_OURO = 15517,
|
NPC_OURO = 15517,
|
||||||
|
|||||||
Reference in New Issue
Block a user