fix(Scripts/SethekkHalls): Update Talon King Ikiss script (#15098)
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
--
|
||||||
|
DELETE FROM `spell_script_names` WHERE `spell_id` = 38194;
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||||
|
(38194, 'spell_talon_king_ikiss_blink');
|
||||||
@@ -264,6 +264,27 @@ SpellCastResult UnitAI::DoCastRandomTarget(uint32 spellId, uint32 threatTablePos
|
|||||||
return SPELL_FAILED_BAD_TARGETS;
|
return SPELL_FAILED_BAD_TARGETS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Cast spell on the max threat target, which may not always be the current victim.
|
||||||
|
*
|
||||||
|
* @param uint32 spellId Spell ID to cast.
|
||||||
|
* @param uint32 Threat table position.
|
||||||
|
* @param float dist Distance from caster to target.
|
||||||
|
* @param bool playerOnly Select players only, excludes pets and other npcs.
|
||||||
|
* @param bool triggered Triggered cast (full triggered mask).
|
||||||
|
*
|
||||||
|
* @return SpellCastResult
|
||||||
|
*/
|
||||||
|
SpellCastResult UnitAI::DoCastMaxThreat(uint32 spellId, uint32 threatTablePosition, float dist, bool playerOnly, bool triggered)
|
||||||
|
{
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, threatTablePosition, dist, playerOnly))
|
||||||
|
{
|
||||||
|
return DoCast(target, spellId, triggered);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPELL_FAILED_BAD_TARGETS;
|
||||||
|
}
|
||||||
|
|
||||||
#define UPDATE_TARGET(a) {if (AIInfo->target<a) AIInfo->target=a;}
|
#define UPDATE_TARGET(a) {if (AIInfo->target<a) AIInfo->target=a;}
|
||||||
|
|
||||||
void UnitAI::FillAISpellInfo()
|
void UnitAI::FillAISpellInfo()
|
||||||
|
|||||||
@@ -372,6 +372,9 @@ public:
|
|||||||
SpellCastResult DoCastAOE(uint32 spellId, bool triggered = false);
|
SpellCastResult DoCastAOE(uint32 spellId, bool triggered = false);
|
||||||
SpellCastResult DoCastRandomTarget(uint32 spellId, uint32 threatTablePosition = 0, float dist = 0.0f, bool playerOnly = true, bool triggered = false);
|
SpellCastResult DoCastRandomTarget(uint32 spellId, uint32 threatTablePosition = 0, float dist = 0.0f, bool playerOnly = true, bool triggered = false);
|
||||||
|
|
||||||
|
// Cast spell on the top threat target, which may not be the current victim.
|
||||||
|
SpellCastResult DoCastMaxThreat(uint32 spellId, uint32 threatTablePosition = 0, float dist = 0.0f, bool playerOnly = true, bool triggered = false);
|
||||||
|
|
||||||
float DoGetSpellMaxRange(uint32 spellId, bool positive = false);
|
float DoGetSpellMaxRange(uint32 spellId, bool positive = false);
|
||||||
|
|
||||||
void DoMeleeAttackIfReady();
|
void DoMeleeAttackIfReady();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
|
#include "SpellScript.h"
|
||||||
#include "sethekk_halls.h"
|
#include "sethekk_halls.h"
|
||||||
|
|
||||||
enum TailonkingIkiss
|
enum TailonkingIkiss
|
||||||
@@ -26,143 +27,146 @@ enum TailonkingIkiss
|
|||||||
SAY_SLAY = 2,
|
SAY_SLAY = 2,
|
||||||
SAY_DEATH = 3,
|
SAY_DEATH = 3,
|
||||||
EMOTE_ARCANE_EXP = 4,
|
EMOTE_ARCANE_EXP = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Spells
|
||||||
|
{
|
||||||
SPELL_BLINK = 38194,
|
SPELL_BLINK = 38194,
|
||||||
SPELL_BLINK_TELEPORT = 38203,
|
SPELL_BLINK_TELEPORT = 38203,
|
||||||
SPELL_MANA_SHIELD = 38151,
|
SPELL_MANA_SHIELD = 38151,
|
||||||
SPELL_ARCANE_BUBBLE = 9438,
|
SPELL_ARCANE_BUBBLE = 9438,
|
||||||
SPELL_SLOW = 35032,
|
SPELL_SLOW = 35032,
|
||||||
SPELL_POLYMORPH_N = 38245, // Difficulty data
|
SPELL_POLYMORPH = 38245,
|
||||||
SPELL_POLYMORPH_H = 43309,
|
SPELL_ARCANE_VOLLEY = 35059,
|
||||||
SPELL_ARCANE_VOLLEY_N = 35059, // Difficulty data
|
SPELL_ARCANE_EXPLOSION = 38197,
|
||||||
SPELL_ARCANE_VOLLEY_H = 40424,
|
|
||||||
SPELL_ARCANE_EXPLOSION_N = 38197, // Difficulty data
|
|
||||||
SPELL_ARCANE_EXPLOSION_H = 40425,
|
|
||||||
|
|
||||||
EVENT_SPELL_BLINK = 1,
|
|
||||||
EVENT_SPELL_POLYMORPH = 2,
|
|
||||||
EVENT_SPELL_SLOW = 3,
|
|
||||||
EVENT_SPELL_ARCANE_VOLLEY = 4,
|
|
||||||
EVENT_SPELL_ARCANE_EXPLO = 5,
|
|
||||||
EVENT_HEALTH_CHECK = 6,
|
|
||||||
EVENT_SPELL_BLINK_2 = 7
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_talon_king_ikiss : public CreatureScript
|
struct boss_talon_king_ikiss : public BossAI
|
||||||
{
|
{
|
||||||
public:
|
boss_talon_king_ikiss(Creature* creature) : BossAI(creature, DATA_IKISS), _spoken(false), _manaShield(false)
|
||||||
boss_talon_king_ikiss() : CreatureScript("boss_talon_king_ikiss") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
{
|
||||||
return GetSethekkHallsAI<boss_talon_king_ikissAI>(creature);
|
scheduler.SetValidator([this]
|
||||||
|
{
|
||||||
|
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
struct boss_talon_king_ikissAI : public ScriptedAI
|
void Reset() override
|
||||||
{
|
{
|
||||||
boss_talon_king_ikissAI(Creature* creature) : ScriptedAI(creature)
|
_Reset();
|
||||||
|
_spoken = false;
|
||||||
|
_manaShield = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveInLineOfSight(Unit* who) override
|
||||||
|
{
|
||||||
|
if (!_spoken && who->IsPlayer())
|
||||||
{
|
{
|
||||||
|
Talk(SAY_INTRO);
|
||||||
|
_spoken = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventMap events;
|
ScriptedAI::MoveInLineOfSight(who);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
|
{
|
||||||
|
_JustEngagedWith();
|
||||||
|
Talk(SAY_AGGRO);
|
||||||
|
|
||||||
|
scheduler.Schedule(35s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
me->InterruptNonMeleeSpells(false);
|
||||||
|
DoCastAOE(SPELL_BLINK);
|
||||||
|
Talk(EMOTE_ARCANE_EXP);
|
||||||
|
context.Repeat(35s, 40s);
|
||||||
|
|
||||||
|
scheduler.Schedule(1s, [this](TaskContext)
|
||||||
|
{
|
||||||
|
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||||
|
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||||
|
});
|
||||||
|
}).Schedule(5s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastAOE(SPELL_ARCANE_VOLLEY);
|
||||||
|
context.Repeat(7s, 12s);
|
||||||
|
}).Schedule(8s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
IsHeroic() ? DoCastRandomTarget(SPELL_POLYMORPH) : DoCastMaxThreat(SPELL_POLYMORPH);
|
||||||
|
context.Repeat(15s, 17500ms);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (IsHeroic())
|
||||||
|
{
|
||||||
|
scheduler.Schedule(15s, 25s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastAOE(SPELL_SLOW);
|
||||||
|
context.Repeat(15s, 30s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustDied(Unit* /*killer*/) override
|
||||||
|
{
|
||||||
|
_JustDied();
|
||||||
|
Talk(SAY_DEATH);
|
||||||
|
|
||||||
|
if (GameObject* coffer = instance->GetGameObject(DATA_GO_TALON_KING_COFFER))
|
||||||
|
{
|
||||||
|
coffer->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE | GO_FLAG_INTERACT_COND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||||
|
{
|
||||||
|
if (!_manaShield && me->HealthBelowPctDamaged(20, damage))
|
||||||
|
{
|
||||||
|
DoCast(me, SPELL_MANA_SHIELD);
|
||||||
|
_manaShield = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KilledUnit(Unit* /*victim*/) override
|
||||||
|
{
|
||||||
|
if (urand(0, 1))
|
||||||
|
Talk(SAY_SLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
bool _spoken;
|
bool _spoken;
|
||||||
|
bool _manaShield;
|
||||||
|
};
|
||||||
|
|
||||||
void Reset() override
|
// 38194 - Blink
|
||||||
|
class spell_talon_king_ikiss_blink : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_talon_king_ikiss_blink);
|
||||||
|
|
||||||
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||||
|
{
|
||||||
|
return sSpellMgr->GetSpellInfo(SPELL_BLINK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTargets(std::list<WorldObject*>& targets)
|
||||||
|
{
|
||||||
|
uint8 maxSize = 1;
|
||||||
|
if (targets.size() > maxSize)
|
||||||
{
|
{
|
||||||
_spoken = false;
|
Acore::Containers::RandomResize(targets, maxSize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit* who) override
|
void HandleDummyHitTarget(SpellEffIndex effIndex)
|
||||||
{
|
{
|
||||||
if (!_spoken && who->GetTypeId() == TYPEID_PLAYER)
|
PreventHitDefaultEffect(effIndex);
|
||||||
{
|
GetHitUnit()->CastSpell(GetCaster(), SPELL_BLINK_TELEPORT, true);
|
||||||
Talk(SAY_INTRO);
|
}
|
||||||
_spoken = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptedAI::MoveInLineOfSight(who);
|
void Register() override
|
||||||
}
|
{
|
||||||
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_talon_king_ikiss_blink::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||||
void JustEngagedWith(Unit* /*who*/) override
|
OnEffectHitTarget += SpellEffectFn(spell_talon_king_ikiss_blink::HandleDummyHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||||
{
|
}
|
||||||
Talk(SAY_AGGRO);
|
|
||||||
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_BLINK, 35000);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_ARCANE_VOLLEY, 5000);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_POLYMORPH, 8000);
|
|
||||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 2000);
|
|
||||||
if (IsHeroic())
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_SLOW, urand(15000, 25000));
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
Talk(SAY_DEATH);
|
|
||||||
|
|
||||||
if (InstanceScript* instance = me->GetInstanceScript())
|
|
||||||
instance->SetData(DATA_IKISSDOOREVENT, DONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KilledUnit(Unit* /*victim*/) override
|
|
||||||
{
|
|
||||||
if (urand(0, 1))
|
|
||||||
Talk(SAY_SLAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
events.Update(diff);
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (events.ExecuteEvent())
|
|
||||||
{
|
|
||||||
case EVENT_SPELL_ARCANE_VOLLEY:
|
|
||||||
me->CastSpell(me, SPELL_ARCANE_VOLLEY_N, false);
|
|
||||||
events.RepeatEvent(urand(7000, 12000));
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_POLYMORPH:
|
|
||||||
if (Unit* target = (IsHeroic() ? SelectTarget(SelectTargetMethod::Random, 0) : SelectTarget(SelectTargetMethod::MaxThreat, 1)))
|
|
||||||
me->CastSpell(target, SPELL_POLYMORPH_N, false);
|
|
||||||
events.RepeatEvent(urand(15000, 17500));
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_SLOW:
|
|
||||||
me->CastSpell(me, SPELL_SLOW, false);
|
|
||||||
events.RepeatEvent(urand(15000, 30000));
|
|
||||||
break;
|
|
||||||
case EVENT_HEALTH_CHECK:
|
|
||||||
if (me->HealthBelowPct(20))
|
|
||||||
{
|
|
||||||
me->CastSpell(me, SPELL_MANA_SHIELD, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
events.RepeatEvent(1000);
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_BLINK:
|
|
||||||
Talk(EMOTE_ARCANE_EXP);
|
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
|
||||||
{
|
|
||||||
me->CastSpell(target, SPELL_BLINK, false);
|
|
||||||
me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation());
|
|
||||||
|
|
||||||
DoCast(target, SPELL_BLINK_TELEPORT);
|
|
||||||
}
|
|
||||||
events.RepeatEvent(urand(35000, 40000));
|
|
||||||
events.DelayEvents(500);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_BLINK_2, 0);
|
|
||||||
return;
|
|
||||||
case EVENT_SPELL_BLINK_2:
|
|
||||||
me->CastSpell(me, SPELL_ARCANE_EXPLOSION_N, false);
|
|
||||||
me->CastSpell(me, SPELL_ARCANE_BUBBLE, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Anzu
|
enum Anzu
|
||||||
@@ -184,150 +188,116 @@ enum Anzu
|
|||||||
EVENT_ANZU_HEALTH2 = 5
|
EVENT_ANZU_HEALTH2 = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_anzu : public CreatureScript
|
struct boss_anzu : public BossAI
|
||||||
{
|
{
|
||||||
public:
|
boss_anzu(Creature* creature) : BossAI(creature, DATA_ANZU)
|
||||||
boss_anzu() : CreatureScript("boss_anzu") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
{
|
||||||
return GetSethekkHallsAI<boss_anzuAI>(creature);
|
talkTimer = 1;
|
||||||
|
me->ReplaceAllUnitFlags(UNIT_FLAG_NON_ATTACKABLE);
|
||||||
|
me->AddAura(SPELL_SHADOWFORM, me);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct boss_anzuAI : public ScriptedAI
|
uint32 talkTimer;
|
||||||
|
|
||||||
|
void SummonedCreatureDies(Creature* summon, Unit*) override
|
||||||
{
|
{
|
||||||
boss_anzuAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
summons.Despawn(summon);
|
||||||
|
summons.RemoveNotExisting();
|
||||||
|
if (summons.empty())
|
||||||
|
me->RemoveAurasDueToSpell(SPELL_BANISH_SELF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
|
{
|
||||||
|
_JustEngagedWith();
|
||||||
|
events.Reset();
|
||||||
|
events.ScheduleEvent(EVENT_SPELL_SCREECH, 14000);
|
||||||
|
events.ScheduleEvent(EVENT_SPELL_BOMB, 5000);
|
||||||
|
events.ScheduleEvent(EVENT_SPELL_CYCLONE, 8000);
|
||||||
|
events.ScheduleEvent(EVENT_ANZU_HEALTH1, 2000);
|
||||||
|
events.ScheduleEvent(EVENT_ANZU_HEALTH2, 2001);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SummonBroods()
|
||||||
|
{
|
||||||
|
Talk(SAY_SUMMON);
|
||||||
|
me->CastSpell(me, SPELL_BANISH_SELF, true);
|
||||||
|
for (uint8 i = 0; i < 5; ++i)
|
||||||
|
me->SummonCreature(23132 /*NPC_BROOD_OF_ANZU*/, me->GetPositionX() + 20 * cos((float)i), me->GetPositionY() + 20 * std::sin((float)i), me->GetPositionZ() + 25.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (talkTimer)
|
||||||
{
|
{
|
||||||
talkTimer = 1;
|
talkTimer += diff;
|
||||||
me->ReplaceAllUnitFlags(UNIT_FLAG_NON_ATTACKABLE);
|
if (talkTimer >= 1000 && talkTimer < 10000)
|
||||||
me->AddAura(SPELL_SHADOWFORM, me);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventMap events;
|
|
||||||
SummonList summons;
|
|
||||||
uint32 talkTimer;
|
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
|
||||||
summons.DespawnAll();
|
|
||||||
if (InstanceScript* instance = me->GetInstanceScript())
|
|
||||||
if (instance->GetData(TYPE_ANZU_ENCOUNTER) != DONE)
|
|
||||||
instance->SetData(TYPE_ANZU_ENCOUNTER, NOT_STARTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustSummoned(Creature* summon) override
|
|
||||||
{
|
|
||||||
summons.Summon(summon);
|
|
||||||
summon->AI()->AttackStart(me->GetVictim());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SummonedCreatureDies(Creature* summon, Unit*) override
|
|
||||||
{
|
|
||||||
summons.Despawn(summon);
|
|
||||||
summons.RemoveNotExisting();
|
|
||||||
if (summons.empty())
|
|
||||||
me->RemoveAurasDueToSpell(SPELL_BANISH_SELF);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override
|
|
||||||
{
|
|
||||||
events.Reset();
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_SCREECH, 14000);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_BOMB, 5000);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_CYCLONE, 8000);
|
|
||||||
events.ScheduleEvent(EVENT_ANZU_HEALTH1, 2000);
|
|
||||||
events.ScheduleEvent(EVENT_ANZU_HEALTH2, 2001);
|
|
||||||
|
|
||||||
if (InstanceScript* instance = me->GetInstanceScript())
|
|
||||||
instance->SetData(TYPE_ANZU_ENCOUNTER, IN_PROGRESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
if (InstanceScript* instance = me->GetInstanceScript())
|
|
||||||
instance->SetData(TYPE_ANZU_ENCOUNTER, DONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SummonBroods()
|
|
||||||
{
|
|
||||||
Talk(SAY_SUMMON);
|
|
||||||
me->CastSpell(me, SPELL_BANISH_SELF, true);
|
|
||||||
for (uint8 i = 0; i < 5; ++i)
|
|
||||||
me->SummonCreature(23132 /*NPC_BROOD_OF_ANZU*/, me->GetPositionX() + 20 * cos((float)i), me->GetPositionY() + 20 * std::sin((float)i), me->GetPositionZ() + 25.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (talkTimer)
|
|
||||||
{
|
{
|
||||||
talkTimer += diff;
|
Talk(SAY_ANZU_INTRO1);
|
||||||
if (talkTimer >= 1000 && talkTimer < 10000)
|
talkTimer = 10000;
|
||||||
{
|
|
||||||
Talk(SAY_ANZU_INTRO1);
|
|
||||||
talkTimer = 10000;
|
|
||||||
}
|
|
||||||
else if (talkTimer >= 16000)
|
|
||||||
{
|
|
||||||
me->ReplaceAllUnitFlags(UNIT_FLAG_NONE);
|
|
||||||
me->RemoveAurasDueToSpell(SPELL_SHADOWFORM);
|
|
||||||
Talk(SAY_ANZU_INTRO2);
|
|
||||||
talkTimer = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (talkTimer >= 16000)
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
events.Update(diff);
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED))
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (events.ExecuteEvent())
|
|
||||||
{
|
{
|
||||||
case EVENT_SPELL_SCREECH:
|
me->ReplaceAllUnitFlags(UNIT_FLAG_NONE);
|
||||||
me->CastSpell(me, SPELL_PARALYZING_SCREECH, false);
|
me->RemoveAurasDueToSpell(SPELL_SHADOWFORM);
|
||||||
events.RepeatEvent(23000);
|
Talk(SAY_ANZU_INTRO2);
|
||||||
events.DelayEvents(3000);
|
talkTimer = 0;
|
||||||
break;
|
|
||||||
case EVENT_SPELL_BOMB:
|
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true))
|
|
||||||
me->CastSpell(target, SPELL_SPELL_BOMB, false);
|
|
||||||
events.RepeatEvent(urand(16000, 24500));
|
|
||||||
events.DelayEvents(3000);
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_CYCLONE:
|
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45.0f, true))
|
|
||||||
me->CastSpell(target, SPELL_CYCLONE, false);
|
|
||||||
events.RepeatEvent(urand(22000, 27000));
|
|
||||||
events.DelayEvents(3000);
|
|
||||||
break;
|
|
||||||
case EVENT_ANZU_HEALTH1:
|
|
||||||
if (me->HealthBelowPct(66))
|
|
||||||
{
|
|
||||||
SummonBroods();
|
|
||||||
events.DelayEvents(10000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
events.RepeatEvent(1000);
|
|
||||||
break;
|
|
||||||
case EVENT_ANZU_HEALTH2:
|
|
||||||
if (me->HealthBelowPct(33))
|
|
||||||
{
|
|
||||||
SummonBroods();
|
|
||||||
events.DelayEvents(10000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
events.RepeatEvent(1000);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
events.Update(diff);
|
||||||
|
if (me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (events.ExecuteEvent())
|
||||||
|
{
|
||||||
|
case EVENT_SPELL_SCREECH:
|
||||||
|
me->CastSpell(me, SPELL_PARALYZING_SCREECH, false);
|
||||||
|
events.RepeatEvent(23000);
|
||||||
|
events.DelayEvents(3000);
|
||||||
|
break;
|
||||||
|
case EVENT_SPELL_BOMB:
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true))
|
||||||
|
me->CastSpell(target, SPELL_SPELL_BOMB, false);
|
||||||
|
events.RepeatEvent(urand(16000, 24500));
|
||||||
|
events.DelayEvents(3000);
|
||||||
|
break;
|
||||||
|
case EVENT_SPELL_CYCLONE:
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45.0f, true))
|
||||||
|
me->CastSpell(target, SPELL_CYCLONE, false);
|
||||||
|
events.RepeatEvent(urand(22000, 27000));
|
||||||
|
events.DelayEvents(3000);
|
||||||
|
break;
|
||||||
|
case EVENT_ANZU_HEALTH1:
|
||||||
|
if (me->HealthBelowPct(66))
|
||||||
|
{
|
||||||
|
SummonBroods();
|
||||||
|
events.DelayEvents(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
events.RepeatEvent(1000);
|
||||||
|
break;
|
||||||
|
case EVENT_ANZU_HEALTH2:
|
||||||
|
if (me->HealthBelowPct(33))
|
||||||
|
{
|
||||||
|
SummonBroods();
|
||||||
|
events.DelayEvents(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
events.RepeatEvent(1000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_boss_talon_king_ikiss()
|
void AddSC_boss_talon_king_ikiss()
|
||||||
{
|
{
|
||||||
new boss_talon_king_ikiss();
|
RegisterSethekkHallsCreatureAI(boss_talon_king_ikiss);
|
||||||
new boss_anzu();
|
RegisterSpellScript(spell_talon_king_ikiss_blink);
|
||||||
|
RegisterSethekkHallsCreatureAI(boss_anzu);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,17 @@
|
|||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "sethekk_halls.h"
|
#include "sethekk_halls.h"
|
||||||
|
|
||||||
|
DoorData const doorData[] =
|
||||||
|
{
|
||||||
|
{ GO_IKISS_DOOR, DATA_IKISS, DOOR_TYPE_PASSAGE },
|
||||||
|
{ 0, 0, DOOR_TYPE_ROOM } // END
|
||||||
|
};
|
||||||
|
|
||||||
|
ObjectData const gameObjectData[] =
|
||||||
|
{
|
||||||
|
{ GO_THE_TALON_KINGS_COFFER, DATA_GO_TALON_KING_COFFER }
|
||||||
|
};
|
||||||
|
|
||||||
class instance_sethekk_halls : public InstanceMapScript
|
class instance_sethekk_halls : public InstanceMapScript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -31,91 +42,20 @@ public:
|
|||||||
|
|
||||||
struct instance_sethekk_halls_InstanceMapScript : public InstanceScript
|
struct instance_sethekk_halls_InstanceMapScript : public InstanceScript
|
||||||
{
|
{
|
||||||
instance_sethekk_halls_InstanceMapScript(Map* map) : InstanceScript(map) {}
|
instance_sethekk_halls_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||||
|
|
||||||
uint32 AnzuEncounter;
|
|
||||||
ObjectGuid m_uiIkissDoorGUID;
|
|
||||||
ObjectGuid _talonKingsCofferGUID;
|
|
||||||
|
|
||||||
void Initialize() override
|
|
||||||
{
|
{
|
||||||
AnzuEncounter = NOT_STARTED;
|
SetHeaders(DataHeaders);
|
||||||
|
SetBossNumber(EncounterCount);
|
||||||
|
LoadDoorData(doorData);
|
||||||
|
LoadObjectData(nullptr, gameObjectData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnCreatureCreate(Creature* creature) override
|
void OnCreatureCreate(Creature* creature) override
|
||||||
{
|
{
|
||||||
if (creature->GetEntry() == NPC_ANZU || creature->GetEntry() == NPC_VOICE_OF_THE_RAVEN_GOD)
|
if (creature->GetEntry() == NPC_ANZU || creature->GetEntry() == NPC_VOICE_OF_THE_RAVEN_GOD)
|
||||||
if (AnzuEncounter >= IN_PROGRESS)
|
if (GetBossState(DATA_ANZU) == DONE)
|
||||||
creature->DespawnOrUnsummon(1);
|
creature->DespawnOrUnsummon(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnGameObjectCreate(GameObject* go) override
|
|
||||||
{
|
|
||||||
switch (go->GetEntry())
|
|
||||||
{
|
|
||||||
case GO_IKISS_DOOR:
|
|
||||||
m_uiIkissDoorGUID = go->GetGUID();
|
|
||||||
break;
|
|
||||||
case GO_THE_TALON_KINGS_COFFER:
|
|
||||||
_talonKingsCofferGUID = go->GetGUID();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetData(uint32 type, uint32 data) override
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case DATA_IKISSDOOREVENT:
|
|
||||||
if (data == DONE)
|
|
||||||
{
|
|
||||||
DoUseDoorOrButton(m_uiIkissDoorGUID, DAY * IN_MILLISECONDS);
|
|
||||||
if (GameObject* coffer = instance->GetGameObject(_talonKingsCofferGUID))
|
|
||||||
coffer->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE | GO_FLAG_INTERACT_COND);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TYPE_ANZU_ENCOUNTER:
|
|
||||||
AnzuEncounter = data;
|
|
||||||
SaveToDB();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetSaveData() override
|
|
||||||
{
|
|
||||||
OUT_SAVE_INST_DATA;
|
|
||||||
|
|
||||||
std::ostringstream saveStream;
|
|
||||||
saveStream << "S H " << AnzuEncounter;
|
|
||||||
|
|
||||||
OUT_SAVE_INST_DATA_COMPLETE;
|
|
||||||
return saveStream.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Load(const char* strIn) override
|
|
||||||
{
|
|
||||||
if (!strIn)
|
|
||||||
{
|
|
||||||
OUT_LOAD_INST_DATA_FAIL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OUT_LOAD_INST_DATA(strIn);
|
|
||||||
|
|
||||||
char dataHead1, dataHead2;
|
|
||||||
|
|
||||||
std::istringstream loadStream(strIn);
|
|
||||||
loadStream >> dataHead1 >> dataHead2;
|
|
||||||
|
|
||||||
if (dataHead1 == 'S' && dataHead2 == 'H')
|
|
||||||
{
|
|
||||||
loadStream >> AnzuEncounter;
|
|
||||||
if (AnzuEncounter == IN_PROGRESS)
|
|
||||||
AnzuEncounter = NOT_STARTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
OUT_LOAD_INST_DATA_COMPLETE;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -20,14 +20,30 @@
|
|||||||
|
|
||||||
#include "CreatureAIImpl.h"
|
#include "CreatureAIImpl.h"
|
||||||
|
|
||||||
|
#define DataHeaders "SH"
|
||||||
|
|
||||||
|
uint32 constexpr EncounterCount = 3;
|
||||||
|
|
||||||
#define SethekkHallsScriptName "instance_sethekk_halls"
|
#define SethekkHallsScriptName "instance_sethekk_halls"
|
||||||
|
|
||||||
|
enum Encounters
|
||||||
|
{
|
||||||
|
DATA_DARKWEAVER_SYTH,
|
||||||
|
DATA_ANZU,
|
||||||
|
DATA_IKISS,
|
||||||
|
};
|
||||||
|
|
||||||
enum eTypes
|
enum eTypes
|
||||||
{
|
{
|
||||||
DATA_IKISSDOOREVENT = 1,
|
DATA_IKISSDOOREVENT = 1,
|
||||||
TYPE_ANZU_ENCOUNTER = 2,
|
TYPE_ANZU_ENCOUNTER = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum InstanceData
|
||||||
|
{
|
||||||
|
DATA_GO_TALON_KING_COFFER
|
||||||
|
};
|
||||||
|
|
||||||
enum eIds
|
enum eIds
|
||||||
{
|
{
|
||||||
NPC_VOICE_OF_THE_RAVEN_GOD = 21851,
|
NPC_VOICE_OF_THE_RAVEN_GOD = 21851,
|
||||||
@@ -43,4 +59,6 @@ inline AI* GetSethekkHallsAI(T* obj)
|
|||||||
return GetInstanceAI<AI>(obj, SethekkHallsScriptName);
|
return GetInstanceAI<AI>(obj, SethekkHallsScriptName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RegisterSethekkHallsCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetSethekkHallsAI)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user