refactor(Scripts/ZulAman): refactor Halazzi (#18267)
* initial * some fixes * last booboos * fixes after test * finale * actual final * blegh
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
--
|
||||||
|
DELETE FROM `creature_template_movement` WHERE `CreatureId` = 24224;
|
||||||
|
INSERT INTO `creature_template_movement` (`CreatureId`, `Flight`, `Rooted`) VALUES
|
||||||
|
(24224, 1, 1);
|
||||||
@@ -37,9 +37,13 @@ enum Spells
|
|||||||
SPELL_SHRED_ARMOR = 43243 // Used by Spirit Lynx
|
SPELL_SHRED_ARMOR = 43243 // Used by Spirit Lynx
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum UniqueEvents
|
||||||
|
{
|
||||||
|
EVENT_BERSERK = 0
|
||||||
|
};
|
||||||
|
|
||||||
enum Hal_CreatureIds
|
enum Hal_CreatureIds
|
||||||
{
|
{
|
||||||
NPC_SPIRIT_LYNX = 24143,
|
|
||||||
NPC_TOTEM = 24224
|
NPC_TOTEM = 24224
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -63,326 +67,274 @@ enum Yells
|
|||||||
SAY_DEATH = 5
|
SAY_DEATH = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_halazzi : public CreatureScript
|
enum Groups
|
||||||
{
|
{
|
||||||
public:
|
GROUP_LYNX = 0,
|
||||||
boss_halazzi() : CreatureScript("boss_halazzi") { }
|
GROUP_HUMAN = 1,
|
||||||
|
GROUP_MERGE = 2
|
||||||
|
};
|
||||||
|
|
||||||
struct boss_halazziAI : public ScriptedAI
|
struct boss_halazzi : public BossAI
|
||||||
|
{
|
||||||
|
boss_halazzi(Creature* creature) : BossAI(creature, DATA_HALAZZIEVENT)
|
||||||
{
|
{
|
||||||
boss_halazziAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
scheduler.SetValidator([this]
|
||||||
{
|
{
|
||||||
instance = creature->GetInstanceScript();
|
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
BossAI::Reset();
|
||||||
|
_transformCount = 0;
|
||||||
|
_healthCheckPercentage = 0;
|
||||||
|
_phase = PHASE_NONE;
|
||||||
|
_lynxFormHealth = me->GetMaxHealth();
|
||||||
|
_healthPortion = _lynxFormHealth/4;
|
||||||
|
_humanFormHealth = (me->GetMaxHealth())/0.66666666;
|
||||||
|
EnterPhase(PHASE_LYNX);
|
||||||
|
DoCastSelf(SPELL_DUAL_WIELD, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustSummoned(Creature* summon) override
|
||||||
|
{
|
||||||
|
BossAI::JustSummoned(summon);
|
||||||
|
summon->Attack(me->GetVictim(), false);
|
||||||
|
summon->SetInCombatWithZone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustEngagedWith(Unit* who) override
|
||||||
|
{
|
||||||
|
BossAI::JustEngagedWith(who);
|
||||||
|
Talk(SAY_AGGRO);
|
||||||
|
ScheduleUniqueTimedEvent(10min, [&]
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_BERSERK, true);
|
||||||
|
}, EVENT_BERSERK);
|
||||||
|
EnterPhase(PHASE_LYNX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||||
|
{
|
||||||
|
if (damage >= me->GetHealth() && _phase != PHASE_ENRAGE)
|
||||||
|
{
|
||||||
|
damage = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
InstanceScript* instance;
|
|
||||||
SummonList summons;
|
|
||||||
PhaseHalazzi Phase;
|
|
||||||
|
|
||||||
uint32 FrenzyTimer;
|
|
||||||
uint32 SaberlashTimer;
|
|
||||||
uint32 ShockTimer;
|
|
||||||
uint32 TotemTimer;
|
|
||||||
uint32 CheckTimer;
|
|
||||||
uint32 BerserkTimer;
|
|
||||||
uint32 TransformCount;
|
|
||||||
|
|
||||||
ObjectGuid LynxGUID;
|
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
{
|
||||||
instance->SetData(DATA_HALAZZIEVENT, NOT_STARTED);
|
if (_phase == PHASE_LYNX || _phase == PHASE_ENRAGE)
|
||||||
summons.DespawnAll();
|
|
||||||
|
|
||||||
LynxGUID.Clear();
|
|
||||||
TransformCount = 0;
|
|
||||||
BerserkTimer = 600000;
|
|
||||||
CheckTimer = 1000;
|
|
||||||
|
|
||||||
DoCast(me, SPELL_DUAL_WIELD, true);
|
|
||||||
|
|
||||||
Phase = PHASE_NONE;
|
|
||||||
EnterPhase(PHASE_LYNX);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override
|
|
||||||
{
|
|
||||||
instance->SetData(DATA_HALAZZIEVENT, IN_PROGRESS);
|
|
||||||
Talk(SAY_AGGRO);
|
|
||||||
EnterPhase(PHASE_LYNX);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustSummoned(Creature* summon) override
|
|
||||||
{
|
|
||||||
summon->AI()->AttackStart(me->GetVictim());
|
|
||||||
if (summon->GetEntry() == NPC_SPIRIT_LYNX)
|
|
||||||
LynxGUID = summon->GetGUID();
|
|
||||||
summons.Summon(summon);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
|
||||||
{
|
|
||||||
if (damage >= me->GetHealth() && Phase != PHASE_ENRAGE)
|
|
||||||
damage = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpellHit(Unit*, SpellInfo const* spell) override
|
|
||||||
{
|
|
||||||
if (spell->Id == SPELL_TRANSFORM_SPLIT2)
|
|
||||||
EnterPhase(PHASE_HUMAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AttackStart(Unit* who) override
|
|
||||||
{
|
|
||||||
if (Phase != PHASE_MERGE)
|
|
||||||
ScriptedAI::AttackStart(who);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnterPhase(PhaseHalazzi NextPhase)
|
|
||||||
{
|
|
||||||
switch (NextPhase)
|
|
||||||
{
|
{
|
||||||
case PHASE_LYNX:
|
_healthCheckPercentage = 25 * (3 - _transformCount);
|
||||||
case PHASE_ENRAGE:
|
if (!HealthAbovePct(_healthCheckPercentage))
|
||||||
if (Phase == PHASE_MERGE)
|
{
|
||||||
{
|
EnterPhase(PHASE_SPLIT);
|
||||||
DoCast(me, SPELL_TRANSFORM_MERGE, true);
|
}
|
||||||
me->Attack(me->GetVictim(), true);
|
|
||||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
|
||||||
}
|
|
||||||
if (Creature* Lynx = ObjectAccessor::GetCreature(*me, LynxGUID))
|
|
||||||
Lynx->DisappearAndDie();
|
|
||||||
me->SetMaxHealth(600000);
|
|
||||||
me->SetHealth(600000 - 150000 * TransformCount);
|
|
||||||
FrenzyTimer = 16000;
|
|
||||||
SaberlashTimer = 20000;
|
|
||||||
ShockTimer = 10000;
|
|
||||||
TotemTimer = 12000;
|
|
||||||
break;
|
|
||||||
case PHASE_SPLIT:
|
|
||||||
Talk(SAY_SPLIT);
|
|
||||||
DoCast(me, SPELL_TRANSFORM_SPLIT, true);
|
|
||||||
break;
|
|
||||||
case PHASE_HUMAN:
|
|
||||||
//DoCast(me, SPELL_SUMMON_LYNX, true);
|
|
||||||
DoSpawnCreature(NPC_SPIRIT_LYNX, 5, 5, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
|
||||||
me->SetMaxHealth(400000);
|
|
||||||
me->SetHealth(400000);
|
|
||||||
ShockTimer = 10000;
|
|
||||||
TotemTimer = 12000;
|
|
||||||
break;
|
|
||||||
case PHASE_MERGE:
|
|
||||||
if (Unit* pLynx = ObjectAccessor::GetUnit(*me, LynxGUID))
|
|
||||||
{
|
|
||||||
Talk(SAY_MERGE);
|
|
||||||
pLynx->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
|
||||||
pLynx->GetMotionMaster()->Clear();
|
|
||||||
pLynx->GetMotionMaster()->MoveFollow(me, 0, 0);
|
|
||||||
me->GetMotionMaster()->Clear();
|
|
||||||
me->GetMotionMaster()->MoveFollow(pLynx, 0, 0);
|
|
||||||
++TransformCount;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Phase = NextPhase;
|
else if (_phase == PHASE_HUMAN)
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (BerserkTimer <= diff)
|
|
||||||
{
|
{
|
||||||
DoCast(me, SPELL_BERSERK, true);
|
if (Creature* lynx = instance->GetCreature(DATA_SPIRIT_LYNX))
|
||||||
BerserkTimer = 60000;
|
{
|
||||||
|
if (!HealthAbovePct(20) || !lynx->HealthAbovePct(20))
|
||||||
|
{
|
||||||
|
EnterPhase(PHASE_MERGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//should not really happen
|
||||||
|
EnterEvadeMode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else BerserkTimer -= diff;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Phase == PHASE_LYNX || Phase == PHASE_ENRAGE)
|
void SpellHit(Unit*, SpellInfo const* spell) override
|
||||||
{
|
{
|
||||||
if (SaberlashTimer <= diff)
|
if (spell->Id == SPELL_TRANSFORM_SPLIT2)
|
||||||
|
{
|
||||||
|
EnterPhase(PHASE_HUMAN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttackStart(Unit* who) override
|
||||||
|
{
|
||||||
|
if (_phase != PHASE_MERGE)
|
||||||
|
{
|
||||||
|
BossAI::AttackStart(who);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnterPhase(PhaseHalazzi nextPhase)
|
||||||
|
{
|
||||||
|
switch (nextPhase)
|
||||||
|
{
|
||||||
|
case PHASE_LYNX:
|
||||||
|
case PHASE_ENRAGE:
|
||||||
|
if (_phase == PHASE_MERGE)
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_TRANSFORM_MERGE, true);
|
||||||
|
me->RemoveAurasDueToSpell(SPELL_TRANSFORM_SPLIT2);
|
||||||
|
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||||
|
}
|
||||||
|
summons.DespawnAll();
|
||||||
|
me->SetMaxHealth(_lynxFormHealth);
|
||||||
|
me->SetHealth(_lynxFormHealth - _healthPortion * _transformCount);
|
||||||
|
scheduler.CancelGroup(GROUP_MERGE);
|
||||||
|
scheduler.Schedule(16s, GROUP_LYNX, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_FRENZY);
|
||||||
|
context.Repeat(10s, 15s);
|
||||||
|
}).Schedule(20s, GROUP_LYNX, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
Talk(SAY_SABER);
|
Talk(SAY_SABER);
|
||||||
// A tank with more than 490 defense skills should receive no critical hit
|
|
||||||
//DoCast(me, 41296, true);
|
|
||||||
DoCastVictim(SPELL_SABER_LASH, true);
|
DoCastVictim(SPELL_SABER_LASH, true);
|
||||||
//me->RemoveAurasDueToSpell(41296);
|
context.Repeat(30s);
|
||||||
SaberlashTimer = 30000;
|
});
|
||||||
}
|
break;
|
||||||
else SaberlashTimer -= diff;
|
case PHASE_SPLIT:
|
||||||
|
Talk(SAY_SPLIT);
|
||||||
if (FrenzyTimer <= diff)
|
DoCastSelf(SPELL_TRANSFORM_SPLIT, true);
|
||||||
{
|
break;
|
||||||
DoCast(me, SPELL_FRENZY);
|
case PHASE_HUMAN:
|
||||||
FrenzyTimer = urand(10000, 15000);
|
scheduler.CancelGroup(GROUP_MERGE);
|
||||||
}
|
DoCastSelf(SPELL_SUMMON_LYNX, true);
|
||||||
else FrenzyTimer -= diff;
|
me->SetMaxHealth(_humanFormHealth);
|
||||||
|
me->SetHealth(_humanFormHealth);
|
||||||
if (Phase == PHASE_LYNX)
|
scheduler.CancelGroup(GROUP_LYNX);
|
||||||
{
|
scheduler.Schedule(10s, GROUP_HUMAN, [this](TaskContext context)
|
||||||
if (CheckTimer <= diff)
|
|
||||||
{
|
|
||||||
if (HealthBelowPct(25 * (3 - TransformCount)))
|
|
||||||
EnterPhase(PHASE_SPLIT);
|
|
||||||
CheckTimer = 1000;
|
|
||||||
}
|
|
||||||
else CheckTimer -= diff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE)
|
|
||||||
{
|
|
||||||
if (TotemTimer <= diff)
|
|
||||||
{
|
|
||||||
DoCast(me, SPELL_SUMMON_TOTEM);
|
|
||||||
TotemTimer = 20000;
|
|
||||||
}
|
|
||||||
else TotemTimer -= diff;
|
|
||||||
|
|
||||||
if (ShockTimer <= diff)
|
|
||||||
{
|
{
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||||
{
|
{
|
||||||
if (target->IsNonMeleeSpellCast(false))
|
if (target->IsNonMeleeSpellCast(false))
|
||||||
|
{
|
||||||
DoCast(target, SPELL_EARTHSHOCK);
|
DoCast(target, SPELL_EARTHSHOCK);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
DoCast(target, SPELL_FLAMESHOCK);
|
DoCast(target, SPELL_FLAMESHOCK);
|
||||||
ShockTimer = urand(10000, 15000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else ShockTimer -= diff;
|
|
||||||
|
|
||||||
if (Phase == PHASE_HUMAN)
|
|
||||||
{
|
|
||||||
if (CheckTimer <= diff)
|
|
||||||
{
|
|
||||||
if (!HealthAbovePct(20) /*HealthBelowPct(10)*/)
|
|
||||||
EnterPhase(PHASE_MERGE);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Unit* Lynx = ObjectAccessor::GetUnit(*me, LynxGUID);
|
|
||||||
if (Lynx && !Lynx->HealthAbovePct(20) /*Lynx->HealthBelowPct(10)*/)
|
|
||||||
EnterPhase(PHASE_MERGE);
|
|
||||||
}
|
|
||||||
CheckTimer = 1000;
|
|
||||||
}
|
|
||||||
else CheckTimer -= diff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Phase == PHASE_MERGE)
|
|
||||||
{
|
|
||||||
if (CheckTimer <= diff)
|
|
||||||
{
|
|
||||||
Unit* Lynx = ObjectAccessor::GetUnit(*me, LynxGUID);
|
|
||||||
if (Lynx)
|
|
||||||
{
|
|
||||||
Lynx->GetMotionMaster()->MoveFollow(me, 0, 0);
|
|
||||||
me->GetMotionMaster()->MoveFollow(Lynx, 0, 0);
|
|
||||||
if (me->IsWithinDistInMap(Lynx, 6.0f))
|
|
||||||
{
|
|
||||||
if (TransformCount < 3)
|
|
||||||
EnterPhase(PHASE_LYNX);
|
|
||||||
else
|
|
||||||
EnterPhase(PHASE_ENRAGE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CheckTimer = 1000;
|
context.Repeat(10s, 15s);
|
||||||
|
}).Schedule(12s, GROUP_HUMAN, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_SUMMON_TOTEM);
|
||||||
|
context.Repeat(20s);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case PHASE_MERGE:
|
||||||
|
if (Creature* lynx = instance->GetCreature(DATA_SPIRIT_LYNX))
|
||||||
|
{
|
||||||
|
Talk(SAY_MERGE);
|
||||||
|
scheduler.CancelGroup(GROUP_HUMAN);
|
||||||
|
lynx->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||||
|
lynx->GetMotionMaster()->Clear();
|
||||||
|
lynx->GetMotionMaster()->MoveFollow(me, 0, 0);
|
||||||
|
me->GetMotionMaster()->Clear();
|
||||||
|
me->GetMotionMaster()->MoveFollow(lynx, 0, 0);
|
||||||
|
++_transformCount;
|
||||||
|
scheduler.Schedule(2s, GROUP_MERGE, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (Creature* lynx = instance->GetCreature(DATA_SPIRIT_LYNX))
|
||||||
|
{
|
||||||
|
if (me->IsWithinDistInMap(lynx, 6.0f))
|
||||||
|
{
|
||||||
|
if (_transformCount < 3)
|
||||||
|
{
|
||||||
|
EnterPhase(PHASE_LYNX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnterPhase(PHASE_ENRAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.Repeat(2s);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else CheckTimer -= diff;
|
break;
|
||||||
}
|
default:
|
||||||
|
break;
|
||||||
DoMeleeAttackIfReady();
|
|
||||||
}
|
}
|
||||||
|
_phase = nextPhase;
|
||||||
|
}
|
||||||
|
|
||||||
void KilledUnit(Unit* victim) override
|
void KilledUnit(Unit* victim) override
|
||||||
|
{
|
||||||
|
BossAI::KilledUnit(victim);
|
||||||
|
if (victim->IsPlayer())
|
||||||
{
|
{
|
||||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Talk(SAY_KILL);
|
Talk(SAY_KILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
instance->SetData(DATA_HALAZZIEVENT, DONE);
|
|
||||||
Talk(SAY_DEATH);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
|
||||||
return GetZulAmanAI<boss_halazziAI>(creature);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JustDied(Unit* killer) override
|
||||||
|
{
|
||||||
|
BossAI::JustDied(killer);
|
||||||
|
Talk(SAY_DEATH);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
uint32 _lynxFormHealth;
|
||||||
|
uint32 _humanFormHealth;
|
||||||
|
uint32 _healthPortion;
|
||||||
|
uint8 _transformCount;
|
||||||
|
uint32 _healthCheckPercentage;
|
||||||
|
PhaseHalazzi _phase;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Spirits Lynx AI
|
// Spirits Lynx AI
|
||||||
class npc_halazzi_lynx : public CreatureScript
|
struct npc_halazzi_lynx : public ScriptedAI
|
||||||
{
|
{
|
||||||
public:
|
npc_halazzi_lynx(Creature* creature) : ScriptedAI(creature) { }
|
||||||
npc_halazzi_lynx() : CreatureScript("npc_halazzi_lynx") { }
|
|
||||||
|
|
||||||
struct npc_halazzi_lynxAI : public ScriptedAI
|
void Reset() override
|
||||||
{
|
{
|
||||||
npc_halazzi_lynxAI(Creature* creature) : ScriptedAI(creature) { }
|
scheduler.CancelAll();
|
||||||
|
}
|
||||||
|
|
||||||
uint32 FrenzyTimer;
|
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||||
uint32 shredder_timer;
|
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
|
||||||
FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds
|
|
||||||
shredder_timer = 4000;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
|
||||||
{
|
|
||||||
if (damage >= me->GetHealth())
|
|
||||||
damage = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AttackStart(Unit* who) override
|
|
||||||
{
|
|
||||||
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
|
|
||||||
ScriptedAI::AttackStart(who);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override {/*DoZoneInCombat();*/ }
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (FrenzyTimer <= diff)
|
|
||||||
{
|
|
||||||
DoCast(me, SPELL_LYNX_FRENZY);
|
|
||||||
FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds
|
|
||||||
}
|
|
||||||
else FrenzyTimer -= diff;
|
|
||||||
|
|
||||||
if (shredder_timer <= diff)
|
|
||||||
{
|
|
||||||
DoCastVictim(SPELL_SHRED_ARMOR);
|
|
||||||
shredder_timer = 4000;
|
|
||||||
}
|
|
||||||
else shredder_timer -= diff;
|
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
{
|
||||||
return GetZulAmanAI<npc_halazzi_lynxAI>(creature);
|
if (damage >= me->GetHealth())
|
||||||
|
{
|
||||||
|
damage = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttackStart(Unit* who) override
|
||||||
|
{
|
||||||
|
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
|
||||||
|
{
|
||||||
|
ScriptedAI::AttackStart(who);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustEngagedWith(Unit* who) override
|
||||||
|
{
|
||||||
|
ScriptedAI::JustEngagedWith(who);
|
||||||
|
|
||||||
|
ScheduleTimedEvent(30s, 50s, [&]
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_LYNX_FRENZY);
|
||||||
|
}, 30s, 50s);
|
||||||
|
ScheduleTimedEvent(4s, [&]{
|
||||||
|
DoCastVictim(SPELL_SHRED_ARMOR);
|
||||||
|
}, 4s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduler.Update(diff);
|
||||||
|
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_boss_halazzi()
|
void AddSC_boss_halazzi()
|
||||||
{
|
{
|
||||||
new boss_halazzi();
|
RegisterZulAmanCreatureAI(boss_halazzi);
|
||||||
new npc_halazzi_lynx();
|
RegisterZulAmanCreatureAI(npc_halazzi_lynx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,17 @@ static SHostageInfo HostageInfo[] =
|
|||||||
|
|
||||||
Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f};
|
Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f};
|
||||||
|
|
||||||
|
ObjectData const creatureData[] =
|
||||||
|
{
|
||||||
|
{ NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
ObjectData const gameObjectData[] =
|
||||||
|
{
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
class instance_zulaman : public InstanceMapScript
|
class instance_zulaman : public InstanceMapScript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -92,6 +103,7 @@ public:
|
|||||||
void Initialize() override
|
void Initialize() override
|
||||||
{
|
{
|
||||||
SetHeaders(DataHeader);
|
SetHeaders(DataHeader);
|
||||||
|
LoadObjectData(creatureData, gameObjectData);
|
||||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||||
|
|
||||||
QuestTimer = 0;
|
QuestTimer = 0;
|
||||||
@@ -135,6 +147,7 @@ public:
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
InstanceScript::OnCreatureCreate(creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnGameObjectCreate(GameObject* go) override
|
void OnGameObjectCreate(GameObject* go) override
|
||||||
|
|||||||
@@ -32,9 +32,10 @@ enum DataTypes
|
|||||||
DATA_HALAZZIEVENT = 4,
|
DATA_HALAZZIEVENT = 4,
|
||||||
DATA_HEXLORDEVENT = 5,
|
DATA_HEXLORDEVENT = 5,
|
||||||
DATA_ZULJINEVENT = 6,
|
DATA_ZULJINEVENT = 6,
|
||||||
DATA_CHESTLOOTED = 7,
|
DATA_SPIRIT_LYNX = 7,
|
||||||
TYPE_RAND_VENDOR_1 = 8,
|
DATA_CHESTLOOTED = 8,
|
||||||
TYPE_RAND_VENDOR_2 = 9
|
TYPE_RAND_VENDOR_1 = 9,
|
||||||
|
TYPE_RAND_VENDOR_2 = 10
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CreatureIds
|
enum CreatureIds
|
||||||
@@ -44,7 +45,8 @@ enum CreatureIds
|
|||||||
NPC_ZULJIN = 23863,
|
NPC_ZULJIN = 23863,
|
||||||
NPC_HEXLORD = 24239,
|
NPC_HEXLORD = 24239,
|
||||||
NPC_HALAZZI = 23577,
|
NPC_HALAZZI = 23577,
|
||||||
NPC_NALORAKK = 23576
|
NPC_NALORAKK = 23576,
|
||||||
|
NPC_SPIRIT_LYNX = 24143
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GameobjectIds
|
enum GameobjectIds
|
||||||
@@ -68,4 +70,6 @@ inline AI* GetZulAmanAI(T* obj)
|
|||||||
return GetInstanceAI<AI>(obj, ZulAmanScriptName);
|
return GetInstanceAI<AI>(obj, ZulAmanScriptName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RegisterZulAmanCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetZulAmanAI)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user