722 lines
27 KiB
C#
722 lines
27 KiB
C#
/*
|
|
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
using Framework.Constants;
|
|
using Game.AI;
|
|
using Game.Entities;
|
|
using Game.Maps;
|
|
using Game.Scripting;
|
|
using Game.Spells;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Scripts.Northrend.AzjolNerub.AzjolNerub.Anubarak
|
|
{
|
|
struct SpellIds
|
|
{
|
|
public const uint Emerge = 53500;
|
|
public const uint Submerge = 53421;
|
|
public const uint ImpaleAura = 53456;
|
|
public const uint ImpaleVisual = 53455;
|
|
public const uint ImpaleDamage = 53454;
|
|
public const uint LeechingSwarm = 53467;
|
|
public const uint Pound = 59433;
|
|
public const uint PoundDamage = 59432;
|
|
public const uint CarrionBeetles = 53520;
|
|
public const uint CarrionBeetle = 53521;
|
|
|
|
public const uint SummonDarter = 53599;
|
|
public const uint SummonAssassin = 53609;
|
|
public const uint SummonGuardian = 53614;
|
|
public const uint SummonVenomancer = 53615;
|
|
|
|
public const uint Dart = 59349;
|
|
public const uint Backstab = 52540;
|
|
public const uint AssassinVisual = 53611;
|
|
public const uint SunderArmor = 53618;
|
|
public const uint PoisonBolt = 53617;
|
|
}
|
|
|
|
struct CreatureIds
|
|
{
|
|
public const uint WorldTrigger = 22515;
|
|
}
|
|
|
|
struct TextIds
|
|
{
|
|
public const uint SayAggro = 0;
|
|
public const uint SaySlay = 1;
|
|
public const uint SayDeath = 2;
|
|
public const uint SayLocust = 3;
|
|
public const uint SaySubmerge = 4;
|
|
public const uint SayIntro = 5;
|
|
}
|
|
|
|
struct EventIds
|
|
{
|
|
public const uint Pound = 1;
|
|
public const uint Impale = 2;
|
|
public const uint LeechingSwarm = 3;
|
|
public const uint CarrionBeetles = 4;
|
|
public const uint Submerge = 5; // Use Event For This So We Don'T Submerge Mid-Cast
|
|
public const uint Darter = 6;
|
|
public const uint Assassin = 7;
|
|
public const uint Guardian = 8;
|
|
public const uint Venomancer = 9;
|
|
public const uint CloseDoor = 10;
|
|
}
|
|
|
|
struct Misc
|
|
{
|
|
public const uint AchievGottaGoStartEvent = 20381;
|
|
|
|
public const byte PhaseEmerge = 1;
|
|
public const byte PhaseSubmerge = 2;
|
|
|
|
public const int GuidTypePet = 0;
|
|
public const int GuidTypeImpale = 1;
|
|
|
|
public const byte SummonGroupWorldTriggerGuardian = 1;
|
|
|
|
public const int ActionPetDied = 1;
|
|
public const int ActionPetEvade = 2;
|
|
}
|
|
|
|
[Script]
|
|
class boss_anub_arak : CreatureScript
|
|
{
|
|
public boss_anub_arak() : base("boss_anub_arak") { }
|
|
|
|
class boss_anub_arakAI : BossAI
|
|
{
|
|
public boss_anub_arakAI(Creature creature) : base(creature, ANDataTypes.Anubarak) { }
|
|
|
|
public override void Reset()
|
|
{
|
|
base.Reset();
|
|
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
|
instance.DoStopCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievGottaGoStartEvent);
|
|
_nextSubmerge = 75;
|
|
_petCount = 0;
|
|
}
|
|
|
|
public override void EnterCombat(Unit who)
|
|
{
|
|
base.EnterCombat(who);
|
|
|
|
GameObject door = instance.GetGameObject(ANDataTypes.AnubarakWall);
|
|
if (door)
|
|
door.SetGoState(GameObjectState.Active); // open door for now
|
|
|
|
Talk(TextIds.SayAggro);
|
|
instance.DoStartCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievGottaGoStartEvent);
|
|
|
|
_events.SetPhase(Misc.PhaseEmerge);
|
|
_events.ScheduleEvent(EventIds.CloseDoor, TimeSpan.FromSeconds(5));
|
|
_events.ScheduleEvent(EventIds.Pound, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), 0, Misc.PhaseEmerge);
|
|
_events.ScheduleEvent(EventIds.LeechingSwarm, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(7), 0, Misc.PhaseEmerge);
|
|
_events.ScheduleEvent(EventIds.CarrionBeetles, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(17), 0, Misc.PhaseEmerge);
|
|
|
|
// set up world triggers
|
|
List<TempSummon> summoned;
|
|
me.SummonCreatureGroup(Misc.SummonGroupWorldTriggerGuardian, out summoned);
|
|
if (summoned.Empty()) // something went wrong
|
|
{
|
|
EnterEvadeMode(EvadeReason.Other);
|
|
return;
|
|
}
|
|
_guardianTrigger = summoned.First().GetGUID();
|
|
|
|
Creature trigger = DoSummon(CreatureIds.WorldTrigger, me.GetPosition(), 0u, TempSummonType.ManualDespawn);
|
|
if (trigger)
|
|
_assassinTrigger = trigger.GetGUID();
|
|
else
|
|
{
|
|
EnterEvadeMode(EvadeReason.Other);
|
|
return;
|
|
}
|
|
}
|
|
|
|
public override void EnterEvadeMode(EvadeReason why)
|
|
{
|
|
summons.DespawnAll();
|
|
_DespawnAtEvade();
|
|
}
|
|
|
|
public override void UpdateAI(uint diff)
|
|
{
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
_events.Update(diff);
|
|
|
|
if (me.HasUnitState(UnitState.Casting))
|
|
return;
|
|
|
|
_events.ExecuteEvents(eventId =>
|
|
{
|
|
switch (eventId)
|
|
{
|
|
case EventIds.CloseDoor:
|
|
GameObject door = instance.GetGameObject(ANDataTypes.AnubarakWall);
|
|
if (door)
|
|
door.SetGoState(GameObjectState.Ready);
|
|
break;
|
|
case EventIds.Pound:
|
|
DoCastVictim(SpellIds.Pound);
|
|
_events.Repeat(TimeSpan.FromSeconds(26), TimeSpan.FromSeconds(32));
|
|
break;
|
|
case EventIds.LeechingSwarm:
|
|
Talk(TextIds.SayLocust);
|
|
DoCastAOE(SpellIds.LeechingSwarm);
|
|
_events.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(28));
|
|
break;
|
|
case EventIds.CarrionBeetles:
|
|
DoCastAOE(SpellIds.CarrionBeetles);
|
|
_events.Repeat(TimeSpan.FromSeconds(24), TimeSpan.FromSeconds(27));
|
|
break;
|
|
case EventIds.Impale:
|
|
Creature impaleTarget = ObjectAccessor.GetCreature(me, _impaleTarget);
|
|
if (impaleTarget)
|
|
DoCast(impaleTarget, SpellIds.ImpaleDamage, true);
|
|
break;
|
|
case EventIds.Submerge:
|
|
Talk(TextIds.SaySubmerge);
|
|
DoCastSelf(SpellIds.Submerge);
|
|
break;
|
|
case EventIds.Darter:
|
|
{
|
|
List<Creature> triggers = new List<Creature>();
|
|
me.GetCreatureListWithEntryInGrid(triggers, CreatureIds.WorldTrigger);
|
|
if (!triggers.Empty())
|
|
{
|
|
var it = triggers.SelectRandom();
|
|
it.CastSpell(it, SpellIds.SummonDarter, true);
|
|
_events.Repeat(TimeSpan.FromSeconds(11));
|
|
}
|
|
else
|
|
EnterEvadeMode(EvadeReason.Other);
|
|
break;
|
|
}
|
|
case EventIds.Assassin:
|
|
{
|
|
Creature trigger = ObjectAccessor.GetCreature(me, _assassinTrigger);
|
|
if (trigger)
|
|
{
|
|
trigger.CastSpell(trigger, SpellIds.SummonAssassin, true);
|
|
trigger.CastSpell(trigger, SpellIds.SummonAssassin, true);
|
|
if (_assassinCount > 2)
|
|
{
|
|
_assassinCount -= 2;
|
|
_events.Repeat(TimeSpan.FromSeconds(20));
|
|
}
|
|
else
|
|
_assassinCount = 0;
|
|
}
|
|
else // something went wrong
|
|
EnterEvadeMode(EvadeReason.Other);
|
|
break;
|
|
}
|
|
case EventIds.Guardian:
|
|
{
|
|
Creature trigger = ObjectAccessor.GetCreature(me, _guardianTrigger);
|
|
if (trigger)
|
|
{
|
|
trigger.CastSpell(trigger, SpellIds.SummonGuardian, true);
|
|
trigger.CastSpell(trigger, SpellIds.SummonGuardian, true);
|
|
if (_guardianCount > 2)
|
|
{
|
|
_guardianCount -= 2;
|
|
_events.Repeat(TimeSpan.FromSeconds(20));
|
|
}
|
|
else
|
|
_guardianCount = 0;
|
|
}
|
|
else
|
|
EnterEvadeMode(EvadeReason.Other);
|
|
}
|
|
break;
|
|
case EventIds.Venomancer:
|
|
{
|
|
Creature trigger = ObjectAccessor.GetCreature(me, _guardianTrigger);
|
|
if (trigger)
|
|
{
|
|
trigger.CastSpell(trigger, SpellIds.SummonVenomancer, true);
|
|
trigger.CastSpell(trigger, SpellIds.SummonVenomancer, true);
|
|
if (_venomancerCount > 2)
|
|
{
|
|
_venomancerCount -= 2;
|
|
_events.Repeat(TimeSpan.FromSeconds(20));
|
|
}
|
|
else
|
|
_venomancerCount = 0;
|
|
}
|
|
else
|
|
EnterEvadeMode(EvadeReason.Other);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (me.HasUnitState(UnitState.Casting))
|
|
return;
|
|
});
|
|
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
|
|
public override void JustDied(Unit killer)
|
|
{
|
|
_JustDied();
|
|
Talk(TextIds.SayDeath);
|
|
}
|
|
|
|
public override void KilledUnit(Unit victim)
|
|
{
|
|
if (victim.IsTypeId(TypeId.Player))
|
|
Talk(TextIds.SaySlay);
|
|
}
|
|
|
|
public override void SetGUID(ObjectGuid guid, int type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case Misc.GuidTypePet:
|
|
{
|
|
Creature creature = ObjectAccessor.GetCreature(me, guid);
|
|
if (creature)
|
|
JustSummoned(creature);
|
|
else // something has gone horribly wrong
|
|
EnterEvadeMode(EvadeReason.Other);
|
|
break;
|
|
}
|
|
case Misc.GuidTypeImpale:
|
|
_impaleTarget = guid;
|
|
_events.ScheduleEvent(EventIds.Impale, TimeSpan.FromSeconds(4));
|
|
break;
|
|
}
|
|
}
|
|
|
|
public override void DoAction(int action)
|
|
{
|
|
switch (action)
|
|
{
|
|
case Misc.ActionPetDied:
|
|
if (_petCount == 0) // underflow check - something has gone horribly wrong
|
|
{
|
|
EnterEvadeMode(EvadeReason.Other);
|
|
return;
|
|
}
|
|
if (--_petCount == 0) // last pet died, emerge
|
|
{
|
|
me.RemoveAurasDueToSpell(SpellIds.Submerge);
|
|
me.RemoveAurasDueToSpell(SpellIds.ImpaleAura);
|
|
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
|
DoCastSelf(SpellIds.Emerge);
|
|
_events.SetPhase(Misc.PhaseEmerge);
|
|
_events.ScheduleEvent(EventIds.Pound, TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(18), 0, Misc.PhaseEmerge);
|
|
_events.ScheduleEvent(EventIds.LeechingSwarm, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7), 0, Misc.PhaseEmerge);
|
|
_events.ScheduleEvent(EventIds.CarrionBeetles, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), 0, Misc.PhaseEmerge);
|
|
}
|
|
break;
|
|
case Misc.ActionPetEvade:
|
|
EnterEvadeMode(EvadeReason.Other);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public override void DamageTaken(Unit source, ref uint damage)
|
|
{
|
|
if (me.HasAura(SpellIds.Submerge))
|
|
damage = 0;
|
|
else
|
|
if (_nextSubmerge != 0 && me.HealthBelowPctDamaged((int)_nextSubmerge, damage))
|
|
{
|
|
_events.CancelEvent(EventIds.Submerge);
|
|
_events.ScheduleEvent(EventIds.Submerge, 0, 0, Misc.PhaseEmerge);
|
|
_nextSubmerge = _nextSubmerge - 25;
|
|
}
|
|
}
|
|
|
|
public override void SpellHit(Unit whose, SpellInfo spell)
|
|
{
|
|
if (spell.Id == SpellIds.Submerge)
|
|
{
|
|
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
|
me.RemoveAurasDueToSpell(SpellIds.LeechingSwarm);
|
|
DoCastSelf(SpellIds.ImpaleAura, true);
|
|
|
|
_events.SetPhase(Misc.PhaseSubmerge);
|
|
switch (_nextSubmerge)
|
|
{
|
|
case 50: // first submerge phase
|
|
_assassinCount = 4;
|
|
_guardianCount = 2;
|
|
_venomancerCount = 0;
|
|
break;
|
|
case 25: // second submerge phase
|
|
_assassinCount = 6;
|
|
_guardianCount = 2;
|
|
_venomancerCount = 2;
|
|
break;
|
|
case 0: // third submerge phase
|
|
_assassinCount = 6;
|
|
_guardianCount = 2;
|
|
_venomancerCount = 2;
|
|
_events.ScheduleEvent(EventIds.Darter, TimeSpan.FromSeconds(0), 0, Misc.PhaseSubmerge);
|
|
break;
|
|
}
|
|
_petCount = (uint)(_guardianCount + _venomancerCount);
|
|
if (_assassinCount != 0)
|
|
_events.ScheduleEvent(EventIds.Assassin, TimeSpan.FromSeconds(0), 0, Misc.PhaseSubmerge);
|
|
if (_guardianCount != 0)
|
|
_events.ScheduleEvent(EventIds.Guardian, TimeSpan.FromSeconds(4), 0, Misc.PhaseSubmerge);
|
|
if (_venomancerCount != 0)
|
|
_events.ScheduleEvent(EventIds.Venomancer, TimeSpan.FromSeconds(20), 0, Misc.PhaseSubmerge);
|
|
}
|
|
}
|
|
|
|
ObjectGuid _impaleTarget;
|
|
uint _nextSubmerge;
|
|
uint _petCount;
|
|
ObjectGuid _guardianTrigger;
|
|
ObjectGuid _assassinTrigger;
|
|
byte _assassinCount;
|
|
byte _guardianCount;
|
|
byte _venomancerCount;
|
|
}
|
|
|
|
public override CreatureAI GetAI(Creature creature)
|
|
{
|
|
return GetInstanceAI<boss_anub_arakAI>(creature);
|
|
}
|
|
}
|
|
|
|
class npc_anubarak_pet_template : ScriptedAI
|
|
{
|
|
public npc_anubarak_pet_template(Creature creature, bool isLarge) : base(creature)
|
|
{
|
|
_instance = creature.GetInstanceScript();
|
|
_isLarge = isLarge;
|
|
}
|
|
|
|
public override void InitializeAI()
|
|
{
|
|
base.InitializeAI();
|
|
|
|
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
|
|
if (anubarak)
|
|
anubarak.GetAI().SetGUID(me.GetGUID(), Misc.GuidTypePet);
|
|
else
|
|
me.DespawnOrUnsummon();
|
|
}
|
|
|
|
public override void JustDied(Unit killer)
|
|
{
|
|
base.JustDied(killer);
|
|
if (_isLarge)
|
|
{
|
|
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
|
|
if (anubarak)
|
|
anubarak.GetAI().DoAction(Misc.ActionPetDied);
|
|
}
|
|
}
|
|
|
|
public override void EnterEvadeMode(EvadeReason why)
|
|
{
|
|
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
|
|
if (anubarak)
|
|
anubarak.GetAI().DoAction(Misc.ActionPetEvade);
|
|
else
|
|
me.DespawnOrUnsummon();
|
|
}
|
|
|
|
protected InstanceScript _instance;
|
|
bool _isLarge;
|
|
}
|
|
|
|
[Script]
|
|
class npc_anubarak_anub_ar_darter : CreatureScript
|
|
{
|
|
public npc_anubarak_anub_ar_darter() : base("npc_anubarak_anub_ar_darter") { }
|
|
|
|
class npc_anubarak_anub_ar_darterAI : npc_anubarak_pet_template
|
|
{
|
|
public npc_anubarak_anub_ar_darterAI(Creature creature) : base(creature, false) { }
|
|
|
|
public override void InitializeAI()
|
|
{
|
|
base.InitializeAI();
|
|
DoCastAOE(SpellIds.Dart);
|
|
}
|
|
}
|
|
|
|
public override CreatureAI GetAI(Creature creature)
|
|
{
|
|
return GetInstanceAI<npc_anubarak_anub_ar_darterAI>(creature);
|
|
}
|
|
}
|
|
|
|
[Script]
|
|
class npc_anubarak_anub_ar_assassin : CreatureScript
|
|
{
|
|
public npc_anubarak_anub_ar_assassin() : base("npc_anubarak_anub_ar_assassin") { }
|
|
|
|
class npc_anubarak_anub_ar_assassinAI : npc_anubarak_pet_template
|
|
{
|
|
public npc_anubarak_anub_ar_assassinAI(Creature creature) : base(creature, false)
|
|
{
|
|
_backstabTimer = 6 * Time.InMilliseconds;
|
|
}
|
|
|
|
bool IsInBounds(Position jumpTo, List<AreaBoundary> boundary)
|
|
{
|
|
if (boundary == null)
|
|
return true;
|
|
foreach (var it in boundary)
|
|
if (!it.IsWithinBoundary(jumpTo))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
Position GetRandomPositionAround(Creature anubarak)
|
|
{
|
|
float DISTANCE_MIN = 10.0f;
|
|
float DISTANCE_MAX = 30.0f;
|
|
double angle = RandomHelper.NextDouble() * 2.0 * Math.PI;
|
|
return new Position(anubarak.GetPositionX() + (float)(RandomHelper.FRand(DISTANCE_MIN, DISTANCE_MAX) * Math.Sin(angle)), anubarak.GetPositionY() + (float)(RandomHelper.FRand(DISTANCE_MIN, DISTANCE_MAX) * Math.Cos(angle)), anubarak.GetPositionZ());
|
|
}
|
|
|
|
public override void InitializeAI()
|
|
{
|
|
base.InitializeAI();
|
|
var boundary = _instance.GetBossBoundary(ANDataTypes.Anubarak);
|
|
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
|
|
if (anubarak)
|
|
{
|
|
Position jumpTo;
|
|
do
|
|
jumpTo = GetRandomPositionAround(anubarak);
|
|
while (!IsInBounds(jumpTo, boundary));
|
|
me.GetMotionMaster().MoveJump(jumpTo, 40.0f, 40.0f);
|
|
DoCastSelf(SpellIds.AssassinVisual, true);
|
|
}
|
|
}
|
|
|
|
public override void UpdateAI(uint diff)
|
|
{
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
if (diff >= _backstabTimer)
|
|
{
|
|
if (me.GetVictim() && me.GetVictim().isInBack(me))
|
|
DoCastVictim(SpellIds.Backstab);
|
|
_backstabTimer = 6 * Time.InMilliseconds;
|
|
}
|
|
else
|
|
_backstabTimer -= diff;
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
|
|
public override void MovementInform(MovementGeneratorType type, uint id)
|
|
{
|
|
if (id == EventId.Jump)
|
|
{
|
|
me.RemoveAurasDueToSpell(SpellIds.AssassinVisual);
|
|
DoZoneInCombat();
|
|
}
|
|
}
|
|
|
|
uint _backstabTimer;
|
|
}
|
|
|
|
public override CreatureAI GetAI(Creature creature)
|
|
{
|
|
return GetInstanceAI<npc_anubarak_anub_ar_assassinAI>(creature);
|
|
}
|
|
}
|
|
|
|
[Script]
|
|
class npc_anubarak_anub_ar_guardian : CreatureScript
|
|
{
|
|
public npc_anubarak_anub_ar_guardian() : base("npc_anubarak_anub_ar_guardian") { }
|
|
|
|
class npc_anubarak_anub_ar_guardianAI : npc_anubarak_pet_template
|
|
{
|
|
public npc_anubarak_anub_ar_guardianAI(Creature creature) : base(creature, true)
|
|
{
|
|
_sunderTimer = 6 * Time.InMilliseconds;
|
|
}
|
|
|
|
public override void UpdateAI(uint diff)
|
|
{
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
if (diff >= _sunderTimer)
|
|
{
|
|
DoCastVictim(SpellIds.SunderArmor);
|
|
_sunderTimer = 12 * Time.InMilliseconds;
|
|
}
|
|
else
|
|
_sunderTimer -= diff;
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
|
|
uint _sunderTimer;
|
|
}
|
|
|
|
public override CreatureAI GetAI(Creature creature)
|
|
{
|
|
return GetInstanceAI<npc_anubarak_anub_ar_guardianAI>(creature);
|
|
}
|
|
}
|
|
|
|
[Script]
|
|
class npc_anubarak_anub_ar_venomancer : CreatureScript
|
|
{
|
|
public npc_anubarak_anub_ar_venomancer() : base("npc_anubarak_anub_ar_venomancer") { }
|
|
|
|
class npc_anubarak_anub_ar_venomancerAI : npc_anubarak_pet_template
|
|
{
|
|
public npc_anubarak_anub_ar_venomancerAI(Creature creature) : base(creature, true)
|
|
{
|
|
_boltTimer = 5 * Time.InMilliseconds;
|
|
}
|
|
|
|
public override void UpdateAI(uint diff)
|
|
{
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
if (diff >= _boltTimer)
|
|
{
|
|
DoCastVictim(SpellIds.PoisonBolt);
|
|
_boltTimer = RandomHelper.URand(2, 3) * Time.InMilliseconds;
|
|
}
|
|
else
|
|
_boltTimer -= diff;
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
|
|
uint _boltTimer;
|
|
}
|
|
|
|
public override CreatureAI GetAI(Creature creature)
|
|
{
|
|
return GetInstanceAI<npc_anubarak_anub_ar_venomancerAI>(creature);
|
|
}
|
|
}
|
|
|
|
[Script]
|
|
class npc_anubarak_impale_target : CreatureScript
|
|
{
|
|
public npc_anubarak_impale_target() : base("npc_anubarak_impale_target") { }
|
|
|
|
class npc_anubarak_impale_targetAI : NullCreatureAI
|
|
{
|
|
public npc_anubarak_impale_targetAI(Creature creature) : base(creature) { }
|
|
|
|
public override void InitializeAI()
|
|
{
|
|
Creature anubarak = me.GetInstanceScript().GetCreature(ANDataTypes.Anubarak);
|
|
if (anubarak)
|
|
{
|
|
DoCastSelf(SpellIds.ImpaleVisual);
|
|
me.DespawnOrUnsummon(TimeSpan.FromSeconds(6));
|
|
anubarak.GetAI().SetGUID(me.GetGUID(), Misc.GuidTypeImpale);
|
|
}
|
|
else
|
|
me.DespawnOrUnsummon();
|
|
}
|
|
}
|
|
|
|
public override CreatureAI GetAI(Creature creature)
|
|
{
|
|
return GetInstanceAI<npc_anubarak_impale_targetAI>(creature);
|
|
}
|
|
}
|
|
|
|
[Script]
|
|
class spell_anubarak_pound : SpellScriptLoader
|
|
{
|
|
public spell_anubarak_pound() : base("spell_anubarak_pound") { }
|
|
|
|
class spell_anubarak_pound_SpellScript : SpellScript
|
|
{
|
|
public override bool Validate(SpellInfo spell)
|
|
{
|
|
return ValidateSpellInfo(SpellIds.PoundDamage);
|
|
}
|
|
|
|
void HandleDummy(uint effIndex)
|
|
{
|
|
Unit target = GetHitUnit();
|
|
if (target)
|
|
GetCaster().CastSpell(target, SpellIds.PoundDamage, true);
|
|
}
|
|
|
|
public override void Register()
|
|
{
|
|
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.ApplyAura));
|
|
}
|
|
}
|
|
|
|
public override SpellScript GetSpellScript()
|
|
{
|
|
return new spell_anubarak_pound_SpellScript();
|
|
}
|
|
}
|
|
|
|
[Script]
|
|
class spell_anubarak_carrion_beetles : SpellScriptLoader
|
|
{
|
|
public spell_anubarak_carrion_beetles() : base("spell_anubarak_carrion_beetles") { }
|
|
|
|
class spell_anubarak_carrion_beetles_AuraScript : AuraScript
|
|
{
|
|
public override bool Validate(SpellInfo spell)
|
|
{
|
|
return ValidateSpellInfo(SpellIds.CarrionBeetle);
|
|
}
|
|
|
|
void HandlePeriodic(AuraEffect eff)
|
|
{
|
|
GetCaster().CastSpell(GetCaster(), SpellIds.CarrionBeetle, true);
|
|
GetCaster().CastSpell(GetCaster(), SpellIds.CarrionBeetle, true);
|
|
}
|
|
|
|
public override void Register()
|
|
{
|
|
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodic, 0, AuraType.PeriodicDummy));
|
|
}
|
|
}
|
|
|
|
public override AuraScript GetAuraScript()
|
|
{
|
|
return new spell_anubarak_carrion_beetles_AuraScript();
|
|
}
|
|
}
|
|
}
|