Ported .Net Core commits:
hondacrx: - Initial commit: Switch to .Net Core 2.0 - Fix build and removed not needed files Fabi: - Updated solution platforms. - Changed folder structure. - Change library target framework to netstandard2.0. - Updated solution platforms again... - Removed windows specific kernel32 function usage (Ctrl-C handler).
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Scripts.EasternKingdoms.Deadmines
|
||||
{
|
||||
/*class instance_deadmines : InstanceMapScript
|
||||
{
|
||||
public instance_deadmines() : base("instance_deadmines", 36)
|
||||
{
|
||||
}
|
||||
|
||||
class instance_deadmines_InstanceMapScript : InstanceScript
|
||||
{
|
||||
public instance_deadmines_InstanceMapScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
|
||||
State = CANNON_NOT_USED;
|
||||
CannonBlast_Timer = 0;
|
||||
PiratesDelay_Timer = 0;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Update(uint diff)
|
||||
{
|
||||
if (IronCladDoorGUID.IsEmpty() || DefiasCannonGUID.IsEmpty() || DoorLeverGUID.IsEmpty())
|
||||
return;
|
||||
|
||||
GameObject pIronCladDoor = instance.GetGameObject(IronCladDoorGUID);
|
||||
if (!pIronCladDoor)
|
||||
return;
|
||||
|
||||
switch (State)
|
||||
{
|
||||
case CANNON_GUNPOWDER_USED:
|
||||
CannonBlast_Timer = DATA_CANNON_BLAST_TIMER;
|
||||
// it's a hack - Mr. Smite should do that but his too far away
|
||||
//pIronCladDoor.SetName("Mr. Smite");
|
||||
//pIronCladDoor.MonsterYell(SAY_MR_SMITE_ALARM1, LANG_UNIVERSAL, NULL);
|
||||
pIronCladDoor.PlayDirectSound(SOUND_MR_SMITE_ALARM1);
|
||||
State = CANNON_BLAST_INITIATED;
|
||||
break;
|
||||
case CANNON_BLAST_INITIATED:
|
||||
PiratesDelay_Timer = DATA_PIRATES_DELAY_TIMER;
|
||||
if (CannonBlast_Timer <= diff)
|
||||
{
|
||||
SummonCreatures();
|
||||
GameObject pDefiasCannon = instance.GetGameObject(DefiasCannonGUID);
|
||||
if (pDefiasCannon)
|
||||
{
|
||||
pDefiasCannon.SetGoState(GO_STATE_ACTIVE);
|
||||
pDefiasCannon.PlayDirectSound(SOUND_CANNONFIRE);
|
||||
}
|
||||
pIronCladDoor.SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
|
||||
pIronCladDoor.PlayDirectSound(SOUND_DESTROYDOOR);
|
||||
GameObject pDoorLever = instance.GetGameObject(DoorLeverGUID);
|
||||
if (pDoorLever)
|
||||
pDoorLever.SetUInt32Value(GAMEOBJECT_FLAGS, 4);
|
||||
//pIronCladDoor.MonsterYell(SAY_MR_SMITE_ALARM2, LANG_UNIVERSAL, NULL);
|
||||
pIronCladDoor.PlayDirectSound(SOUND_MR_SMITE_ALARM2);
|
||||
State = PIRATES_ATTACK;
|
||||
}
|
||||
else CannonBlast_Timer -= diff;
|
||||
break;
|
||||
case PIRATES_ATTACK:
|
||||
if (PiratesDelay_Timer <= diff)
|
||||
{
|
||||
MoveCreaturesInside();
|
||||
State = EVENT_DONE;
|
||||
}
|
||||
else PiratesDelay_Timer -= diff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SummonCreatures()
|
||||
{
|
||||
GameObject pIronCladDoor = instance.GetGameObject(IronCladDoorGUID);
|
||||
if (pIronCladDoor)
|
||||
{
|
||||
Creature DefiasPirate1 = pIronCladDoor.SummonCreature(657, pIronCladDoor.GetPositionX() - 2, pIronCladDoor.GetPositionY() - 7, pIronCladDoor.GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
|
||||
Creature DefiasPirate2 = pIronCladDoor.SummonCreature(657, pIronCladDoor.GetPositionX() + 3, pIronCladDoor.GetPositionY() - 6, pIronCladDoor.GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
|
||||
Creature DefiasCompanion = pIronCladDoor.SummonCreature(3450, pIronCladDoor.GetPositionX() + 2, pIronCladDoor.GetPositionY() - 6, pIronCladDoor.GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
|
||||
|
||||
DefiasPirate1GUID = DefiasPirate1.GetGUID();
|
||||
DefiasPirate2GUID = DefiasPirate2.GetGUID();
|
||||
DefiasCompanionGUID = DefiasCompanion.GetGUID();
|
||||
}
|
||||
}
|
||||
|
||||
void MoveCreaturesInside()
|
||||
{
|
||||
if (DefiasPirate1GUID.IsEmpty() || DefiasPirate2GUID.IsEmpty() || DefiasCompanionGUID.IsEmpty())
|
||||
return;
|
||||
|
||||
Creature pDefiasPirate1 = instance.GetCreature(DefiasPirate1GUID);
|
||||
Creature pDefiasPirate2 = instance.GetCreature(DefiasPirate2GUID);
|
||||
Creature pDefiasCompanion = instance.GetCreature(DefiasCompanionGUID);
|
||||
if (!pDefiasPirate1 || !pDefiasPirate2 || !pDefiasCompanion)
|
||||
return;
|
||||
|
||||
MoveCreatureInside(pDefiasPirate1);
|
||||
MoveCreatureInside(pDefiasPirate2);
|
||||
MoveCreatureInside(pDefiasCompanion);
|
||||
}
|
||||
|
||||
void MoveCreatureInside(Creature creature)
|
||||
{
|
||||
creature.SetWalk(false);
|
||||
creature.GetMotionMaster().MovePoint(0, -102.7f, -655.9f, creature.GetPositionZ());
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GO_FACTORY_DOOR: FactoryDoorGUID = go.GetGUID(); break;
|
||||
case GO_IRONCLAD_DOOR: IronCladDoorGUID = go.GetGUID(); break;
|
||||
case GO_DEFIAS_CANNON: DefiasCannonGUID = go.GetGUID(); break;
|
||||
case GO_DOOR_LEVER: DoorLeverGUID = go.GetGUID(); break;
|
||||
case GO_MR_SMITE_CHEST: uiSmiteChestGUID = go.GetGUID(); break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetData(uint type, uint data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EVENT_STATE:
|
||||
if (!DefiasCannonGUID.IsEmpty() && !IronCladDoorGUID.IsEmpty())
|
||||
State = data;
|
||||
break;
|
||||
case EVENT_RHAHKZOR:
|
||||
if (data == DONE)
|
||||
{
|
||||
GameObject go = instance.GetGameObject(FactoryDoorGUID);
|
||||
if (go)
|
||||
go.SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EVENT_STATE:
|
||||
return State;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case DATA_SMITE_CHEST:
|
||||
return uiSmiteChestGUID;
|
||||
}
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
|
||||
ObjectGuid FactoryDoorGUID;
|
||||
ObjectGuid IronCladDoorGUID;
|
||||
ObjectGuid DefiasCannonGUID;
|
||||
ObjectGuid DoorLeverGUID;
|
||||
ObjectGuid DefiasPirate1GUID;
|
||||
ObjectGuid DefiasPirate2GUID;
|
||||
ObjectGuid DefiasCompanionGUID;
|
||||
|
||||
uint State;
|
||||
uint CannonBlast_Timer;
|
||||
uint PiratesDelay_Timer;
|
||||
ObjectGuid uiSmiteChestGUID;
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_deadmines_InstanceMapScript(map);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.EasternKingdoms.Karazhan.Midnight
|
||||
{
|
||||
struct Misc
|
||||
{
|
||||
public const uint MountedDisplayid = 16040;
|
||||
|
||||
//Attumen (@Todo Use The Summoning Spell Instead Of Creature Id. It Works; But Is Not Convenient For Us)
|
||||
public const uint SummonAttumen = 15550;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayMidnightKill = 0;
|
||||
public const uint SayAppear = 1;
|
||||
public const uint SayMount = 2;
|
||||
|
||||
public const uint SayKill = 0;
|
||||
public const uint SayDisarmed = 1;
|
||||
public const uint SayDeath = 2;
|
||||
public const uint SayRandom = 3;
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Shadowcleave = 29832;
|
||||
public const uint IntangiblePresence = 29833;
|
||||
public const uint BerserkerCharge = 26561; //Only When Mounted
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class boss_attumen : ScriptedAI
|
||||
{
|
||||
public boss_attumen(Creature creature) : base(creature)
|
||||
{
|
||||
CleaveTimer = RandomHelper.URand(10000, 15000);
|
||||
CurseTimer = 30000;
|
||||
RandomYellTimer = RandomHelper.URand(30000, 60000); //Occasionally yell
|
||||
ChargeTimer = 20000;
|
||||
ResetTimer = 0;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
ResetTimer = 0;
|
||||
Midnight.Clear();
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
base.EnterEvadeMode(why);
|
||||
ResetTimer = 2000;
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
Talk(TextIds.SayKill);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(TextIds.SayDeath);
|
||||
Unit midnight = Global.ObjAccessor.GetUnit(me, Midnight);
|
||||
if (midnight)
|
||||
midnight.KillSelf();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (ResetTimer != 0)
|
||||
{
|
||||
if (ResetTimer <= diff)
|
||||
{
|
||||
ResetTimer = 0;
|
||||
Unit pMidnight = Global.ObjAccessor.GetUnit(me, Midnight);
|
||||
if (pMidnight)
|
||||
{
|
||||
pMidnight.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
pMidnight.SetVisible(true);
|
||||
}
|
||||
Midnight.Clear();
|
||||
me.SetVisible(false);
|
||||
me.KillSelf();
|
||||
}
|
||||
else ResetTimer -= diff;
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me.HasFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable))
|
||||
return;
|
||||
|
||||
if (CleaveTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Shadowcleave);
|
||||
CleaveTimer = RandomHelper.URand(10000, 15000);
|
||||
}
|
||||
else CleaveTimer -= diff;
|
||||
|
||||
if (CurseTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.IntangiblePresence);
|
||||
CurseTimer = 30000;
|
||||
}
|
||||
else CurseTimer -= diff;
|
||||
|
||||
if (RandomYellTimer <= diff)
|
||||
{
|
||||
Talk(TextIds.SayRandom);
|
||||
RandomYellTimer = RandomHelper.URand(30000, 60000);
|
||||
}
|
||||
else RandomYellTimer -= diff;
|
||||
|
||||
if (me.GetUInt32Value(UnitFields.DisplayId) == Misc.MountedDisplayid)
|
||||
{
|
||||
if (ChargeTimer <= diff)
|
||||
{
|
||||
var t_list = me.GetThreatManager().getThreatList();
|
||||
List<Unit> target_list = new List<Unit>();
|
||||
foreach (var hostileRefe in t_list)
|
||||
{
|
||||
var unit = Global.ObjAccessor.GetUnit(me, hostileRefe.getUnitGuid());
|
||||
if (unit && !unit.IsWithinDist(me, SharedConst.AttackDistance, false))
|
||||
target_list.Add(unit);
|
||||
unit = null;
|
||||
}
|
||||
Unit target = null;
|
||||
if (!target_list.Empty())
|
||||
target = target_list.SelectRandom();
|
||||
|
||||
DoCast(target, SpellIds.BerserkerCharge);
|
||||
ChargeTimer = 20000;
|
||||
}
|
||||
else ChargeTimer -= diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HealthBelowPct(25))
|
||||
{
|
||||
Creature pMidnight = ObjectAccessor.GetCreature(me, Midnight);
|
||||
if (pMidnight && pMidnight.IsTypeId(TypeId.Unit))
|
||||
{
|
||||
((boss_midnight)pMidnight.GetAI()).Mount(me);
|
||||
me.SetHealth(pMidnight.GetHealth());
|
||||
DoResetThreat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void SpellHit(Unit source, SpellInfo spell)
|
||||
{
|
||||
if (spell.Mechanic == Mechanics.Disarm)
|
||||
Talk(TextIds.SayDisarmed);
|
||||
}
|
||||
|
||||
public ObjectGuid Midnight;
|
||||
uint CleaveTimer;
|
||||
uint CurseTimer;
|
||||
uint RandomYellTimer;
|
||||
uint ChargeTimer; //only when mounted
|
||||
uint ResetTimer;
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class boss_midnight : ScriptedAI
|
||||
{
|
||||
public boss_midnight(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Phase = 1;
|
||||
Attumen.Clear();
|
||||
mountTimer = 0;
|
||||
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
me.SetVisible(true);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (Phase == 2)
|
||||
{
|
||||
Unit unit = Global.ObjAccessor.GetUnit(me, Attumen);
|
||||
if (unit)
|
||||
Talk(TextIds.SayMidnightKill, unit);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (Phase == 1 && HealthBelowPct(95))
|
||||
{
|
||||
Phase = 2;
|
||||
Creature attumen = me.SummonCreature(Misc.SummonAttumen, 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType.TimedOrDeadDespawn, 30000);
|
||||
if (attumen)
|
||||
{
|
||||
Attumen = attumen.GetGUID();
|
||||
attumen.GetAI().AttackStart(me.GetVictim());
|
||||
SetMidnight(attumen, me.GetGUID());
|
||||
Talk(TextIds.SayAppear, attumen);
|
||||
}
|
||||
}
|
||||
else if (Phase == 2 && HealthBelowPct(25))
|
||||
{
|
||||
Unit pAttumen = Global.ObjAccessor.GetUnit(me, Attumen);
|
||||
if (pAttumen)
|
||||
Mount(pAttumen);
|
||||
}
|
||||
else if (Phase == 3)
|
||||
{
|
||||
if (mountTimer != 0)
|
||||
{
|
||||
if (mountTimer <= diff)
|
||||
{
|
||||
mountTimer = 0;
|
||||
me.SetVisible(false);
|
||||
me.GetMotionMaster().MoveIdle();
|
||||
Unit pAttumen = Global.ObjAccessor.GetUnit(me, Attumen);
|
||||
if (pAttumen)
|
||||
{
|
||||
pAttumen.SetDisplayId(Misc.MountedDisplayid);
|
||||
pAttumen.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
if (pAttumen.GetVictim())
|
||||
{
|
||||
pAttumen.GetMotionMaster().MoveChase(pAttumen.GetVictim());
|
||||
pAttumen.SetTarget(pAttumen.GetVictim().GetGUID());
|
||||
}
|
||||
pAttumen.SetObjectScale(1);
|
||||
}
|
||||
}
|
||||
else mountTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
if (Phase != 3)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public void Mount(Unit pAttumen)
|
||||
{
|
||||
Talk(TextIds.SayMount, pAttumen);
|
||||
Phase = 3;
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
pAttumen.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
float angle = me.GetAngle(pAttumen);
|
||||
float distance = me.GetDistance2d(pAttumen);
|
||||
float newX = me.GetPositionX() + (float)Math.Cos(angle) * (distance / 2);
|
||||
float newY = me.GetPositionY() + (float)Math.Sin(angle) * (distance / 2);
|
||||
float newZ = 50;
|
||||
me.GetMotionMaster().Clear();
|
||||
me.GetMotionMaster().MovePoint(0, newX, newY, newZ);
|
||||
distance += 10;
|
||||
newX = me.GetPositionX() + (float)Math.Cos(angle) * (distance / 2);
|
||||
newY = me.GetPositionY() + (float)Math.Sin(angle) * (distance / 2);
|
||||
pAttumen.GetMotionMaster().Clear();
|
||||
pAttumen.GetMotionMaster().MovePoint(0, newX, newY, newZ);
|
||||
mountTimer = 1000;
|
||||
}
|
||||
|
||||
void SetMidnight(Creature pAttumen, ObjectGuid value)
|
||||
{
|
||||
((boss_attumen)pAttumen.GetAI()).Midnight = value;
|
||||
}
|
||||
|
||||
ObjectGuid Attumen;
|
||||
byte Phase;
|
||||
uint mountTimer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.EasternKingdoms.Karazhan.Curator
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SaySummon = 1;
|
||||
public const uint SayEvocate = 2;
|
||||
public const uint SayEnrage = 3;
|
||||
public const uint SayKill = 4;
|
||||
public const uint SayDeath = 5;
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
//Flare spell info
|
||||
public const uint AstralFlarePassive = 30234; //Visual effect + Flare damage
|
||||
|
||||
//Curator spell info
|
||||
public const uint HatefulBolt = 30383;
|
||||
public const uint Evocation = 30254;
|
||||
public const uint Enrage = 30403; //Arcane Infusion: Transforms Curator and adds damage.
|
||||
public const uint Berserk = 26662;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_curator : ScriptedAI
|
||||
{
|
||||
public boss_curator(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
//Summon Astral Flare
|
||||
Creature AstralFlare = DoSpawnCreature(17096, RandomHelper.Rand32() % 37, RandomHelper.Rand32() % 37, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
|
||||
if (AstralFlare && target)
|
||||
{
|
||||
AstralFlare.CastSpell(AstralFlare, SpellIds.AstralFlarePassive, false);
|
||||
AstralFlare.GetAI().AttackStart(target);
|
||||
}
|
||||
|
||||
//Reduce Mana by 10% of max health
|
||||
int mana = me.GetMaxPower(PowerType.Mana);
|
||||
if (mana != 0)
|
||||
{
|
||||
mana /= 10;
|
||||
me.ModifyPower(PowerType.Mana, -mana);
|
||||
|
||||
//if this get's us below 10%, then we evocate (the 10th should be summoned now)
|
||||
if (me.GetPower(PowerType.Mana) * 100 / me.GetMaxPower(PowerType.Mana) < 10)
|
||||
{
|
||||
Talk(TextIds.SayEvocate);
|
||||
me.InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SpellIds.Evocation);
|
||||
_scheduler.DelayAll(TimeSpan.FromSeconds(20));
|
||||
//Evocating = true;
|
||||
//no AddTimer cooldown, this will make first flare appear instantly after evocate end, like expected
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RandomHelper.URand(0, 1) == 0)
|
||||
{
|
||||
Talk(TextIds.SaySummon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task.Repeat();
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
if (Enraged)
|
||||
task.Repeat(TimeSpan.FromSeconds(7));
|
||||
else
|
||||
task.Repeat();
|
||||
|
||||
Unit target = SelectTarget(SelectAggroTarget.TopAggro, 1);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.HatefulBolt);
|
||||
});
|
||||
|
||||
Enraged = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Arcane, true);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
Talk(TextIds.SayKill);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(TextIds.SayDeath);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit victim)
|
||||
{
|
||||
Talk(TextIds.SayAggro);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (!Enraged)
|
||||
{
|
||||
if (!HealthAbovePct(15))
|
||||
{
|
||||
Enraged = true;
|
||||
DoCast(me, SpellIds.Enrage);
|
||||
Talk(TextIds.SayEnrage);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Enraged;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* 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 Framework.IO;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using Game.AI;
|
||||
|
||||
namespace Scripts.EasternKingdoms.Karazhan
|
||||
{
|
||||
struct karazhanConst
|
||||
{
|
||||
public const uint MaxEncounter = 12;
|
||||
|
||||
public const uint BossAttumen = 1;
|
||||
public const uint BossMoroes = 2;
|
||||
public const uint BossMaiden = 3;
|
||||
public const uint OptionalBoss = 4;
|
||||
public const uint BossOpera = 5;
|
||||
public const uint Curator = 6;
|
||||
public const uint Aran = 7;
|
||||
public const uint Terestian = 8;
|
||||
public const uint Netherspite = 9;
|
||||
public const uint Chess = 10;
|
||||
public const uint Malchezzar = 11;
|
||||
public const uint Nightbane = 12;
|
||||
|
||||
public static Dialogue[] OzDialogue =
|
||||
{
|
||||
new Dialogue(0, 6000),
|
||||
new Dialogue(1, 18000),
|
||||
new Dialogue(2, 9000),
|
||||
new Dialogue(3, 15000)
|
||||
};
|
||||
|
||||
public static Dialogue[] HoodDialogue =
|
||||
{
|
||||
new Dialogue(4, 6000),
|
||||
new Dialogue(5, 10000),
|
||||
new Dialogue(6, 14000),
|
||||
new Dialogue(7, 15000)
|
||||
};
|
||||
|
||||
public static Dialogue[] RAJDialogue =
|
||||
{
|
||||
new Dialogue(8, 5000),
|
||||
new Dialogue(9, 7000),
|
||||
new Dialogue(10, 14000),
|
||||
new Dialogue(11, 14000)
|
||||
};
|
||||
|
||||
// Entries and spawn locations for creatures in Oz event
|
||||
public static float[][] Spawns =
|
||||
{
|
||||
new float[] { 17535, -10896}, // Dorothee
|
||||
new float[] { 17546, -10891}, // Roar
|
||||
new float[] { 17547, -10884}, // Tinhead
|
||||
new float[] { 17543, -10902}, // Strawman
|
||||
new float[] { 17603, -10892}, // Grandmother
|
||||
new float[] { 17534, -10900}, // Julianne
|
||||
};
|
||||
|
||||
public static float SPAWN_Z = 90.5f;
|
||||
public static float SPAWN_Y = -1758f;
|
||||
public static float SPAWN_O = 4.738f;
|
||||
|
||||
public static string SAY_READY = "Splendid, I'm going to get the audience ready. Break a leg!";
|
||||
public static string SAY_OZ_INTRO1 = "Finally, everything is in place. Are you ready for your big stage debut?";
|
||||
public static string OZ_GOSSIP1 = "I'm not an actor.";
|
||||
public static string SAY_OZ_INTRO2 = "Don't worry, you'll be fine. You look like a natural!";
|
||||
public static string OZ_GOSSIP2 = "Ok, I'll give it a try, then.";
|
||||
|
||||
public static string SAY_RAJ_INTRO1 = "The romantic plays are really tough, but you'll do better this time. You have TALENT. Ready?";
|
||||
public static string RAJ_GOSSIP1 = "I've never been more ready.";
|
||||
|
||||
public static string OZ_GM_GOSSIP1 = "[GM] Change event to EVENT_OZ";
|
||||
public static string OZ_GM_GOSSIP2 = "[GM] Change event to EVENT_HOOD";
|
||||
public static string OZ_GM_GOSSIP3 = "[GM] Change event to EVENT_RAJ";
|
||||
|
||||
// Barnes
|
||||
public const uint SpellSpotlight = 25824;
|
||||
public const uint SpellTuxedo = 32616;
|
||||
|
||||
// Berthold
|
||||
public const uint SpellTeleport = 39567;
|
||||
|
||||
// Image of Medivh
|
||||
public const uint SpellFireBall = 30967;
|
||||
public const uint SpellUberFireball = 30971;
|
||||
public const uint SpellConflagrationBlast = 30977;
|
||||
public const uint SpellManaShield = 31635;
|
||||
|
||||
public const uint NpcArcanagos = 17652;
|
||||
public const uint NpcSpotlight = 19525;
|
||||
}
|
||||
|
||||
struct Dialogue
|
||||
{
|
||||
public Dialogue(int textid, uint timer)
|
||||
{
|
||||
TextId = textid;
|
||||
Timer = timer;
|
||||
}
|
||||
|
||||
public int TextId;
|
||||
public uint Timer;
|
||||
}
|
||||
|
||||
struct DataTypes
|
||||
{
|
||||
public const uint OperaPerformance = 13;
|
||||
public const uint OperaOzDeathcount = 14;
|
||||
|
||||
public const uint Kilrek = 15;
|
||||
public const uint Terestian = 16;
|
||||
public const uint Moroes = 17;
|
||||
public const uint GoCurtains = 18;
|
||||
public const uint GoStagedoorleft = 19;
|
||||
public const uint GoStagedoorright = 20;
|
||||
public const uint GoLibraryDoor = 21;
|
||||
public const uint GoMassiveDoor = 22;
|
||||
public const uint GoNetherDoor = 23;
|
||||
public const uint GoGameDoor = 24;
|
||||
public const uint GoGameExitDoor = 25;
|
||||
|
||||
public const uint ImageOfMedivh = 26;
|
||||
public const uint MastersTerraceDoor1 = 27;
|
||||
public const uint MastersTerraceDoor2 = 28;
|
||||
public const uint GoSideEntranceDoor = 29;
|
||||
}
|
||||
|
||||
struct OperaEvents
|
||||
{
|
||||
public const uint Oz = 1;
|
||||
public const uint Hood = 2;
|
||||
public const uint RAJ = 3;
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class instance_karazhan : InstanceMapScript
|
||||
{
|
||||
public instance_karazhan() : base("instance_karazhan", 532) { }
|
||||
|
||||
public class instance_karazhan_InstanceMapScript : InstanceScript
|
||||
{
|
||||
public instance_karazhan_InstanceMapScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("KZ");
|
||||
|
||||
// 1 - OZ, 2 - HOOD, 3 - RAJ, this never gets altered.
|
||||
m_uiOperaEvent = RandomHelper.URand(1, 3);
|
||||
m_uiOzDeathCount = 0;
|
||||
}
|
||||
|
||||
public override bool IsEncounterInProgress()
|
||||
{
|
||||
for (byte i = 0; i < karazhanConst.MaxEncounter; ++i)
|
||||
if (m_auiEncounter[i] == (uint)EncounterState.InProgress)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case 17229:
|
||||
m_uiKilrekGUID = creature.GetGUID();
|
||||
break;
|
||||
case 15688:
|
||||
m_uiTerestianGUID = creature.GetGUID();
|
||||
break;
|
||||
case 15687:
|
||||
m_uiMoroesGUID = creature.GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetData(uint type, uint uiData)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case karazhanConst.BossAttumen:
|
||||
m_auiEncounter[0] = uiData;
|
||||
break;
|
||||
case karazhanConst.BossMoroes:
|
||||
if (m_auiEncounter[1] == (uint)EncounterState.Done)
|
||||
break;
|
||||
m_auiEncounter[1] = uiData;
|
||||
break;
|
||||
case karazhanConst.BossMaiden:
|
||||
m_auiEncounter[2] = uiData;
|
||||
break;
|
||||
case karazhanConst.OptionalBoss:
|
||||
m_auiEncounter[3] = uiData;
|
||||
break;
|
||||
case karazhanConst.BossOpera:
|
||||
m_auiEncounter[4] = uiData;
|
||||
if (uiData == (uint)EncounterState.Done)
|
||||
UpdateEncounterStateForKilledCreature(16812, null);
|
||||
break;
|
||||
case karazhanConst.Curator:
|
||||
m_auiEncounter[5] = uiData;
|
||||
break;
|
||||
case karazhanConst.Aran:
|
||||
m_auiEncounter[6] = uiData;
|
||||
break;
|
||||
case karazhanConst.Terestian:
|
||||
m_auiEncounter[7] = uiData;
|
||||
break;
|
||||
case karazhanConst.Netherspite:
|
||||
m_auiEncounter[8] = uiData;
|
||||
break;
|
||||
case karazhanConst.Chess:
|
||||
if (uiData == (uint)EncounterState.Done)
|
||||
DoRespawnGameObject(DustCoveredChest, Time.Day);
|
||||
m_auiEncounter[9] = uiData;
|
||||
break;
|
||||
case karazhanConst.Malchezzar:
|
||||
m_auiEncounter[10] = uiData;
|
||||
break;
|
||||
case karazhanConst.Nightbane:
|
||||
if (m_auiEncounter[11] != (uint)EncounterState.Done)
|
||||
m_auiEncounter[11] = uiData;
|
||||
break;
|
||||
case DataTypes.OperaOzDeathcount:
|
||||
if (uiData == (uint)EncounterState.Special)
|
||||
++m_uiOzDeathCount;
|
||||
else if (uiData == (uint)EncounterState.InProgress)
|
||||
m_uiOzDeathCount = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uiData == (uint)EncounterState.Done)
|
||||
{
|
||||
OUT_SAVE_INST_DATA();
|
||||
|
||||
strSaveData = string.Format("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11}", m_auiEncounter[0], m_auiEncounter[1], m_auiEncounter[2], m_auiEncounter[3],
|
||||
m_auiEncounter[4], m_auiEncounter[5], m_auiEncounter[6], m_auiEncounter[7], m_auiEncounter[8], m_auiEncounter[9], m_auiEncounter[10], m_auiEncounter[11]);
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE();
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetGuidData(uint identifier, ObjectGuid data)
|
||||
{
|
||||
if (identifier == DataTypes.ImageOfMedivh)
|
||||
ImageGUID = data;
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case 183932:
|
||||
m_uiCurtainGUID = go.GetGUID();
|
||||
break;
|
||||
case 184278:
|
||||
m_uiStageDoorLeftGUID = go.GetGUID();
|
||||
if (m_auiEncounter[4] == (uint)EncounterState.Done)
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
break;
|
||||
case 184279:
|
||||
m_uiStageDoorRightGUID = go.GetGUID();
|
||||
if (m_auiEncounter[4] == (uint)EncounterState.Done)
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
break;
|
||||
case 184517:
|
||||
m_uiLibraryDoor = go.GetGUID();
|
||||
break;
|
||||
case 185521:
|
||||
m_uiMassiveDoor = go.GetGUID();
|
||||
break;
|
||||
case 184276:
|
||||
m_uiGamesmansDoor = go.GetGUID();
|
||||
break;
|
||||
case 184277:
|
||||
m_uiGamesmansExitDoor = go.GetGUID();
|
||||
break;
|
||||
case 185134:
|
||||
m_uiNetherspaceDoor = go.GetGUID();
|
||||
break;
|
||||
case 184274:
|
||||
MastersTerraceDoor[0] = go.GetGUID();
|
||||
break;
|
||||
case 184280:
|
||||
MastersTerraceDoor[1] = go.GetGUID();
|
||||
break;
|
||||
case 184275:
|
||||
m_uiSideEntranceDoor = go.GetGUID();
|
||||
if (m_auiEncounter[4] == (uint)EncounterState.Done)
|
||||
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.Locked);
|
||||
else
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.Locked);
|
||||
break;
|
||||
case 185119:
|
||||
DustCoveredChest = go.GetGUID();
|
||||
break;
|
||||
}
|
||||
|
||||
switch (m_uiOperaEvent)
|
||||
{
|
||||
/// @todo Set Object visibilities for Opera based on performance
|
||||
case OperaEvents.Oz:
|
||||
break;
|
||||
|
||||
case OperaEvents.Hood:
|
||||
break;
|
||||
|
||||
case OperaEvents.RAJ:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetSaveData()
|
||||
{
|
||||
return strSaveData;
|
||||
}
|
||||
|
||||
public override uint GetData(uint uiData)
|
||||
{
|
||||
switch (uiData)
|
||||
{
|
||||
case karazhanConst.BossAttumen:
|
||||
return m_auiEncounter[0];
|
||||
case karazhanConst.BossMoroes:
|
||||
return m_auiEncounter[1];
|
||||
case karazhanConst.BossMaiden:
|
||||
return m_auiEncounter[2];
|
||||
case karazhanConst.OptionalBoss:
|
||||
return m_auiEncounter[3];
|
||||
case karazhanConst.BossOpera:
|
||||
return m_auiEncounter[4];
|
||||
case karazhanConst.Curator:
|
||||
return m_auiEncounter[5];
|
||||
case karazhanConst.Aran:
|
||||
return m_auiEncounter[6];
|
||||
case karazhanConst.Terestian:
|
||||
return m_auiEncounter[7];
|
||||
case karazhanConst.Netherspite:
|
||||
return m_auiEncounter[8];
|
||||
case karazhanConst.Chess:
|
||||
return m_auiEncounter[9];
|
||||
case karazhanConst.Malchezzar:
|
||||
return m_auiEncounter[10];
|
||||
case karazhanConst.Nightbane:
|
||||
return m_auiEncounter[11];
|
||||
case DataTypes.OperaPerformance:
|
||||
return m_uiOperaEvent;
|
||||
case DataTypes.OperaOzDeathcount:
|
||||
return m_uiOzDeathCount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint uiData)
|
||||
{
|
||||
switch (uiData)
|
||||
{
|
||||
case DataTypes.Kilrek:
|
||||
return m_uiKilrekGUID;
|
||||
case DataTypes.Terestian:
|
||||
return m_uiTerestianGUID;
|
||||
case DataTypes.Moroes:
|
||||
return m_uiMoroesGUID;
|
||||
case DataTypes.GoStagedoorleft:
|
||||
return m_uiStageDoorLeftGUID;
|
||||
case DataTypes.GoStagedoorright:
|
||||
return m_uiStageDoorRightGUID;
|
||||
case DataTypes.GoCurtains:
|
||||
return m_uiCurtainGUID;
|
||||
case DataTypes.GoLibraryDoor:
|
||||
return m_uiLibraryDoor;
|
||||
case DataTypes.GoMassiveDoor:
|
||||
return m_uiMassiveDoor;
|
||||
case DataTypes.GoSideEntranceDoor:
|
||||
return m_uiSideEntranceDoor;
|
||||
case DataTypes.GoGameDoor:
|
||||
return m_uiGamesmansDoor;
|
||||
case DataTypes.GoGameExitDoor:
|
||||
return m_uiGamesmansExitDoor;
|
||||
case DataTypes.GoNetherDoor:
|
||||
return m_uiNetherspaceDoor;
|
||||
case DataTypes.MastersTerraceDoor1:
|
||||
return MastersTerraceDoor[0];
|
||||
case DataTypes.MastersTerraceDoor2:
|
||||
return MastersTerraceDoor[1];
|
||||
case DataTypes.ImageOfMedivh:
|
||||
return ImageGUID;
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
public override void Load(string str)
|
||||
{
|
||||
if (string.IsNullOrEmpty(str))
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL();
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(str);
|
||||
StringArguments loadStream = new StringArguments(str);
|
||||
|
||||
for (byte i = 0; i < karazhanConst.MaxEncounter; ++i)
|
||||
{
|
||||
var state = (EncounterState)loadStream.NextUInt32();
|
||||
// Do not load an encounter as "In Progress" - reset it instead.
|
||||
m_auiEncounter[i] = (uint)(state == EncounterState.InProgress ? EncounterState.NotStarted : state);
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE();
|
||||
}
|
||||
|
||||
uint[] m_auiEncounter = new uint[karazhanConst.MaxEncounter];
|
||||
string strSaveData;
|
||||
|
||||
uint m_uiOperaEvent;
|
||||
uint m_uiOzDeathCount;
|
||||
|
||||
ObjectGuid m_uiCurtainGUID;
|
||||
ObjectGuid m_uiStageDoorLeftGUID;
|
||||
ObjectGuid m_uiStageDoorRightGUID;
|
||||
ObjectGuid m_uiKilrekGUID;
|
||||
ObjectGuid m_uiTerestianGUID;
|
||||
ObjectGuid m_uiMoroesGUID;
|
||||
ObjectGuid m_uiLibraryDoor; // Door at Shade of Aran
|
||||
ObjectGuid m_uiMassiveDoor; // Door at Netherspite
|
||||
ObjectGuid m_uiSideEntranceDoor; // Side Entrance
|
||||
ObjectGuid m_uiGamesmansDoor; // Door before Chess
|
||||
ObjectGuid m_uiGamesmansExitDoor; // Door after Chess
|
||||
ObjectGuid m_uiNetherspaceDoor; // Door at Malchezaar
|
||||
ObjectGuid[] MastersTerraceDoor = new ObjectGuid[2];
|
||||
ObjectGuid ImageGUID;
|
||||
ObjectGuid DustCoveredChest;
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_karazhan_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
public static T GetKarazhanAI<T>(Creature creature) where T : CreatureAI
|
||||
{
|
||||
return GetInstanceAI<T>(creature, "instance_karazhan");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,732 @@
|
||||
/*
|
||||
* 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 System.Collections.Generic;
|
||||
|
||||
namespace Scripts.EasternKingdoms.Karazhan.Moroes
|
||||
{
|
||||
struct Misc
|
||||
{
|
||||
public static Position[] Locations =
|
||||
{
|
||||
new Position(-10991.0f, -1884.33f, 81.73f, 0.614315f),
|
||||
new Position(-10989.4f, -1885.88f, 81.73f, 0.904913f),
|
||||
new Position(-10978.1f, -1887.07f, 81.73f, 2.035550f),
|
||||
new Position(-10975.9f, -1885.81f, 81.73f, 2.253890f),
|
||||
};
|
||||
|
||||
public static uint[] Adds =
|
||||
{
|
||||
17007,
|
||||
19872,
|
||||
19873,
|
||||
19874,
|
||||
19875,
|
||||
19876,
|
||||
};
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint Aggro = 0;
|
||||
public const uint Special = 1;
|
||||
public const uint Kill = 2;
|
||||
public const uint Death = 3;
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Vanish = 29448;
|
||||
public const uint Garrote = 37066;
|
||||
public const uint Blind = 34694;
|
||||
public const uint Gouge = 29425;
|
||||
public const uint Frenzy = 37023;
|
||||
|
||||
// Adds
|
||||
public const uint Manaburn = 29405;
|
||||
public const uint Mindfly = 29570;
|
||||
public const uint Swpain = 34441;
|
||||
public const uint Shadowform = 29406;
|
||||
|
||||
public const uint Hammerofjustice = 13005;
|
||||
public const uint Judgementofcommand = 29386;
|
||||
public const uint Sealofcommand = 29385;
|
||||
|
||||
public const uint Dispelmagic = 15090;
|
||||
public const uint Greaterheal = 29564;
|
||||
public const uint Holyfire = 29563;
|
||||
public const uint Pwshield = 29408;
|
||||
|
||||
public const uint Cleanse = 29380;
|
||||
public const uint Greaterblessofmight = 29381;
|
||||
public const uint Holylight = 29562;
|
||||
public const uint Divineshield = 41367;
|
||||
|
||||
public const uint Hamstring = 9080;
|
||||
public const uint Mortalstrike = 29572;
|
||||
public const uint Whirlwind = 29573;
|
||||
|
||||
public const uint Disarm = 8379;
|
||||
public const uint Heroicstrike = 29567;
|
||||
public const uint Shieldbash = 11972;
|
||||
public const uint Shieldwall = 29390;
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class boss_moroes : ScriptedAI
|
||||
{
|
||||
public boss_moroes(Creature creature) : base(creature)
|
||||
{
|
||||
instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Vanish_Timer = 30000;
|
||||
Blind_Timer = 35000;
|
||||
Gouge_Timer = 23000;
|
||||
Wait_Timer = 0;
|
||||
CheckAdds_Timer = 5000;
|
||||
|
||||
Enrage = false;
|
||||
InVanish = false;
|
||||
if (me.IsAlive())
|
||||
SpawnAdds();
|
||||
|
||||
instance.SetData(karazhanConst.BossMoroes, (uint)EncounterState.NotStarted);
|
||||
}
|
||||
|
||||
void StartEvent()
|
||||
{
|
||||
instance.SetData(karazhanConst.BossMoroes, (uint)EncounterState.InProgress);
|
||||
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
StartEvent();
|
||||
|
||||
Talk(TextIds.Aggro);
|
||||
AddsAttack();
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
Talk(TextIds.Kill);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(TextIds.Death);
|
||||
|
||||
instance.SetData(karazhanConst.BossMoroes, (uint)EncounterState.Done);
|
||||
|
||||
DeSpawnAdds();
|
||||
|
||||
//remove aura from spell Garrote when Moroes dies
|
||||
instance.DoRemoveAurasDueToSpellOnPlayers(SpellIds.Garrote);
|
||||
}
|
||||
|
||||
void SpawnAdds()
|
||||
{
|
||||
DeSpawnAdds();
|
||||
|
||||
if (isAddlistEmpty())
|
||||
{
|
||||
List<uint> AddList = new List<uint>();
|
||||
|
||||
for (byte i = 0; i < 6; ++i)
|
||||
AddList.Add(Misc.Adds[i]);
|
||||
|
||||
AddList.RandomResize(4);
|
||||
|
||||
byte c = 0;
|
||||
for (var i = 0; i != AddList.Count && c < 4; ++i, ++c)
|
||||
{
|
||||
uint entry = AddList[i];
|
||||
Creature creature = me.SummonCreature(entry, Misc.Locations[c], TempSummonType.CorpseTimedDespawn, 10000);
|
||||
if (creature)
|
||||
{
|
||||
AddGUID[c] = creature.GetGUID();
|
||||
AddId[c] = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
{
|
||||
Creature creature = me.SummonCreature(AddId[i], Misc.Locations[i], TempSummonType.CorpseTimedDespawn, 10000);
|
||||
if (creature)
|
||||
AddGUID[i] = creature.GetGUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isAddlistEmpty()
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
if (AddId[i] == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeSpawnAdds()
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
{
|
||||
if (!AddGUID[i].IsEmpty())
|
||||
{
|
||||
Creature temp = ObjectAccessor.GetCreature(me, AddGUID[i]);
|
||||
if (temp)
|
||||
temp.DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddsAttack()
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
{
|
||||
if (!AddGUID[i].IsEmpty())
|
||||
{
|
||||
Creature temp = ObjectAccessor.GetCreature((me), AddGUID[i]);
|
||||
if (temp && temp.IsAlive())
|
||||
{
|
||||
temp.GetAI().AttackStart(me.GetVictim());
|
||||
DoZoneInCombat(temp);
|
||||
}
|
||||
else
|
||||
EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (instance.GetData(karazhanConst.BossMoroes) == 0)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Enrage && HealthBelowPct(30))
|
||||
{
|
||||
DoCast(me, SpellIds.Frenzy);
|
||||
Enrage = true;
|
||||
}
|
||||
|
||||
if (CheckAdds_Timer <= diff)
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
{
|
||||
if (!AddGUID[i].IsEmpty())
|
||||
{
|
||||
Creature temp = ObjectAccessor.GetCreature((me), AddGUID[i]);
|
||||
if (temp && temp.IsAlive())
|
||||
if (!temp.GetVictim())
|
||||
temp.GetAI().AttackStart(me.GetVictim());
|
||||
}
|
||||
}
|
||||
CheckAdds_Timer = 5000;
|
||||
}
|
||||
else CheckAdds_Timer -= diff;
|
||||
|
||||
if (!Enrage)
|
||||
{
|
||||
//Cast Vanish, then Garrote random victim
|
||||
if (Vanish_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SpellIds.Vanish);
|
||||
InVanish = true;
|
||||
Vanish_Timer = 30000;
|
||||
Wait_Timer = 5000;
|
||||
}
|
||||
else Vanish_Timer -= diff;
|
||||
|
||||
if (Gouge_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Gouge);
|
||||
Gouge_Timer = 40000;
|
||||
}
|
||||
else Gouge_Timer -= diff;
|
||||
|
||||
if (Blind_Timer <= diff)
|
||||
{
|
||||
List<Unit> targets = SelectTargetList(5, SelectAggroTarget.Random, me.GetCombatReach() * 5, true);
|
||||
foreach (var i in targets)
|
||||
{
|
||||
|
||||
if (!me.IsWithinMeleeRange(i))
|
||||
{
|
||||
DoCast(i, SpellIds.Blind);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Blind_Timer = 40000;
|
||||
}
|
||||
else
|
||||
Blind_Timer -= diff;
|
||||
}
|
||||
|
||||
if (InVanish)
|
||||
{
|
||||
if (Wait_Timer <= diff)
|
||||
{
|
||||
Talk(TextIds.Special);
|
||||
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
|
||||
if (target)
|
||||
target.CastSpell(target, SpellIds.Garrote, true);
|
||||
|
||||
InVanish = false;
|
||||
}
|
||||
else
|
||||
Wait_Timer -= diff;
|
||||
}
|
||||
|
||||
if (!InVanish)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
public ObjectGuid[] AddGUID = new ObjectGuid[4];
|
||||
|
||||
uint Vanish_Timer;
|
||||
uint Blind_Timer;
|
||||
uint Gouge_Timer;
|
||||
uint Wait_Timer;
|
||||
uint CheckAdds_Timer;
|
||||
uint[] AddId = new uint[4];
|
||||
|
||||
bool InVanish;
|
||||
bool Enrage;
|
||||
}
|
||||
|
||||
class boss_moroes_guestAI : ScriptedAI
|
||||
{
|
||||
public boss_moroes_guestAI(Creature creature) : base(creature)
|
||||
{
|
||||
instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
instance.SetData(karazhanConst.BossMoroes, (uint)EncounterState.NotStarted);
|
||||
}
|
||||
|
||||
public void AcquireGUID()
|
||||
{
|
||||
Creature Moroes = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Moroes));
|
||||
if (Moroes)
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
{
|
||||
ObjectGuid GUID = ((boss_moroes)Moroes.GetAI()).AddGUID[i];
|
||||
if (!GUID.IsEmpty())
|
||||
GuestGUID[i] = GUID;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Unit SelectGuestTarget()
|
||||
{
|
||||
ObjectGuid TempGUID = GuestGUID[RandomHelper.Rand32() % 4];
|
||||
if (!TempGUID.IsEmpty())
|
||||
{
|
||||
Unit unit = Global.ObjAccessor.GetUnit(me, TempGUID);
|
||||
if (unit && unit.IsAlive())
|
||||
return unit;
|
||||
}
|
||||
|
||||
return me;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (instance.GetData(karazhanConst.BossMoroes) == 0)
|
||||
EnterEvadeMode();
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
ObjectGuid[] GuestGUID = new ObjectGuid[4];
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_baroness_dorothea_millstipe : boss_moroes_guestAI
|
||||
{
|
||||
//Shadow Priest
|
||||
public boss_baroness_dorothea_millstipe(Creature creature) : base(creature) { }
|
||||
|
||||
uint ManaBurn_Timer;
|
||||
uint MindFlay_Timer;
|
||||
uint ShadowWordPain_Timer;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
ManaBurn_Timer = 7000;
|
||||
MindFlay_Timer = 1000;
|
||||
ShadowWordPain_Timer = 6000;
|
||||
|
||||
DoCast(me, SpellIds.Shadowform, true);
|
||||
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (MindFlay_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Mindfly);
|
||||
MindFlay_Timer = 12000; // 3 sec channeled
|
||||
}
|
||||
else MindFlay_Timer -= diff;
|
||||
|
||||
if (ManaBurn_Timer <= diff)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
|
||||
if (target)
|
||||
if (target.getPowerType() == PowerType.Mana)
|
||||
DoCast(target, SpellIds.Manaburn);
|
||||
ManaBurn_Timer = 5000; // 3 sec cast
|
||||
}
|
||||
else ManaBurn_Timer -= diff;
|
||||
|
||||
if (ShadowWordPain_Timer <= diff)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, SpellIds.Swpain);
|
||||
ShadowWordPain_Timer = 7000;
|
||||
}
|
||||
}
|
||||
else ShadowWordPain_Timer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_baron_rafe_dreuger : boss_moroes_guestAI
|
||||
{
|
||||
//Retr Pally
|
||||
public boss_baron_rafe_dreuger(Creature creature) : base(creature) { }
|
||||
|
||||
uint HammerOfJustice_Timer;
|
||||
uint SealOfCommand_Timer;
|
||||
uint JudgementOfCommand_Timer;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
HammerOfJustice_Timer = 1000;
|
||||
SealOfCommand_Timer = 7000;
|
||||
JudgementOfCommand_Timer = SealOfCommand_Timer + 29000;
|
||||
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (SealOfCommand_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SpellIds.Sealofcommand);
|
||||
SealOfCommand_Timer = 32000;
|
||||
JudgementOfCommand_Timer = 29000;
|
||||
}
|
||||
else SealOfCommand_Timer -= diff;
|
||||
|
||||
if (JudgementOfCommand_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Judgementofcommand);
|
||||
JudgementOfCommand_Timer = SealOfCommand_Timer + 29000;
|
||||
}
|
||||
else JudgementOfCommand_Timer -= diff;
|
||||
|
||||
if (HammerOfJustice_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Hammerofjustice);
|
||||
HammerOfJustice_Timer = 12000;
|
||||
}
|
||||
else HammerOfJustice_Timer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_lady_catriona_von_indi : boss_moroes_guestAI
|
||||
{
|
||||
//Holy Priest
|
||||
public boss_lady_catriona_von_indi(Creature creature) : base(creature) { }
|
||||
|
||||
uint DispelMagic_Timer;
|
||||
uint GreaterHeal_Timer;
|
||||
uint HolyFire_Timer;
|
||||
uint PowerWordShield_Timer;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
DispelMagic_Timer = 11000;
|
||||
GreaterHeal_Timer = 1500;
|
||||
HolyFire_Timer = 5000;
|
||||
PowerWordShield_Timer = 1000;
|
||||
|
||||
AcquireGUID();
|
||||
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (PowerWordShield_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SpellIds.Pwshield);
|
||||
PowerWordShield_Timer = 15000;
|
||||
}
|
||||
else PowerWordShield_Timer -= diff;
|
||||
|
||||
if (GreaterHeal_Timer <= diff)
|
||||
{
|
||||
Unit target = SelectGuestTarget();
|
||||
|
||||
DoCast(target, SpellIds.Greaterheal);
|
||||
GreaterHeal_Timer = 17000;
|
||||
}
|
||||
else GreaterHeal_Timer -= diff;
|
||||
|
||||
if (HolyFire_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Holyfire);
|
||||
HolyFire_Timer = 22000;
|
||||
}
|
||||
else HolyFire_Timer -= diff;
|
||||
|
||||
if (DispelMagic_Timer <= diff)
|
||||
{
|
||||
Unit target = RandomHelper.RAND(SelectGuestTarget(), SelectTarget(SelectAggroTarget.Random, 0, 100, true));
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Dispelmagic);
|
||||
|
||||
DispelMagic_Timer = 25000;
|
||||
}
|
||||
else DispelMagic_Timer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_lady_keira_berrybuck : boss_moroes_guestAI
|
||||
{
|
||||
//Holy Pally
|
||||
public boss_lady_keira_berrybuck(Creature creature) : base(creature) { }
|
||||
|
||||
uint Cleanse_Timer;
|
||||
uint GreaterBless_Timer;
|
||||
uint HolyLight_Timer;
|
||||
uint DivineShield_Timer;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Cleanse_Timer = 13000;
|
||||
GreaterBless_Timer = 1000;
|
||||
HolyLight_Timer = 7000;
|
||||
DivineShield_Timer = 31000;
|
||||
|
||||
AcquireGUID();
|
||||
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (DivineShield_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SpellIds.Divineshield);
|
||||
DivineShield_Timer = 31000;
|
||||
}
|
||||
else DivineShield_Timer -= diff;
|
||||
|
||||
if (HolyLight_Timer <= diff)
|
||||
{
|
||||
Unit target = SelectGuestTarget();
|
||||
|
||||
DoCast(target, SpellIds.Holylight);
|
||||
HolyLight_Timer = 10000;
|
||||
}
|
||||
else HolyLight_Timer -= diff;
|
||||
|
||||
if (GreaterBless_Timer <= diff)
|
||||
{
|
||||
Unit target = SelectGuestTarget();
|
||||
|
||||
DoCast(target, SpellIds.Greaterblessofmight);
|
||||
|
||||
GreaterBless_Timer = 50000;
|
||||
}
|
||||
else GreaterBless_Timer -= diff;
|
||||
|
||||
if (Cleanse_Timer <= diff)
|
||||
{
|
||||
Unit target = SelectGuestTarget();
|
||||
|
||||
DoCast(target, SpellIds.Cleanse);
|
||||
|
||||
Cleanse_Timer = 10000;
|
||||
}
|
||||
else Cleanse_Timer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_lord_robin_daris : boss_moroes_guestAI
|
||||
{
|
||||
//Arms Warr
|
||||
public boss_lord_robin_daris(Creature creature) : base(creature) { }
|
||||
|
||||
uint Hamstring_Timer;
|
||||
uint MortalStrike_Timer;
|
||||
uint WhirlWind_Timer;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Hamstring_Timer = 7000;
|
||||
MortalStrike_Timer = 10000;
|
||||
WhirlWind_Timer = 21000;
|
||||
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (Hamstring_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Hamstring);
|
||||
Hamstring_Timer = 12000;
|
||||
}
|
||||
else Hamstring_Timer -= diff;
|
||||
|
||||
if (MortalStrike_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Mortalstrike);
|
||||
MortalStrike_Timer = 18000;
|
||||
}
|
||||
else MortalStrike_Timer -= diff;
|
||||
|
||||
if (WhirlWind_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SpellIds.Whirlwind);
|
||||
WhirlWind_Timer = 21000;
|
||||
}
|
||||
else WhirlWind_Timer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_lord_crispin_ference : boss_moroes_guestAI
|
||||
{
|
||||
//Arms Warr
|
||||
public boss_lord_crispin_ference(Creature creature) : base(creature) { }
|
||||
|
||||
uint Disarm_Timer;
|
||||
uint HeroicStrike_Timer;
|
||||
uint ShieldBash_Timer;
|
||||
uint ShieldWall_Timer;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Disarm_Timer = 6000;
|
||||
HeroicStrike_Timer = 10000;
|
||||
ShieldBash_Timer = 8000;
|
||||
ShieldWall_Timer = 4000;
|
||||
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (Disarm_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Disarm);
|
||||
Disarm_Timer = 12000;
|
||||
}
|
||||
else Disarm_Timer -= diff;
|
||||
|
||||
if (HeroicStrike_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Heroicstrike);
|
||||
HeroicStrike_Timer = 10000;
|
||||
}
|
||||
else HeroicStrike_Timer -= diff;
|
||||
|
||||
if (ShieldBash_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.Shieldbash);
|
||||
ShieldBash_Timer = 13000;
|
||||
}
|
||||
else ShieldBash_Timer -= diff;
|
||||
|
||||
if (ShieldWall_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SpellIds.Shieldwall);
|
||||
ShieldWall_Timer = 21000;
|
||||
}
|
||||
else ShieldWall_Timer -= diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* 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;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
|
||||
namespace Scripts.EasternKingdoms
|
||||
{
|
||||
enum UnworthyInitiatePhase
|
||||
{
|
||||
Chained,
|
||||
ToEquip,
|
||||
Equiping,
|
||||
ToAttack,
|
||||
Attacking
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class npc_unworthy_initiate : ScriptedAI
|
||||
{
|
||||
public npc_unworthy_initiate(Creature creature) : base(creature)
|
||||
{
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
if (me.GetCurrentEquipmentId() == 0)
|
||||
me.SetCurrentEquipmentId((byte)me.GetOriginalEquipmentId());
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
anchorGUID.Clear();
|
||||
phase = UnworthyInitiatePhase.Chained;
|
||||
_events.Reset();
|
||||
me.SetFaction(7);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
|
||||
me.SetStandState(UnitStandStateType.Kneel);
|
||||
me.LoadEquipment(0, true);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_events.ScheduleEvent(EventIcyTouch, 1000, 1);
|
||||
_events.ScheduleEvent(EventPlagueStrike, 3000, 1);
|
||||
_events.ScheduleEvent(EventBloodStrike, 2000, 1);
|
||||
_events.ScheduleEvent(EventDeathCoil, 5000, 1);
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Point)
|
||||
return;
|
||||
|
||||
if (id == 1)
|
||||
{
|
||||
wait_timer = 5000;
|
||||
me.CastSpell(me, SpellDKInitateVisual, true);
|
||||
|
||||
Player starter = Global.ObjAccessor.GetPlayer(me, playerGUID);
|
||||
if (starter)
|
||||
Global.CreatureTextMgr.SendChat(me, (byte)SayEventAttack, null, ChatMsg.Addon, Language.Addon, CreatureTextRange.Normal, 0, Team.Other, false, starter);
|
||||
|
||||
phase = UnworthyInitiatePhase.ToAttack;
|
||||
}
|
||||
}
|
||||
|
||||
public void EventStart(Creature anchor, Player target)
|
||||
{
|
||||
wait_timer = 5000;
|
||||
phase = UnworthyInitiatePhase.ToEquip;
|
||||
|
||||
me.SetStandState(UnitStandStateType.Stand);
|
||||
me.RemoveAurasDueToSpell(SpellSoulPrisonChainSelf);
|
||||
me.RemoveAurasDueToSpell(SpellSoulPrisonChain);
|
||||
|
||||
float z;
|
||||
anchor.GetContactPoint(me, out anchorX, out anchorY, out z, 1.0f);
|
||||
|
||||
playerGUID = target.GetGUID();
|
||||
Talk(SayEventStart);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case UnworthyInitiatePhase.Chained:
|
||||
if (anchorGUID.IsEmpty())
|
||||
{
|
||||
Creature anchor = me.FindNearestCreature(29521, 30);
|
||||
if (anchor)
|
||||
{
|
||||
anchor.GetAI().SetGUID(me.GetGUID());
|
||||
anchor.CastSpell(me, SpellSoulPrisonChain, true);
|
||||
anchorGUID = anchor.GetGUID();
|
||||
}
|
||||
else
|
||||
Log.outError(LogFilter.Scripts, "npc_unworthy_initiateAI: unable to find anchor!");
|
||||
|
||||
float dist = 99.0f;
|
||||
GameObject prison = null;
|
||||
|
||||
for (byte i = 0; i < 12; ++i)
|
||||
{
|
||||
GameObject temp_prison = me.FindNearestGameObject(acherus_soul_prison[i], 30);
|
||||
if (temp_prison)
|
||||
{
|
||||
if (me.IsWithinDist(temp_prison, dist, false))
|
||||
{
|
||||
dist = me.GetDistance2d(temp_prison);
|
||||
prison = temp_prison;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prison)
|
||||
prison.ResetDoorOrButton();
|
||||
else
|
||||
Log.outError(LogFilter.Scripts, "npc_unworthy_initiateAI: unable to find prison!");
|
||||
}
|
||||
break;
|
||||
case UnworthyInitiatePhase.ToEquip:
|
||||
if (wait_timer != 0)
|
||||
{
|
||||
if (wait_timer > diff)
|
||||
wait_timer -= diff;
|
||||
else
|
||||
{
|
||||
me.GetMotionMaster().MovePoint(1, anchorX, anchorY, me.GetPositionZ());
|
||||
phase = UnworthyInitiatePhase.Equiping;
|
||||
wait_timer = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UnworthyInitiatePhase.ToAttack:
|
||||
if (wait_timer != 0)
|
||||
{
|
||||
if (wait_timer > diff)
|
||||
wait_timer -= diff;
|
||||
else
|
||||
{
|
||||
me.SetFaction(14);
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
|
||||
phase = UnworthyInitiatePhase.Attacking;
|
||||
|
||||
Player target = Global.ObjAccessor.GetPlayer(me, playerGUID);
|
||||
if (target)
|
||||
AttackStart(target);
|
||||
wait_timer = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UnworthyInitiatePhase.Attacking:
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EventIcyTouch:
|
||||
DoCastVictim(SpellIcyTouch);
|
||||
_events.DelayEvents(1000, 1);
|
||||
_events.ScheduleEvent(EventIcyTouch, 5000, 1);
|
||||
break;
|
||||
case EventPlagueStrike:
|
||||
DoCastVictim(SpellPlagueStrike);
|
||||
_events.DelayEvents(1000, 1);
|
||||
_events.ScheduleEvent(EventPlagueStrike, 5000, 1);
|
||||
break;
|
||||
case EventBloodStrike:
|
||||
DoCastVictim(SpellBloodStrike);
|
||||
_events.DelayEvents(1000, 1);
|
||||
_events.ScheduleEvent(EventBloodStrike, 5000, 1);
|
||||
break;
|
||||
case EventDeathCoil:
|
||||
DoCastVictim(SpellDeathCoil);
|
||||
_events.DelayEvents(1000, 1);
|
||||
_events.ScheduleEvent(EventDeathCoil, 5000, 1);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid playerGUID;
|
||||
UnworthyInitiatePhase phase;
|
||||
uint wait_timer;
|
||||
float anchorX, anchorY;
|
||||
ObjectGuid anchorGUID;
|
||||
|
||||
const uint SpellSoulPrisonChainSelf = 54612;
|
||||
const uint SpellSoulPrisonChain = 54613;
|
||||
const uint SpellDKInitateVisual = 51519;
|
||||
|
||||
const uint SpellIcyTouch = 52372;
|
||||
const uint SpellPlagueStrike = 52373;
|
||||
const uint SpellBloodStrike = 52374;
|
||||
const uint SpellDeathCoil = 52375;
|
||||
|
||||
const uint SayEventStart = 0;
|
||||
const uint SayEventAttack = 1;
|
||||
|
||||
const uint EventIcyTouch = 1;
|
||||
const uint EventPlagueStrike = 2;
|
||||
const uint EventBloodStrike = 3;
|
||||
const uint EventDeathCoil = 4;
|
||||
|
||||
static uint[] acherus_soul_prison = { 191577, 191580, 191581, 191582, 191583, 191584, 191585, 191586, 191587, 191588, 191589, 191590 };
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_unworthy_initiate_anchor : PassiveAI
|
||||
{
|
||||
public npc_unworthy_initiate_anchor(Creature creature) : base(creature) { }
|
||||
|
||||
public override void SetGUID(ObjectGuid guid, int id)
|
||||
{
|
||||
if (prisonerGUID.IsEmpty())
|
||||
prisonerGUID = guid;
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGUID(int id)
|
||||
{
|
||||
return prisonerGUID;
|
||||
}
|
||||
|
||||
ObjectGuid prisonerGUID;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class go_acherus_soul_prison : GameObjectScript
|
||||
{
|
||||
public go_acherus_soul_prison() : base("go_acherus_soul_prison") { }
|
||||
|
||||
public override bool OnGossipHello(Player player, GameObject go)
|
||||
{
|
||||
Creature anchor = go.FindNearestCreature(29521, 15);
|
||||
if (anchor)
|
||||
{
|
||||
ObjectGuid prisonerGUID = anchor.GetAI().GetGUID();
|
||||
if (!prisonerGUID.IsEmpty())
|
||||
{
|
||||
Creature prisoner = ObjectAccessor.GetCreature(player, prisonerGUID);
|
||||
if (prisoner)
|
||||
((npc_unworthy_initiate)prisoner.GetAI()).EventStart(anchor, player);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct EyeOfAcherus
|
||||
{
|
||||
public const uint EyeHugeDisplayId = 26320;
|
||||
public const uint EyeSmallDisplayId = 25499;
|
||||
|
||||
public const uint SpellEyePhasemask = 70889;
|
||||
public const uint SpellEyeVisual = 51892;
|
||||
public const uint SpellEyeFlight = 51923;
|
||||
public const uint SpellEyeFlightBoost = 51890;
|
||||
public const uint SpellEyeControl = 51852;
|
||||
|
||||
public const string SayEyeLaunched = "Eye of Acherus is launched towards its destination.";
|
||||
public const string SayEyeUnderControl = "You are now in control of the eye.";
|
||||
|
||||
public static float[] EyeDestination = { 1750.8276f, -5873.788f, 147.2266f };
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_eye_of_acherus : ScriptedAI
|
||||
{
|
||||
public npc_eye_of_acherus(Creature creature) : base(creature)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
uint startTimer;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
startTimer = 2000;
|
||||
}
|
||||
|
||||
public override void AttackStart(Unit u) { }
|
||||
|
||||
public override void MoveInLineOfSight(Unit u) { }
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Unit charmer = me.GetCharmer();
|
||||
if (charmer)
|
||||
charmer.RemoveAurasDueToSpell(EyeOfAcherus.SpellEyeControl);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (me.IsCharmed())
|
||||
{
|
||||
if (startTimer <= diff) // fly to start point
|
||||
{
|
||||
me.CastSpell(me, EyeOfAcherus.SpellEyePhasemask, true);
|
||||
me.CastSpell(me, EyeOfAcherus.SpellEyeVisual, true);
|
||||
me.CastSpell(me, EyeOfAcherus.SpellEyeFlightBoost, true);
|
||||
me.SetSpeedRate(UnitMoveType.Flight, 4f);
|
||||
|
||||
me.GetMotionMaster().MovePoint(0, EyeOfAcherus.EyeDestination[0], EyeOfAcherus.EyeDestination[1], EyeOfAcherus.EyeDestination[2]);
|
||||
return;
|
||||
}
|
||||
else
|
||||
startTimer -= diff;
|
||||
}
|
||||
else
|
||||
me.ForcedDespawn();
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Point || id != 0)
|
||||
return;
|
||||
|
||||
me.SetDisplayId(EyeOfAcherus.EyeSmallDisplayId);
|
||||
|
||||
me.CastSpell(me, EyeOfAcherus.SpellEyeFlight, true);
|
||||
me.Say(EyeOfAcherus.SayEyeUnderControl, Language.Universal);
|
||||
|
||||
if (me.GetCharmer() && me.GetCharmer().IsTypeId(TypeId.Player))
|
||||
me.GetCharmer().ToPlayer().SetClientControl(me, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using Game.Entities;
|
||||
using Game.AI;
|
||||
using Game.Scripting;
|
||||
using Framework.Constants;
|
||||
|
||||
namespace Scripts.EasternKingdoms.TheStockade
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayPull = 0; // Forest Just Setback!
|
||||
public const uint SayEnrage = 1; // Areatriggermessage: Hogger Enrages!
|
||||
public const uint SayDeath = 2; // Yiipe!
|
||||
|
||||
public const uint SayWarden1 = 0; // Yell - This Ends Here; Hogger!
|
||||
public const uint SayWarden2 = 1; // Say - He'S...He'S Dead?
|
||||
public const uint SayWarden3 = 2; // Say - It'S Simply Too Good To Be True. You Couldn'T Have Killed Him So Easily!
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint ViciousSlice = 86604;
|
||||
public const uint MaddeningCall = 86620;
|
||||
public const uint Enrage = 86736;
|
||||
}
|
||||
|
||||
struct Events
|
||||
{
|
||||
public const uint SayWarden1 = 1;
|
||||
public const uint SayWarden2 = 2;
|
||||
public const uint SayWarden3 = 3;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_hogger : BossAI
|
||||
{
|
||||
public boss_hogger(Creature creature) : base(creature, DataTypes.Hogger) { }
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(TextIds.SayPull);
|
||||
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(4), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.ViciousSlice);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(14));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), task =>
|
||||
{
|
||||
DoCast(SpellIds.MaddeningCall);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20));
|
||||
});
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(TextIds.SayDeath);
|
||||
_JustDied();
|
||||
me.SummonCreature(CreatureIds.WardenThelwater, Misc.WardenThelwaterPos);
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
base.JustSummoned(summon);
|
||||
if (summon.GetEntry() == CreatureIds.WardenThelwater)
|
||||
summon.GetMotionMaster().MovePoint(0, Misc.WardenThelwaterMovePos);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (me.HealthBelowPctDamaged(30, damage) && !_hasEnraged)
|
||||
{
|
||||
_hasEnraged = true;
|
||||
Talk(TextIds.SayEnrage);
|
||||
DoCastSelf(SpellIds.Enrage);
|
||||
}
|
||||
}
|
||||
|
||||
bool _hasEnraged;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_warden_thelwater : ScriptedAI
|
||||
{
|
||||
public npc_warden_thelwater(Creature creature) : base(creature) { }
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type == MovementGeneratorType.Point && id == 0)
|
||||
_events.ScheduleEvent(Events.SayWarden1, TimeSpan.FromSeconds(1));
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Events.SayWarden1:
|
||||
Talk(TextIds.SayWarden1);
|
||||
_events.ScheduleEvent(Events.SayWarden2, TimeSpan.FromSeconds(4));
|
||||
break;
|
||||
case Events.SayWarden2:
|
||||
Talk(TextIds.SayWarden2);
|
||||
_events.ScheduleEvent(Events.SayWarden3, TimeSpan.FromSeconds(3));
|
||||
break;
|
||||
case Events.SayWarden3:
|
||||
Talk(TextIds.SayWarden3);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using Game.Entities;
|
||||
|
||||
namespace Scripts.EasternKingdoms.TheStockade
|
||||
{
|
||||
struct Misc
|
||||
{
|
||||
public static Position WardenThelwaterMovePos = new Position(152.019f, 106.198f, -35.1896f, 1.082104f);
|
||||
public static Position WardenThelwaterPos = new Position(138.369f, 78.2932f, -33.85627f, 1.082104f);
|
||||
}
|
||||
|
||||
struct DataTypes
|
||||
{
|
||||
public const uint RandolphMoloch = 0;
|
||||
public const uint LordOverheat = 1;
|
||||
public const uint Hogger = 2;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint RandolphMoloch = 46383;
|
||||
public const uint LordOverheat = 46264;
|
||||
public const uint Hogger = 46254;
|
||||
public const uint WardenThelwater = 46409;
|
||||
public const uint MortimerMoloch = 46482;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Script]
|
||||
class instance_the_stockade : InstanceMapScript
|
||||
{
|
||||
public instance_the_stockade() : base("instance_the_stockade", 34) { }
|
||||
|
||||
class instance_the_stockade_InstanceMapScript : InstanceScript
|
||||
{
|
||||
public instance_the_stockade_InstanceMapScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("SS");
|
||||
SetBossNumber(3);
|
||||
}
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_the_stockade_InstanceMapScript(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
|
||||
namespace Scripts.Events
|
||||
{
|
||||
struct HallowsEnd
|
||||
{
|
||||
public const uint ItemWaterBucket = 32971;
|
||||
public const uint SpellHasWaterBucket = 42336;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_hallows_end_has_water_bucket : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(HallowsEnd.SpellHasWaterBucket);
|
||||
}
|
||||
|
||||
void HandleEffectApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
if (caster.IsPlayer())
|
||||
if (!caster.ToPlayer().HasItemCount(HallowsEnd.ItemWaterBucket, 1, false))
|
||||
caster.RemoveAurasDueToSpell(HallowsEnd.SpellHasWaterBucket);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(HandleEffectApply, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 Game.Maps;
|
||||
using Game.Scripting;
|
||||
|
||||
namespace Scripts.Kalimdor
|
||||
{
|
||||
[Script]
|
||||
public class instance_ragefire_chasm : InstanceMapScript
|
||||
{
|
||||
public instance_ragefire_chasm() : base("instance_ragefire_chasm", 389) { }
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new RagefireChasmInstanceMapScript(map);
|
||||
}
|
||||
|
||||
class RagefireChasmInstanceMapScript : InstanceScript
|
||||
{
|
||||
public RagefireChasmInstanceMapScript(Map map) : base(map) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* 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;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.Kalimdor.ZoneAshenvale
|
||||
{
|
||||
struct CreatureIds
|
||||
{
|
||||
//RuulSnowhoof
|
||||
public const uint ThistlefurUrsa = 3921;
|
||||
public const uint ThistlefurTotemic = 3922;
|
||||
public const uint ThistlefurPathfinder = 3926;
|
||||
|
||||
//Muglash
|
||||
public const uint WrathRider = 3713;
|
||||
public const uint WrathSorceress = 3717;
|
||||
public const uint WrathRazortail = 3712;
|
||||
public const uint WrathPriestess = 3944;
|
||||
public const uint WrathMyrmidon = 3711;
|
||||
public const uint WrathSeawitch = 3715;
|
||||
public const uint Vorsha = 12940;
|
||||
public const uint Muglash = 12717;
|
||||
}
|
||||
|
||||
struct GameObjectIds
|
||||
{
|
||||
//RuulSnowhoof
|
||||
public const uint Cage = 178147;
|
||||
|
||||
//Muglash
|
||||
public const uint NagaBrazier = 178247;
|
||||
|
||||
//KingoftheFoulweald
|
||||
public const uint Banner = 178205;
|
||||
}
|
||||
|
||||
struct QuestIds
|
||||
{
|
||||
//RuulSnowhoof
|
||||
public const uint FreedomToRuul = 6482;
|
||||
|
||||
//Muglash
|
||||
public const uint Vorsha = 6641;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
//Muglash
|
||||
public const uint SayMugStart1 = 0;
|
||||
public const uint SayMugStart2 = 1;
|
||||
public const uint SayMugBrazier = 2;
|
||||
public const uint SayMugBrazierWait = 3;
|
||||
public const uint SayMugOnGuard = 4;
|
||||
public const uint SayMugRest = 5;
|
||||
public const uint SayMugDone = 6;
|
||||
public const uint SayMugGratitude = 7;
|
||||
public const uint SayMugPatrol = 8;
|
||||
public const uint SayMugReturn = 9;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
//RuulSnowhoof
|
||||
public const uint FactionQuest = 113;
|
||||
public static Position[] RuulSnowhoofSummonsCoord =
|
||||
{
|
||||
new Position(3449.218018f, -587.825073f, 174.978867f, 4.714445f),
|
||||
new Position(3446.384521f, -587.830872f, 175.186279f, 4.714445f),
|
||||
new Position(3444.218994f, -587.835327f, 175.380600f, 4.714445f),
|
||||
new Position(3508.344482f, -492.024261f, 186.929031f, 4.145029f),
|
||||
new Position(3506.265625f, -490.531006f, 186.740128f, 4.239277f),
|
||||
new Position(3503.682373f, -489.393799f, 186.629684f, 4.349232f)
|
||||
};
|
||||
|
||||
//Muglash
|
||||
public static Position[] FirstNagaCoord =
|
||||
{
|
||||
new Position(3603.504150f, 1122.631104f, 1.635f, 0.0f), // rider
|
||||
new Position(3589.293945f, 1148.664063f, 5.565f, 0.0f), // sorceress
|
||||
new Position(3609.925537f, 1168.759521f, -1.168f, 0.0f) // razortail
|
||||
};
|
||||
|
||||
public static Position[] SecondNagaCoord =
|
||||
{
|
||||
new Position(3609.925537f, 1168.759521f, -1.168f, 0.0f), // witch
|
||||
new Position(3645.652100f, 1139.425415f, 1.322f, 0.0f), // priest
|
||||
new Position(3583.602051f, 1128.405762f, 2.347f, 0.0f) // myrmidon
|
||||
};
|
||||
public static Position VorshaCoord = new Position(3633.056885f, 1172.924072f, -5.388f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
[Script]
|
||||
class npc_ruul_snowhoof : npc_escortAI
|
||||
{
|
||||
public npc_ruul_snowhoof(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
GameObject cage = me.FindNearestGameObject(GameObjectIds.Cage, 20);
|
||||
if (cage)
|
||||
cage.SetGoState(GameObjectState.Ready);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
|
||||
public override void JustSummoned(Creature summoned)
|
||||
{
|
||||
summoned.GetAI().AttackStart(me);
|
||||
}
|
||||
|
||||
public override void sQuestAccept(Player player, Quest quest)
|
||||
{
|
||||
if (quest.Id == QuestIds.FreedomToRuul)
|
||||
{
|
||||
me.SetFaction(Misc.FactionQuest);
|
||||
base.Start(true, false, player.GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
public override void WaypointReached(uint waypointId)
|
||||
{
|
||||
Player player = GetPlayerForEscort();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
me.SetUInt32Value(UnitFields.Bytes1, 0);
|
||||
GameObject cage = me.FindNearestGameObject(GameObjectIds.Cage, 20);
|
||||
if (cage)
|
||||
cage.SetGoState(GameObjectState.Active);
|
||||
break;
|
||||
case 13:
|
||||
me.SummonCreature(CreatureIds.ThistlefurTotemic, Misc.RuulSnowhoofSummonsCoord[0], TempSummonType.DeadDespawn, 60000);
|
||||
me.SummonCreature(CreatureIds.ThistlefurUrsa, Misc.RuulSnowhoofSummonsCoord[1], TempSummonType.DeadDespawn, 60000);
|
||||
me.SummonCreature(CreatureIds.ThistlefurPathfinder, Misc.RuulSnowhoofSummonsCoord[2], TempSummonType.DeadDespawn, 60000);
|
||||
break;
|
||||
case 19:
|
||||
me.SummonCreature(CreatureIds.ThistlefurTotemic, Misc.RuulSnowhoofSummonsCoord[3], TempSummonType.DeadDespawn, 60000);
|
||||
me.SummonCreature(CreatureIds.ThistlefurUrsa, Misc.RuulSnowhoofSummonsCoord[4], TempSummonType.DeadDespawn, 60000);
|
||||
me.SummonCreature(CreatureIds.ThistlefurPathfinder, Misc.RuulSnowhoofSummonsCoord[5], TempSummonType.DeadDespawn, 60000);
|
||||
break;
|
||||
case 21:
|
||||
player.GroupEventHappens(QuestIds.FreedomToRuul, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
base.UpdateAI(diff);
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class npc_muglash : npc_escortAI
|
||||
{
|
||||
public npc_muglash(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
eventTimer = 10000;
|
||||
waveId = 0;
|
||||
_isBrazierExtinguished = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
Player player = GetPlayerForEscort();
|
||||
if (player)
|
||||
{
|
||||
if (HasEscortState(eEscortState.Paused))
|
||||
{
|
||||
if (Convert.ToBoolean(RandomHelper.URand(0, 1)))
|
||||
Talk(TextIds.SayMugOnGuard, player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
if (HasEscortState(eEscortState.Escorting))
|
||||
{
|
||||
Player player = GetPlayerForEscort();
|
||||
if (player)
|
||||
player.FailQuest(QuestIds.Vorsha);
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summoned)
|
||||
{
|
||||
summoned.GetAI().AttackStart(me);
|
||||
}
|
||||
|
||||
public override void sQuestAccept(Player player, Quest quest)
|
||||
{
|
||||
if (quest.Id == QuestIds.Vorsha)
|
||||
{
|
||||
Talk(TextIds.SayMugStart1);
|
||||
me.SetFaction(Misc.FactionQuest);
|
||||
base.Start(true, false, player.GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
public override void WaypointReached(uint waypointId)
|
||||
{
|
||||
Player player = GetPlayerForEscort();
|
||||
if (player)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(TextIds.SayMugStart2, player);
|
||||
break;
|
||||
case 24:
|
||||
Talk(TextIds.SayMugBrazier, player);
|
||||
|
||||
GameObject go = GetClosestGameObjectWithEntry(me, GameObjectIds.NagaBrazier, SharedConst.InteractionDistance * 2);
|
||||
if (go)
|
||||
{
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
SetEscortPaused(true);
|
||||
}
|
||||
break;
|
||||
case 25:
|
||||
Talk(TextIds.SayMugGratitude);
|
||||
player.GroupEventHappens(QuestIds.Vorsha, me);
|
||||
break;
|
||||
case 26:
|
||||
Talk(TextIds.SayMugPatrol);
|
||||
break;
|
||||
case 27:
|
||||
Talk(TextIds.SayMugReturn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoWaveSummon()
|
||||
{
|
||||
switch (waveId)
|
||||
{
|
||||
case 1:
|
||||
me.SummonCreature(CreatureIds.WrathRider, Misc.FirstNagaCoord[0], TempSummonType.TimedDespawnOOC, 60000);
|
||||
me.SummonCreature(CreatureIds.WrathSorceress, Misc.FirstNagaCoord[1], TempSummonType.TimedDespawnOOC, 60000);
|
||||
me.SummonCreature(CreatureIds.WrathRazortail, Misc.FirstNagaCoord[2], TempSummonType.TimedDespawnOOC, 60000);
|
||||
break;
|
||||
case 2:
|
||||
me.SummonCreature(CreatureIds.WrathPriestess, Misc.SecondNagaCoord[0], TempSummonType.TimedDespawnOOC, 60000);
|
||||
me.SummonCreature(CreatureIds.WrathMyrmidon, Misc.SecondNagaCoord[1], TempSummonType.TimedDespawnOOC, 60000);
|
||||
me.SummonCreature(CreatureIds.WrathSeawitch, Misc.SecondNagaCoord[2], TempSummonType.TimedDespawnOOC, 60000);
|
||||
break;
|
||||
case 3:
|
||||
me.SummonCreature(CreatureIds.Vorsha, Misc.VorshaCoord, TempSummonType.TimedDespawnOOC, 60000);
|
||||
break;
|
||||
case 4:
|
||||
SetEscortPaused(false);
|
||||
Talk(TextIds.SayMugDone);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (!me.GetVictim())
|
||||
{
|
||||
if (HasEscortState(eEscortState.Paused) && _isBrazierExtinguished)
|
||||
{
|
||||
if (eventTimer < diff)
|
||||
{
|
||||
++waveId;
|
||||
DoWaveSummon();
|
||||
eventTimer = 10000;
|
||||
}
|
||||
else
|
||||
eventTimer -= diff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
uint eventTimer;
|
||||
byte waveId;
|
||||
|
||||
public bool _isBrazierExtinguished { get; set; }
|
||||
}
|
||||
|
||||
[Script]
|
||||
class go_naga_brazier : GameObjectScript
|
||||
{
|
||||
public go_naga_brazier() : base("go_naga_brazier") { }
|
||||
|
||||
public override bool OnGossipHello(Player player, GameObject go)
|
||||
{
|
||||
Creature creature = ScriptedAI.GetClosestCreatureWithEntry(go, CreatureIds.Muglash, SharedConst.InteractionDistance * 2);
|
||||
if (creature)
|
||||
{
|
||||
npc_muglash pEscortAI = creature.GetAI<npc_muglash>();
|
||||
if (pEscortAI != null)
|
||||
{
|
||||
creature.GetAI().Talk(TextIds.SayMugBrazierWait);
|
||||
|
||||
pEscortAI._isBrazierExtinguished = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_destroy_karangs_banner : SpellScript
|
||||
{
|
||||
void HandleAfterCast()
|
||||
{
|
||||
GameObject banner = GetCaster().FindNearestGameObject(GameObjectIds.Banner, GetSpellInfo().GetMaxRange(true));
|
||||
if (banner)
|
||||
banner.Delete();
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterCast.Add(new CastHandler(HandleAfterCast));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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 Framework.Dynamic;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
|
||||
namespace Scripts.Kalimdor
|
||||
{
|
||||
[Script]
|
||||
class npc_lazy_peon : NullCreatureAI
|
||||
{
|
||||
public npc_lazy_peon(Creature creature) : base(creature) { }
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
me.SetWalk(true);
|
||||
|
||||
scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(120000), task =>
|
||||
{
|
||||
GameObject Lumberpile = me.FindNearestGameObject(GoLumberpile, 20);
|
||||
if (Lumberpile)
|
||||
me.GetMotionMaster().MovePoint(1, Lumberpile.GetPositionX() - 1, Lumberpile.GetPositionY(), Lumberpile.GetPositionZ());
|
||||
task.Repeat();
|
||||
});
|
||||
|
||||
scheduler.Schedule(TimeSpan.FromMilliseconds(300000), task =>
|
||||
{
|
||||
me.HandleEmoteCommand(Emote.StateNone);
|
||||
me.GetMotionMaster().MovePoint(2, me.GetHomePosition());
|
||||
task.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 1:
|
||||
me.HandleEmoteCommand(Emote.StateWorkChopwood);
|
||||
break;
|
||||
case 2:
|
||||
DoCast(me, SpellBuffSleep);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SpellHit(Unit caster, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id != SpellAwakenPeon)
|
||||
return;
|
||||
|
||||
Player player = caster.ToPlayer();
|
||||
if (player && player.GetQuestStatus(QuestLazyPeons) == QuestStatus.Incomplete)
|
||||
{
|
||||
player.KilledMonsterCredit(me.GetEntry(), me.GetGUID());
|
||||
Talk(SaySpellHit, caster);
|
||||
me.RemoveAllAuras();
|
||||
GameObject Lumberpile = me.FindNearestGameObject(GoLumberpile, 20);
|
||||
if (Lumberpile)
|
||||
me.GetMotionMaster().MovePoint(1, Lumberpile.GetPositionX() - 1, Lumberpile.GetPositionY(), Lumberpile.GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
scheduler.Update(diff);
|
||||
|
||||
//if (!UpdateVictim())
|
||||
//return;
|
||||
|
||||
//DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
const int QuestLazyPeons = 37446;
|
||||
const int GoLumberpile = 175784;
|
||||
const uint SpellBuffSleep = 17743;
|
||||
const int SpellAwakenPeon = 19938;
|
||||
const int SaySpellHit = 0;
|
||||
|
||||
TaskScheduler scheduler = new TaskScheduler();
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_voodoo : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellBrew, SpellGhostly, SpellHex1, SpellHex2, SpellHex3, SpellGrow, SpellLaunch);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
uint spellid = RandomHelper.RAND(SpellBrew, SpellGhostly, RandomHelper.RAND(SpellHex1, SpellHex2, SpellHex3), SpellGrow, SpellLaunch);
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
GetCaster().CastSpell(target, spellid, false);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
|
||||
const uint SpellBrew = 16712; // Special Brew
|
||||
const uint SpellGhostly = 16713; // Ghostly
|
||||
const uint SpellHex1 = 16707; // Hex
|
||||
const uint SpellHex2 = 16708; // Hex
|
||||
const uint SpellHex3 = 16709; // Hex
|
||||
const uint SpellGrow = 16711; // Grow
|
||||
const uint SpellLaunch = 16716; // Launch (Whee!)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.Amanitar
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Bash = 57094; // Victim
|
||||
public const uint EntanglingRoots = 57095; // Random Victim 100y
|
||||
public const uint Mini = 57055; // Self
|
||||
public const uint VenomBoltVolley = 57088; // Random Victim 100y
|
||||
public const uint HealthyMushroomPotentFungus = 56648; // Killer 3y
|
||||
public const uint PoisonousMushroomPoisonCloud = 57061; // Self - Duration 8 Sec
|
||||
public const uint PoisonousMushroomVisualArea = 61566; // Self
|
||||
public const uint PoisonousMushroomVisualAura = 56741; // Self
|
||||
public const uint PutridMushroom = 31690; // To Make The Mushrooms Visible
|
||||
public const uint PowerMushroomVisualAura = 56740;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint Trigger = 19656;
|
||||
public const uint HealthyMushroom = 30391;
|
||||
public const uint PoisonousMushroom = 30435;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_amanitar : BossAI
|
||||
{
|
||||
public boss_amanitar(Creature creature) : base(creature, DataTypes.Amanitar) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
me.SetMeleeDamageSchool(SpellSchools.Nature);
|
||||
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Nature, true);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
SpawnAdds();
|
||||
task.Repeat(TimeSpan.FromSeconds(20));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(9), task =>
|
||||
{
|
||||
DoCast(SelectTarget(SelectAggroTarget.Random, 0, 100, true), SpellIds.EntanglingRoots, true);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(14), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Bash);
|
||||
task.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(12));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(18), task =>
|
||||
{
|
||||
DoCast(SpellIds.Mini);
|
||||
task.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(30));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCast(SelectTarget(SelectAggroTarget.Random, 0, 100, true), SpellIds.VenomBoltVolley, true);
|
||||
task.Repeat(TimeSpan.FromSeconds(18), TimeSpan.FromSeconds(22));
|
||||
});
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
instance.DoRemoveAurasDueToSpellOnPlayers(SpellIds.Mini);
|
||||
}
|
||||
|
||||
void SpawnAdds()
|
||||
{
|
||||
int u = 0;
|
||||
|
||||
for (byte i = 0; i < 30; ++i)
|
||||
{
|
||||
Position pos = me.GetRandomNearPosition(30.0f);
|
||||
pos.posZ = me.GetMap().GetHeight(pos.GetPositionX(), pos.GetPositionY(), MapConst.MaxHeight) + 2.0f;
|
||||
|
||||
Creature trigger = me.SummonCreature(CreatureIds.Trigger, pos);
|
||||
if (trigger)
|
||||
{
|
||||
Creature temp1 = trigger.FindNearestCreature(CreatureIds.HealthyMushroom, 4.0f, true);
|
||||
Creature temp2 = trigger.FindNearestCreature(CreatureIds.PoisonousMushroom, 4.0f, true);
|
||||
if (temp1 || temp2)
|
||||
{
|
||||
trigger.DisappearAndDie();
|
||||
}
|
||||
else
|
||||
{
|
||||
u = 1 - u;
|
||||
trigger.DisappearAndDie();
|
||||
me.SummonCreature(u > 0 ? CreatureIds.PoisonousMushroom : CreatureIds.HealthyMushroom, pos, TempSummonType.TimedOrCorpseDespawn, 60 * Time.InMilliseconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_amanitar_mushrooms : ScriptedAI
|
||||
{
|
||||
public npc_amanitar_mushrooms(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(1), task =>
|
||||
{
|
||||
if (me.GetEntry() == CreatureIds.PoisonousMushroom)
|
||||
{
|
||||
DoCast(me, SpellIds.PoisonousMushroomVisualArea, true);
|
||||
DoCast(me, SpellIds.PoisonousMushroomPoisonCloud);
|
||||
}
|
||||
task.Repeat(TimeSpan.FromSeconds(7));
|
||||
});
|
||||
|
||||
me.SetDisplayId(me.GetCreatureTemplate().ModelId2);
|
||||
DoCast(SpellIds.PutridMushroom);
|
||||
|
||||
if (me.GetEntry() == CreatureIds.PoisonousMushroom)
|
||||
DoCast(SpellIds.PoisonousMushroomVisualAura);
|
||||
else
|
||||
DoCast(SpellIds.PowerMushroomVisualAura);
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (damage >= me.GetHealth() && me.GetEntry() == CreatureIds.HealthyMushroom)
|
||||
DoCast(me, SpellIds.HealthyMushroomPotentFungus, true);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
public override void AttackStart(Unit victim) { }
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.ElderNadox
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint BroodPlague = 56130;
|
||||
public const uint HBroodRage = 59465;
|
||||
public const uint Enrage = 26662; // Enraged If Too Far Away From Home
|
||||
public const uint SummonSwarmers = 56119; // 2x 30178 -- 2x Every 10secs
|
||||
public const uint SummonSwarmGuard = 56120; // 1x 30176
|
||||
|
||||
// Adds
|
||||
public const uint SwarmBuff = 56281;
|
||||
public const uint Sprint = 56354;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SaySlay = 1;
|
||||
public const uint SayDeath = 2;
|
||||
public const uint SayEggSac = 3;
|
||||
public const uint EmoteHatches = 4;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint DataRespectYourElders = 6;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_elder_nadox : BossAI
|
||||
{
|
||||
public boss_elder_nadox(Creature creature) : base(creature, DataTypes.ElderNadox)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
GuardianSummoned = false;
|
||||
GuardianDied = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(TextIds.SayAggro);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(13), task =>
|
||||
{
|
||||
DoCast(SelectTarget(SelectAggroTarget.Random, 0, 100, true), SpellIds.BroodPlague, true);
|
||||
task.Repeat(TimeSpan.FromSeconds(15));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
/// @todo: summoned by egg
|
||||
DoCast(me, SpellIds.SummonSwarmers);
|
||||
if (RandomHelper.URand(1, 3) == 3) // 33% chance of dialog
|
||||
Talk(TextIds.SayEggSac);
|
||||
task.Repeat();
|
||||
});
|
||||
|
||||
if (IsHeroic())
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
DoCast(SpellIds.HBroodRage);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(50));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
if (me.HasAura(SpellIds.Enrage))
|
||||
return;
|
||||
if (me.GetPositionZ() < 24.0f)
|
||||
DoCast(me, SpellIds.Enrage, true);
|
||||
task.Repeat();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void SummonedCreatureDies(Creature summon, Unit killer)
|
||||
{
|
||||
if (summon.GetEntry() == AKCreatureIds.AhnkaharGuardian)
|
||||
GuardianDied = true;
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
if (type == Misc.DataRespectYourElders)
|
||||
return !GuardianDied ? 1 : 0u;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.IsTypeId(TypeId.Player))
|
||||
Talk(TextIds.SaySlay);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(TextIds.SayDeath);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (!GuardianSummoned && me.HealthBelowPct(50))
|
||||
{
|
||||
/// @todo: summoned by egg
|
||||
Talk(TextIds.EmoteHatches, me);
|
||||
DoCast(me, SpellIds.SummonSwarmGuard);
|
||||
GuardianSummoned = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool GuardianSummoned;
|
||||
bool GuardianDied;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_ahnkahar_nerubian : ScriptedAI
|
||||
{
|
||||
public npc_ahnkahar_nerubian(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(13), task =>
|
||||
{
|
||||
DoCast(me, SpellIds.Sprint);
|
||||
task.Repeat(TimeSpan.FromSeconds(20));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
// 56159 - Swarm
|
||||
[Script]
|
||||
class spell_ahn_kahet_swarm : SpellScript
|
||||
{
|
||||
public spell_ahn_kahet_swarm()
|
||||
{
|
||||
_targetCount = 0;
|
||||
}
|
||||
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SwarmBuff);
|
||||
}
|
||||
|
||||
void CountTargets(List<WorldObject> targets)
|
||||
{
|
||||
_targetCount = targets.Count;
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
if (_targetCount != 0)
|
||||
{
|
||||
Aura aura = GetCaster().GetAura(SpellIds.SwarmBuff);
|
||||
if (aura != null)
|
||||
{
|
||||
aura.SetStackAmount((byte)_targetCount);
|
||||
aura.RefreshDuration();
|
||||
}
|
||||
else
|
||||
GetCaster().CastCustomSpell(SpellIds.SwarmBuff, SpellValueMod.AuraStack, _targetCount, GetCaster(), TriggerCastFlags.FullMask);
|
||||
}
|
||||
else
|
||||
GetCaster().RemoveAurasDueToSpell(SpellIds.SwarmBuff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(CountTargets, 0, Targets.UnitSrcAreaAlly));
|
||||
OnEffectHit.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
|
||||
int _targetCount;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_respect_your_elders : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_respect_your_elders() : base("achievement_respect_your_elders") { }
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
return target && target.GetAI().GetData(Misc.DataRespectYourElders) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.HeraldVolazj
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Insanity = 57496; //Dummy
|
||||
public const uint InsanityVisual = 57561;
|
||||
public const uint InsanityTarget = 57508;
|
||||
public const uint MindFlay = 57941;
|
||||
public const uint ShadowBoltVolley = 57942;
|
||||
public const uint Shiver = 57949;
|
||||
public const uint ClonePlayer = 57507; //Cast On Player During Insanity
|
||||
public const uint InsanityPhasing1 = 57508;
|
||||
public const uint InsanityPhasing2 = 57509;
|
||||
public const uint InsanityPhasing3 = 57510;
|
||||
public const uint InsanityPhasing4 = 57511;
|
||||
public const uint InsanityPhasing5 = 57512;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SaySlay = 1;
|
||||
public const uint SayDeath = 2;
|
||||
public const uint SayPhase = 3;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint AchievQuickDemiseStartEvent = 20382;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_volazj : ScriptedAI
|
||||
{
|
||||
public boss_volazj(Creature creature) : base(creature)
|
||||
{
|
||||
Summons = new SummonList(me);
|
||||
|
||||
Initialize();
|
||||
instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiMindFlayTimer = 8 * Time.InMilliseconds;
|
||||
uiShadowBoltVolleyTimer = 5 * Time.InMilliseconds;
|
||||
uiShiverTimer = 15 * Time.InMilliseconds;
|
||||
// Used for Insanity handling
|
||||
insanityHandled = 0;
|
||||
}
|
||||
|
||||
// returns the percentage of health after taking the given damage.
|
||||
uint GetHealthPct(uint damage)
|
||||
{
|
||||
if (damage > me.GetHealth())
|
||||
return 0;
|
||||
return (uint)(100 * (me.GetHealth() - damage) / me.GetMaxHealth());
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit pAttacker, ref uint damage)
|
||||
{
|
||||
if (me.HasFlag(UnitFields.Flags, UnitFlags.NotSelectable))
|
||||
damage = 0;
|
||||
|
||||
if ((GetHealthPct(0) >= 66 && GetHealthPct(damage) < 66) ||
|
||||
(GetHealthPct(0) >= 33 && GetHealthPct(damage) < 33))
|
||||
{
|
||||
me.InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SpellIds.Insanity, false);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SpellHitTarget(Unit target, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id == SpellIds.Insanity)
|
||||
{
|
||||
// Not good target or too many players
|
||||
if (target.GetTypeId() != TypeId.Player || insanityHandled > 4)
|
||||
return;
|
||||
// First target - start channel visual and set self as unnattackable
|
||||
if (insanityHandled == 0)
|
||||
{
|
||||
// Channel visual
|
||||
DoCast(me, SpellIds.InsanityVisual, true);
|
||||
// Unattackable
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
me.SetControlled(true, UnitState.Stunned);
|
||||
}
|
||||
|
||||
// phase the player
|
||||
target.CastSpell(target, SpellIds.InsanityTarget + insanityHandled, true);
|
||||
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.InsanityTarget + insanityHandled);
|
||||
if (spellInfo == null)
|
||||
return;
|
||||
|
||||
// summon twisted party members for this target
|
||||
var players = me.GetMap().GetPlayers();
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (!player || !player.IsAlive())
|
||||
continue;
|
||||
// Summon clone
|
||||
Unit summon = me.SummonCreature(AKCreatureIds.TwistedVisage, me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), me.GetOrientation(), TempSummonType.CorpseDespawn, 0);
|
||||
if (summon)
|
||||
{
|
||||
// clone
|
||||
player.CastSpell(summon, SpellIds.ClonePlayer, true);
|
||||
// phase the summon
|
||||
summon.SetInPhase((uint)spellInfo.GetEffect(0).MiscValueB, true, true);
|
||||
}
|
||||
}
|
||||
++insanityHandled;
|
||||
}
|
||||
}
|
||||
|
||||
void ResetPlayersPhase()
|
||||
{
|
||||
var players = me.GetMap().GetPlayers();
|
||||
foreach (var player in players)
|
||||
{
|
||||
for (uint index = 0; index <= 4; ++index)
|
||||
player.RemoveAurasDueToSpell(SpellIds.InsanityTarget + index);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
instance.SetBossState(DataTypes.HeraldVolazj, EncounterState.NotStarted);
|
||||
instance.DoStopCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievQuickDemiseStartEvent);
|
||||
|
||||
// Visible for all players in insanity
|
||||
me.SetInPhase(169, true, true);
|
||||
for (uint i = 173; i <= 177; ++i)
|
||||
me.SetInPhase(i, true, true);
|
||||
|
||||
ResetPlayersPhase();
|
||||
|
||||
// Cleanup
|
||||
Summons.DespawnAll();
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
me.SetControlled(false, UnitState.Stunned);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
Talk(TextIds.SayAggro);
|
||||
|
||||
instance.SetBossState(DataTypes.HeraldVolazj, EncounterState.InProgress);
|
||||
instance.DoStartCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievQuickDemiseStartEvent);
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
Summons.Summon(summon);
|
||||
}
|
||||
|
||||
public override void SummonedCreatureDespawn(Creature summon)
|
||||
{
|
||||
uint nextPhase = 0;
|
||||
Summons.Despawn(summon);
|
||||
|
||||
// Check if all summons in this phase killed
|
||||
foreach (var guid in Summons)
|
||||
{
|
||||
Creature visage = ObjectAccessor.GetCreature(me, guid);
|
||||
if (visage)
|
||||
{
|
||||
// Not all are dead
|
||||
if (visage.IsInPhase(summon))
|
||||
return;
|
||||
else
|
||||
{
|
||||
nextPhase = visage.GetPhases().First();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Roll Insanity
|
||||
var players = me.GetMap().GetPlayers();
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
for (uint index = 0; index <= 4; ++index)
|
||||
player.RemoveAurasDueToSpell(SpellIds.InsanityTarget + index);
|
||||
player.CastSpell(player, SpellIds.InsanityTarget + nextPhase - 173, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (insanityHandled != 0)
|
||||
{
|
||||
if (!Summons.Empty())
|
||||
return;
|
||||
|
||||
insanityHandled = 0;
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
me.SetControlled(false, UnitState.Stunned);
|
||||
me.RemoveAurasDueToSpell(SpellIds.InsanityVisual);
|
||||
}
|
||||
|
||||
if (uiMindFlayTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.MindFlay);
|
||||
uiMindFlayTimer = 20 * Time.InMilliseconds;
|
||||
}
|
||||
else uiMindFlayTimer -= diff;
|
||||
|
||||
if (uiShadowBoltVolleyTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SpellIds.ShadowBoltVolley);
|
||||
uiShadowBoltVolleyTimer = 5 * Time.InMilliseconds;
|
||||
}
|
||||
else uiShadowBoltVolleyTimer -= diff;
|
||||
|
||||
if (uiShiverTimer <= diff)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Shiver);
|
||||
uiShiverTimer = 15 * Time.InMilliseconds;
|
||||
}
|
||||
else uiShiverTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(TextIds.SayDeath);
|
||||
|
||||
instance.SetBossState(DataTypes.HeraldVolazj, EncounterState.Done);
|
||||
|
||||
Summons.DespawnAll();
|
||||
ResetPlayersPhase();
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.IsTypeId(TypeId.Player))
|
||||
Talk(TextIds.SaySlay);
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
uint uiMindFlayTimer;
|
||||
uint uiShadowBoltVolleyTimer;
|
||||
uint uiShiverTimer;
|
||||
uint insanityHandled;
|
||||
SummonList Summons;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.JedogaShadowseeker
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint SphereVisual = 56075;
|
||||
public const uint GiftOfTheHerald = 56219;
|
||||
public const uint CycloneStrike = 56855; // Self
|
||||
public const uint LightningBolt = 56891; // 40y
|
||||
public const uint Thundershock = 56926; // 30y
|
||||
|
||||
public const uint BeamVisualJedogasAufseher1 = 60342;
|
||||
public const uint BeamVisualJedogasAufseher2 = 56312;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SaySacrifice1 = 1;
|
||||
public const uint SaySacrifice2 = 2;
|
||||
public const uint SaySlay = 3;
|
||||
public const uint SayDeath = 4;
|
||||
public const uint SayPreaching = 5;
|
||||
}
|
||||
struct Misc
|
||||
{
|
||||
public const int ActionInitiateKilled = 1;
|
||||
public const uint DataVolunteerWork = 2;
|
||||
|
||||
public static Position[] JedogaPosition =
|
||||
{
|
||||
new Position(372.330994f, -705.278015f, -0.624178f, 5.427970f),
|
||||
new Position(372.330994f, -705.278015f, -16.179716f, 5.427970f)
|
||||
};
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class boss_jedoga_shadowseeker : ScriptedAI
|
||||
{
|
||||
public boss_jedoga_shadowseeker(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature.GetInstanceScript();
|
||||
bFirstTime = true;
|
||||
bPreDone = false;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiOpFerTimer = RandomHelper.URand(15 * Time.InMilliseconds, 20 * Time.InMilliseconds);
|
||||
|
||||
uiCycloneTimer = 3 * Time.InMilliseconds;
|
||||
uiBoltTimer = 7 * Time.InMilliseconds;
|
||||
uiThunderTimer = 12 * Time.InMilliseconds;
|
||||
|
||||
bOpFerok = false;
|
||||
bOpFerokFail = false;
|
||||
bOnGround = false;
|
||||
bCanDown = false;
|
||||
volunteerWork = true;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
if (!bFirstTime)
|
||||
instance.SetBossState(DataTypes.JedogaShadowseeker, EncounterState.Fail);
|
||||
|
||||
instance.SetGuidData(DataTypes.PlJedogaTarget, ObjectGuid.Empty);
|
||||
instance.SetGuidData(DataTypes.AddJedogaVictim, ObjectGuid.Empty);
|
||||
instance.SetData(DataTypes.JedogaResetInitiands, 0);
|
||||
MoveUp();
|
||||
|
||||
bFirstTime = false;
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
if (instance == null || (who.GetTypeId() == TypeId.Unit && who.GetEntry() == AKCreatureIds.JedogaController))
|
||||
return;
|
||||
|
||||
Talk(TextIds.SayAggro);
|
||||
me.SetInCombatWithZone();
|
||||
instance.SetBossState(DataTypes.JedogaShadowseeker, EncounterState.InProgress);
|
||||
}
|
||||
|
||||
public override void AttackStart(Unit who)
|
||||
{
|
||||
if (!who || (who.GetTypeId() == TypeId.Unit && who.GetEntry() == AKCreatureIds.JedogaController))
|
||||
return;
|
||||
|
||||
base.AttackStart(who);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit Victim)
|
||||
{
|
||||
if (!Victim || !Victim.IsTypeId(TypeId.Player))
|
||||
return;
|
||||
|
||||
Talk(TextIds.SaySlay);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(TextIds.SayDeath);
|
||||
instance.SetBossState(DataTypes.JedogaShadowseeker, EncounterState.Done);
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
if (action == Misc.ActionInitiateKilled)
|
||||
volunteerWork = false;
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
if (type == Misc.DataVolunteerWork)
|
||||
return volunteerWork ? 1 : 0u;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
if (instance == null || !who || (who.IsTypeId(TypeId.Unit) && who.GetEntry() == AKCreatureIds.JedogaController))
|
||||
return;
|
||||
|
||||
if (!bPreDone && who.IsTypeId(TypeId.Player) && me.GetDistance(who) < 100.0f)
|
||||
{
|
||||
Talk(TextIds.SayPreaching);
|
||||
bPreDone = true;
|
||||
}
|
||||
|
||||
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress || !bOnGround)
|
||||
return;
|
||||
|
||||
if (!me.GetVictim() && me.CanCreatureAttack(who))
|
||||
{
|
||||
float attackRadius = me.GetAttackDistance(who);
|
||||
if (me.IsWithinDistInMap(who, attackRadius) && me.IsWithinLOSInMap(who))
|
||||
{
|
||||
if (!me.GetVictim())
|
||||
{
|
||||
who.RemoveAurasByType(AuraType.ModStealth);
|
||||
AttackStart(who);
|
||||
}
|
||||
else
|
||||
{
|
||||
who.SetInCombatWith(me);
|
||||
me.AddThreat(who, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MoveDown()
|
||||
{
|
||||
bOpFerokFail = false;
|
||||
|
||||
instance.SetData(DataTypes.JedogaTriggerSwitch, 0);
|
||||
me.GetMotionMaster().MovePoint(1, Misc.JedogaPosition[1]);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, false);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, false);
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
|
||||
|
||||
me.RemoveAurasDueToSpell(SpellIds.SphereVisual);
|
||||
|
||||
bOnGround = true;
|
||||
|
||||
if (UpdateVictim())
|
||||
{
|
||||
AttackStart(me.GetVictim());
|
||||
me.GetMotionMaster().MoveChase(me.GetVictim());
|
||||
}
|
||||
else
|
||||
{
|
||||
Unit target = Global.ObjAccessor.GetUnit(me, instance.GetGuidData(DataTypes.PlJedogaTarget));
|
||||
if (target)
|
||||
{
|
||||
AttackStart(target);
|
||||
instance.SetData(DataTypes.JedogaResetInitiands, 0);
|
||||
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress)
|
||||
EnterCombat(target);
|
||||
}
|
||||
else if (!me.IsInCombat())
|
||||
EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
|
||||
void MoveUp()
|
||||
{
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, true);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
|
||||
|
||||
me.AttackStop();
|
||||
me.RemoveAllAuras();
|
||||
me.LoadCreaturesAddon();
|
||||
me.GetMotionMaster().MovePoint(0, Misc.JedogaPosition[0]);
|
||||
|
||||
instance.SetData(DataTypes.JedogaTriggerSwitch, 1);
|
||||
if (instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.InProgress)
|
||||
GetVictimForSacrifice();
|
||||
|
||||
bOnGround = false;
|
||||
uiOpFerTimer = RandomHelper.URand(15 * Time.InMilliseconds, 30 * Time.InMilliseconds);
|
||||
}
|
||||
|
||||
void GetVictimForSacrifice()
|
||||
{
|
||||
ObjectGuid victim = instance.GetGuidData(DataTypes.AddJedogaInitiand);
|
||||
if (!victim.IsEmpty())
|
||||
{
|
||||
Talk(TextIds.SaySacrifice1);
|
||||
instance.SetGuidData(DataTypes.AddJedogaVictim, victim);
|
||||
}
|
||||
else
|
||||
bCanDown = true;
|
||||
}
|
||||
|
||||
void Sacrifice()
|
||||
{
|
||||
Talk(TextIds.SaySacrifice2);
|
||||
|
||||
me.InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SpellIds.GiftOfTheHerald, false);
|
||||
|
||||
bOpFerok = false;
|
||||
bCanDown = true;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress && instance.GetData(DataTypes.AllInitiandDead) != 0)
|
||||
MoveDown();
|
||||
|
||||
if (bOpFerok && !bOnGround && !bCanDown)
|
||||
Sacrifice();
|
||||
|
||||
if (bOpFerokFail && !bOnGround && !bCanDown)
|
||||
bCanDown = true;
|
||||
|
||||
if (bCanDown)
|
||||
{
|
||||
MoveDown();
|
||||
bCanDown = false;
|
||||
}
|
||||
|
||||
if (bOnGround)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiCycloneTimer <= diff)
|
||||
{
|
||||
DoCast(me, SpellIds.CycloneStrike, false);
|
||||
uiCycloneTimer = RandomHelper.URand(15 * Time.InMilliseconds, 30 * Time.InMilliseconds);
|
||||
}
|
||||
else uiCycloneTimer -= diff;
|
||||
|
||||
if (uiBoltTimer <= diff)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
|
||||
if (target)
|
||||
me.CastSpell(target, SpellIds.LightningBolt, false);
|
||||
|
||||
uiBoltTimer = RandomHelper.URand(15 * Time.InMilliseconds, 30 * Time.InMilliseconds);
|
||||
}
|
||||
else uiBoltTimer -= diff;
|
||||
|
||||
if (uiThunderTimer <= diff)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
|
||||
if (target)
|
||||
me.CastSpell(target, SpellIds.Thundershock, false);
|
||||
|
||||
uiThunderTimer = RandomHelper.URand(15 * Time.InMilliseconds, 30 * Time.InMilliseconds);
|
||||
}
|
||||
else uiThunderTimer -= diff;
|
||||
|
||||
if (uiOpFerTimer <= diff)
|
||||
MoveUp();
|
||||
else
|
||||
uiOpFerTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
uint uiOpFerTimer;
|
||||
uint uiCycloneTimer;
|
||||
uint uiBoltTimer;
|
||||
uint uiThunderTimer;
|
||||
|
||||
bool bPreDone;
|
||||
public bool bOpFerok;
|
||||
bool bOnGround;
|
||||
public bool bOpFerokFail;
|
||||
bool bCanDown;
|
||||
bool volunteerWork;
|
||||
bool bFirstTime;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_jedoga_initiand : ScriptedAI
|
||||
{
|
||||
public npc_jedoga_initiand(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
bWalking = false;
|
||||
bCheckTimer = 2 * Time.InMilliseconds;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress)
|
||||
{
|
||||
me.RemoveAurasDueToSpell(SpellIds.SphereVisual);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, false);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, false);
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoCast(me, SpellIds.SphereVisual, false);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, true);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
if (!killer || instance == null)
|
||||
return;
|
||||
|
||||
if (bWalking)
|
||||
{
|
||||
Creature boss = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.JedogaShadowseeker));
|
||||
if (boss)
|
||||
{
|
||||
if (!boss.GetAI<boss_jedoga_shadowseeker>().bOpFerok)
|
||||
boss.GetAI<boss_jedoga_shadowseeker>().bOpFerokFail = true;
|
||||
|
||||
if (killer.IsTypeId(TypeId.Player))
|
||||
boss.GetAI().DoAction(Misc.ActionInitiateKilled);
|
||||
}
|
||||
|
||||
instance.SetGuidData(DataTypes.AddJedogaVictim, ObjectGuid.Empty);
|
||||
|
||||
bWalking = false;
|
||||
}
|
||||
if (killer.IsTypeId(TypeId.Player))
|
||||
instance.SetGuidData(DataTypes.PlJedogaTarget, killer.GetGUID());
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
|
||||
public override void AttackStart(Unit victim)
|
||||
{
|
||||
if ((instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.InProgress) || !victim)
|
||||
return;
|
||||
|
||||
base.AttackStart(victim);
|
||||
}
|
||||
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
if ((instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.InProgress) || !who)
|
||||
return;
|
||||
|
||||
base.MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType uiType, uint uiPointId)
|
||||
{
|
||||
if (uiType != MovementGeneratorType.Point || instance == null)
|
||||
return;
|
||||
|
||||
switch (uiPointId)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Creature boss = me.GetMap().GetCreature(instance.GetGuidData(DataTypes.JedogaShadowseeker));
|
||||
if (boss)
|
||||
{
|
||||
boss.GetAI<boss_jedoga_shadowseeker>().bOpFerok = true;
|
||||
boss.GetAI<boss_jedoga_shadowseeker>().bOpFerokFail = false;
|
||||
me.KillSelf();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (bCheckTimer <= diff)
|
||||
{
|
||||
if (me.GetGUID() == instance.GetGuidData(DataTypes.AddJedogaVictim) && !bWalking)
|
||||
{
|
||||
me.RemoveAurasDueToSpell(SpellIds.SphereVisual);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, false);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, false);
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
|
||||
|
||||
float distance = me.GetDistance(Misc.JedogaPosition[1]);
|
||||
|
||||
if (distance < 9.0f)
|
||||
me.SetSpeedRate(UnitMoveType.Walk, 0.5f);
|
||||
else if (distance < 15.0f)
|
||||
me.SetSpeedRate(UnitMoveType.Walk, 0.75f);
|
||||
else if (distance < 20.0f)
|
||||
me.SetSpeedRate(UnitMoveType.Walk, 1.0f);
|
||||
|
||||
me.GetMotionMaster().Clear(false);
|
||||
me.GetMotionMaster().MovePoint(1, Misc.JedogaPosition[1]);
|
||||
bWalking = true;
|
||||
}
|
||||
if (!bWalking)
|
||||
{
|
||||
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress && me.HasAura(SpellIds.SphereVisual))
|
||||
{
|
||||
me.RemoveAurasDueToSpell(SpellIds.SphereVisual);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, false);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, false);
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
|
||||
}
|
||||
if (instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.InProgress && !me.HasAura(SpellIds.SphereVisual))
|
||||
{
|
||||
DoCast(me, SpellIds.SphereVisual, false);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, true);
|
||||
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
|
||||
}
|
||||
}
|
||||
bCheckTimer = 2 * Time.InMilliseconds;
|
||||
}
|
||||
else bCheckTimer -= diff;
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
uint bCheckTimer;
|
||||
bool bWalking;
|
||||
}
|
||||
|
||||
|
||||
[Script]
|
||||
class npc_jedogas_aufseher_trigger : ScriptedAI
|
||||
{
|
||||
public npc_jedogas_aufseher_trigger(Creature creature) : base(creature)
|
||||
{
|
||||
instance = creature.GetInstanceScript();
|
||||
bRemoved = false;
|
||||
bRemoved2 = false;
|
||||
bCast = false;
|
||||
bCast2 = false;
|
||||
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
public override void Reset() { }
|
||||
public override void EnterCombat(Unit who) { }
|
||||
public override void AttackStart(Unit victim) { }
|
||||
public override void MoveInLineOfSight(Unit who) { }
|
||||
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!bRemoved && me.GetPositionX() > 440.0f)
|
||||
{
|
||||
if (instance.GetBossState(DataTypes.PrinceTaldaram) == EncounterState.Done)
|
||||
{
|
||||
me.InterruptNonMeleeSpells(true);
|
||||
bRemoved = true;
|
||||
return;
|
||||
}
|
||||
if (!bCast)
|
||||
{
|
||||
DoCast(me, SpellIds.BeamVisualJedogasAufseher1, false);
|
||||
bCast = true;
|
||||
}
|
||||
}
|
||||
if (!bRemoved2 && me.GetPositionX() < 440.0f)
|
||||
{
|
||||
if (!bCast2 && instance.GetData(DataTypes.JedogaTriggerSwitch) != 0)
|
||||
{
|
||||
DoCast(me, SpellIds.BeamVisualJedogasAufseher2, false);
|
||||
bCast2 = true;
|
||||
}
|
||||
if (bCast2 && instance.GetData(DataTypes.JedogaTriggerSwitch) == 0)
|
||||
{
|
||||
me.InterruptNonMeleeSpells(true);
|
||||
bCast2 = false;
|
||||
}
|
||||
if (!bRemoved2 && instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.Done)
|
||||
{
|
||||
me.InterruptNonMeleeSpells(true);
|
||||
bRemoved2 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
bool bRemoved;
|
||||
bool bRemoved2;
|
||||
bool bCast;
|
||||
bool bCast2;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_volunteer_work : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_volunteer_work() : base("achievement_volunteer_work") { }
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Creature Jedoga = target.ToCreature();
|
||||
if (Jedoga)
|
||||
if (Jedoga.GetAI().GetData(Misc.DataVolunteerWork) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.PrinceTaldaram
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Bloodthirst = 55968; // Trigger Spell + Add Aura
|
||||
public const uint ConjureFlameSphere = 55931;
|
||||
public const uint FlameSphereSummon1 = 55895; // 1x 30106
|
||||
public const uint FlameSphereSummon2 = 59511; // 1x 31686
|
||||
public const uint FlameSphereSummon3 = 59512; // 1x 31687
|
||||
public const uint FlameSphereSpawnEffect = 55891;
|
||||
public const uint FlameSphereVisual = 55928;
|
||||
public const uint FlameSpherePeriodic = 55926;
|
||||
public const uint FlameSphereDeathEffect = 55947;
|
||||
public const uint EmbraceOfTheVampyr = 55959;
|
||||
public const uint Vanish = 55964;
|
||||
|
||||
public const uint BeamVisual = 60342;
|
||||
public const uint HoverFall = 60425;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint FlameSphere1 = 30106;
|
||||
public const uint FlameSphere2 = 31686;
|
||||
public const uint FlameSphere3 = 31687;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint Say1 = 0;
|
||||
public const uint SayWarning = 1;
|
||||
public const uint SayAggro = 2;
|
||||
public const uint SaySlay = 3;
|
||||
public const uint SayDeath = 4;
|
||||
public const uint SayFeed = 5;
|
||||
public const uint SayVanish = 6;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint EventConjureFlameSpheres = 1;
|
||||
public const uint EventBloodthirst = 2;
|
||||
public const uint EventVanish = 3;
|
||||
public const uint EventJustVanished = 4;
|
||||
public const uint EventVanished = 5;
|
||||
public const uint EventFeeding = 6;
|
||||
|
||||
// Flame Sphere
|
||||
public const uint EventStartMove = 7;
|
||||
public const uint EventDespawn = 8;
|
||||
|
||||
public const uint DataEmbraceDmg = 20000;
|
||||
public const uint DataEmbraceDmgH = 40000;
|
||||
public const float DataSphereDistance = 25.0f;
|
||||
public const float DataSphereAngleOffset = MathFunctions.PI / 2;
|
||||
public const float DataGroundPositionZ = 11.30809f;
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class boss_prince_taldaram : BossAI
|
||||
{
|
||||
public boss_prince_taldaram(Creature creature) : base(creature, DataTypes.PrinceTaldaram)
|
||||
{
|
||||
me.SetDisableGravity(true);
|
||||
_embraceTakenDamage = 0;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
_flameSphereTargetGUID.Clear();
|
||||
_embraceTargetGUID.Clear();
|
||||
_embraceTakenDamage = 0;
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(TextIds.SayAggro);
|
||||
_events.ScheduleEvent(Misc.EventBloodthirst, 10000);
|
||||
_events.ScheduleEvent(Misc.EventVanish, RandomHelper.URand(25000, 35000));
|
||||
_events.ScheduleEvent(Misc.EventConjureFlameSpheres, 5000);
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
base.JustSummoned(summon);
|
||||
|
||||
switch (summon.GetEntry())
|
||||
{
|
||||
case CreatureIds.FlameSphere1:
|
||||
case CreatureIds.FlameSphere2:
|
||||
case CreatureIds.FlameSphere3:
|
||||
summon.GetAI().SetGUID(_flameSphereTargetGUID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Misc.EventBloodthirst:
|
||||
DoCast(me, SpellIds.Bloodthirst);
|
||||
_events.ScheduleEvent(Misc.EventBloodthirst, 10000);
|
||||
break;
|
||||
case Misc.EventConjureFlameSpheres:
|
||||
// random target?
|
||||
Unit victim = me.GetVictim();
|
||||
if (victim)
|
||||
{
|
||||
_flameSphereTargetGUID = victim.GetGUID();
|
||||
DoCast(victim, SpellIds.ConjureFlameSphere);
|
||||
}
|
||||
_events.ScheduleEvent(Misc.EventConjureFlameSpheres, 15000);
|
||||
break;
|
||||
case Misc.EventVanish:
|
||||
{
|
||||
var players = me.GetMap().GetPlayers();
|
||||
uint targets = 0;
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player && player.IsAlive())
|
||||
++targets;
|
||||
}
|
||||
|
||||
if (targets > 2)
|
||||
{
|
||||
Talk(TextIds.SayVanish);
|
||||
DoCast(me, SpellIds.Vanish);
|
||||
me.SetInCombatState(true); // Prevents the boss from resetting
|
||||
_events.DelayEvents(500);
|
||||
_events.ScheduleEvent(Misc.EventJustVanished, 500);
|
||||
Unit embraceTarget = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
|
||||
if (embraceTarget)
|
||||
_embraceTargetGUID = embraceTarget.GetGUID();
|
||||
}
|
||||
_events.ScheduleEvent(Misc.EventVanish, RandomHelper.URand(25000, 35000));
|
||||
break;
|
||||
}
|
||||
case Misc.EventJustVanished:
|
||||
{
|
||||
Unit embraceTarget = GetEmbraceTarget();
|
||||
if (embraceTarget)
|
||||
{
|
||||
me.GetMotionMaster().Clear();
|
||||
me.SetSpeedRate(UnitMoveType.Walk, 2.0f);
|
||||
me.GetMotionMaster().MoveChase(embraceTarget);
|
||||
}
|
||||
_events.ScheduleEvent(Misc.EventVanished, 1300);
|
||||
}
|
||||
break;
|
||||
case Misc.EventVanished:
|
||||
{
|
||||
Unit embraceTarget = GetEmbraceTarget();
|
||||
if (embraceTarget)
|
||||
DoCast(embraceTarget, SpellIds.EmbraceOfTheVampyr);
|
||||
Talk(TextIds.SayFeed);
|
||||
me.GetMotionMaster().Clear();
|
||||
me.SetSpeedRate(UnitMoveType.Walk, 1.0f);
|
||||
me.GetMotionMaster().MoveChase(me.GetVictim());
|
||||
_events.ScheduleEvent(Misc.EventFeeding, 20000);
|
||||
}
|
||||
break;
|
||||
case Misc.EventFeeding:
|
||||
_embraceTargetGUID.Clear();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit doneBy, ref uint damage)
|
||||
{
|
||||
Unit embraceTarget = GetEmbraceTarget();
|
||||
|
||||
if (embraceTarget && embraceTarget.IsAlive())
|
||||
{
|
||||
_embraceTakenDamage += damage;
|
||||
if (_embraceTakenDamage > DungeonMode<uint>(Misc.DataEmbraceDmg, Misc.DataEmbraceDmgH))
|
||||
{
|
||||
_embraceTargetGUID.Clear();
|
||||
me.CastStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(TextIds.SayDeath);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (!victim.IsTypeId(TypeId.Player))
|
||||
return;
|
||||
|
||||
if (victim.GetGUID() == _embraceTargetGUID)
|
||||
_embraceTargetGUID.Clear();
|
||||
|
||||
Talk(TextIds.SaySlay);
|
||||
}
|
||||
|
||||
public bool CheckSpheres()
|
||||
{
|
||||
for (byte i = 0; i < 2; ++i)
|
||||
{
|
||||
if (instance.GetData(DataTypes.Sphere1 + i) == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
RemovePrison();
|
||||
return true;
|
||||
}
|
||||
|
||||
Unit GetEmbraceTarget()
|
||||
{
|
||||
if (!_embraceTargetGUID.IsEmpty())
|
||||
return Global.ObjAccessor.GetUnit(me, _embraceTargetGUID);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void RemovePrison()
|
||||
{
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
me.RemoveAurasDueToSpell(SpellIds.BeamVisual);
|
||||
me.SetHomePosition(me.GetPositionX(), me.GetPositionY(), Misc.DataGroundPositionZ, me.GetOrientation());
|
||||
DoCast(SpellIds.HoverFall);
|
||||
me.SetDisableGravity(false);
|
||||
me.GetMotionMaster().MoveLand(0, me.GetHomePosition());
|
||||
Talk(TextIds.SayWarning);
|
||||
instance.HandleGameObject(instance.GetGuidData(DataTypes.PrinceTaldaramPlatform), true);
|
||||
}
|
||||
|
||||
ObjectGuid _flameSphereTargetGUID;
|
||||
ObjectGuid _embraceTargetGUID;
|
||||
uint _embraceTakenDamage;
|
||||
}
|
||||
|
||||
[Script] // 30106, 31686, 31687 - Flame Sphere
|
||||
class npc_prince_taldaram_flame_sphere : ScriptedAI
|
||||
{
|
||||
public npc_prince_taldaram_flame_sphere(Creature creature) : base(creature)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
DoCast(me, SpellIds.FlameSphereSpawnEffect, true);
|
||||
DoCast(me, SpellIds.FlameSphereVisual, true);
|
||||
|
||||
_flameSphereTargetGUID.Clear();
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(Misc.EventStartMove, 3 * Time.InMilliseconds);
|
||||
_events.ScheduleEvent(Misc.EventDespawn, 13 * Time.InMilliseconds);
|
||||
}
|
||||
|
||||
public override void SetGUID(ObjectGuid guid, int id = 0)
|
||||
{
|
||||
_flameSphereTargetGUID = guid;
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
|
||||
public override void MoveInLineOfSight(Unit who) { }
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Misc.EventStartMove:
|
||||
{
|
||||
DoCast(me, SpellIds.FlameSpherePeriodic, true);
|
||||
|
||||
/// @todo: find correct values
|
||||
float angleOffset = 0.0f;
|
||||
float distOffset = Misc.DataSphereDistance;
|
||||
|
||||
switch (me.GetEntry())
|
||||
{
|
||||
case CreatureIds.FlameSphere1:
|
||||
break;
|
||||
case CreatureIds.FlameSphere2:
|
||||
angleOffset = Misc.DataSphereAngleOffset;
|
||||
break;
|
||||
case CreatureIds.FlameSphere3:
|
||||
angleOffset = -Misc.DataSphereAngleOffset;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
Unit sphereTarget = Global.ObjAccessor.GetUnit(me, _flameSphereTargetGUID);
|
||||
if (!sphereTarget)
|
||||
return;
|
||||
|
||||
float angle = me.GetAngle(sphereTarget) + angleOffset;
|
||||
float x = me.GetPositionX() + distOffset * (float)Math.Cos(angle);
|
||||
float y = me.GetPositionY() + distOffset * (float)Math.Sin(angle);
|
||||
|
||||
/// @todo: correct speed
|
||||
me.GetMotionMaster().MovePoint(0, x, y, me.GetPositionZ());
|
||||
break;
|
||||
}
|
||||
case Misc.EventDespawn:
|
||||
DoCast(me, SpellIds.FlameSphereDeathEffect, true);
|
||||
me.DespawnOrUnsummon(1000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ObjectGuid _flameSphereTargetGUID;
|
||||
}
|
||||
|
||||
[Script] // 193093, 193094 - Ancient Nerubian Device
|
||||
class go_prince_taldaram_sphere : GameObjectScript
|
||||
{
|
||||
public go_prince_taldaram_sphere() : base("go_prince_taldaram_sphere") { }
|
||||
|
||||
public override bool OnGossipHello(Player player, GameObject go)
|
||||
{
|
||||
InstanceScript instance = go.GetInstanceScript();
|
||||
if (instance == null)
|
||||
return false;
|
||||
|
||||
Creature PrinceTaldaram = ObjectAccessor.GetCreature(go, instance.GetGuidData(DataTypes.PrinceTaldaram));
|
||||
if (PrinceTaldaram && PrinceTaldaram.IsAlive())
|
||||
{
|
||||
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GameObjectIds.Sphere1:
|
||||
instance.SetData(DataTypes.Sphere1, (uint)EncounterState.InProgress);
|
||||
PrinceTaldaram.GetAI().Talk(TextIds.Say1);
|
||||
break;
|
||||
case GameObjectIds.Sphere2:
|
||||
instance.SetData(DataTypes.Sphere2, (uint)EncounterState.InProgress);
|
||||
PrinceTaldaram.GetAI().Talk(TextIds.Say1);
|
||||
break;
|
||||
}
|
||||
|
||||
PrinceTaldaram.GetAI<boss_prince_taldaram>().CheckSpheres();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 55931 - Conjure Flame Sphere
|
||||
class spell_prince_taldaram_conjure_flame_sphere : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.FlameSphereSummon1, SpellIds.FlameSphereSummon2, SpellIds.FlameSphereSummon3);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
caster.CastSpell(caster, SpellIds.FlameSphereSummon1, true);
|
||||
|
||||
if (caster.GetMap().IsHeroic())
|
||||
{
|
||||
caster.CastSpell(caster, SpellIds.FlameSphereSummon2, true);
|
||||
caster.CastSpell(caster, SpellIds.FlameSphereSummon3, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 55895, 59511, 59512 - Flame Sphere Summon
|
||||
class spell_prince_taldaram_flame_sphere_summon : SpellScript
|
||||
{
|
||||
void SetDest(ref SpellDestination dest)
|
||||
{
|
||||
dest.RelocateOffset(new Position(0.0f, 0.0f, 5.5f, 0.0f));
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnDestinationTargetSelect.Add(new DestinationTargetSelectHandler(SetDest, 0, Targets.DestCaster));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Northrend.AzjolNerub.Ahnkahet
|
||||
{
|
||||
struct DataTypes
|
||||
{
|
||||
// Encounter States/Boss GUIDs
|
||||
public const uint ElderNadox = 0;
|
||||
public const uint PrinceTaldaram = 1;
|
||||
public const uint JedogaShadowseeker = 2;
|
||||
public const uint Amanitar = 3;
|
||||
public const uint HeraldVolazj = 4;
|
||||
|
||||
// Additional Data
|
||||
public const uint Sphere1 = 5;
|
||||
public const uint Sphere2 = 6;
|
||||
public const uint PrinceTaldaramPlatform = 7;
|
||||
public const uint PlJedogaTarget = 8;
|
||||
public const uint AddJedogaVictim = 9;
|
||||
public const uint AddJedogaInitiand = 10;
|
||||
public const uint JedogaTriggerSwitch = 11;
|
||||
public const uint JedogaResetInitiands = 12;
|
||||
public const uint AllInitiandDead = 13;
|
||||
}
|
||||
|
||||
struct AKCreatureIds
|
||||
{
|
||||
public const uint ElderNadox = 29309;
|
||||
public const uint PrinceTaldaram = 29308;
|
||||
public const uint JedogaShadowseeker = 29310;
|
||||
public const uint Amanitar = 30258;
|
||||
public const uint HeraldVolazj = 29311;
|
||||
|
||||
// Elder Nadox
|
||||
public const uint AhnkaharGuardian = 30176;
|
||||
public const uint AhnkaharSwarmer = 30178;
|
||||
|
||||
// Jedoga Shadowseeker
|
||||
public const uint Initiand = 30114;
|
||||
public const uint JedogaController = 30181;
|
||||
|
||||
// Herald Volazj
|
||||
//public const uint TwistedVisage1 = 30621,
|
||||
//public const uint TwistedVisage2 = 30622,
|
||||
//public const uint TwistedVisage3 = 30623,
|
||||
//public const uint TwistedVisage4 = 30624,
|
||||
public const uint TwistedVisage = 30625;
|
||||
}
|
||||
|
||||
struct GameObjectIds
|
||||
{
|
||||
public const uint PrinceTaldaramGate = 192236;
|
||||
public const uint PrinceTaldaramPlatform = 193564;
|
||||
public const uint Sphere1 = 193093;
|
||||
public const uint Sphere2 = 193094;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class instance_ahnkahet : InstanceMapScript
|
||||
{
|
||||
public instance_ahnkahet() : base("instance_ahnkahet", 619) { }
|
||||
|
||||
class instance_ahnkahet_InstanceScript : InstanceScript
|
||||
{
|
||||
public instance_ahnkahet_InstanceScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("AK");
|
||||
SetBossNumber(DataTypes.HeraldVolazj + 1);
|
||||
LoadDoorData(new DoorData(GameObjectIds.PrinceTaldaramGate, DataTypes.PrinceTaldaram, DoorType.Passage));
|
||||
|
||||
SwitchTrigger = 0;
|
||||
|
||||
SpheresState[0] = 0;
|
||||
SpheresState[1] = 0;
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case AKCreatureIds.ElderNadox:
|
||||
ElderNadoxGUID = creature.GetGUID();
|
||||
break;
|
||||
case AKCreatureIds.PrinceTaldaram:
|
||||
PrinceTaldaramGUID = creature.GetGUID();
|
||||
break;
|
||||
case AKCreatureIds.JedogaShadowseeker:
|
||||
JedogaShadowseekerGUID = creature.GetGUID();
|
||||
break;
|
||||
case AKCreatureIds.Amanitar:
|
||||
AmanitarGUID = creature.GetGUID();
|
||||
break;
|
||||
case AKCreatureIds.HeraldVolazj:
|
||||
HeraldVolazjGUID = creature.GetGUID();
|
||||
break;
|
||||
case AKCreatureIds.Initiand:
|
||||
InitiandGUIDs.Add(creature.GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GameObjectIds.PrinceTaldaramPlatform:
|
||||
PrinceTaldaramPlatformGUID = go.GetGUID();
|
||||
if (GetBossState(DataTypes.PrinceTaldaram) == EncounterState.Done)
|
||||
HandleGameObject(ObjectGuid.Empty, true, go);
|
||||
break;
|
||||
case GameObjectIds.Sphere1:
|
||||
if (SpheresState[0] != 0)
|
||||
{
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
}
|
||||
else
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
break;
|
||||
case GameObjectIds.Sphere2:
|
||||
if (SpheresState[1] != 0)
|
||||
{
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
}
|
||||
else
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
break;
|
||||
case GameObjectIds.PrinceTaldaramGate:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectRemove(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GameObjectIds.PrinceTaldaramGate:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetData(uint type, uint data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.Sphere1:
|
||||
case DataTypes.Sphere2:
|
||||
SpheresState[type - DataTypes.Sphere1] = data;
|
||||
break;
|
||||
case DataTypes.JedogaTriggerSwitch:
|
||||
SwitchTrigger = (byte)data;
|
||||
break;
|
||||
case DataTypes.JedogaResetInitiands:
|
||||
foreach (ObjectGuid guid in InitiandGUIDs)
|
||||
{
|
||||
Creature creature = instance.GetCreature(guid);
|
||||
if (creature)
|
||||
{
|
||||
creature.Respawn();
|
||||
if (!creature.IsInEvadeMode())
|
||||
creature.GetAI().EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.Sphere1:
|
||||
case DataTypes.Sphere2:
|
||||
return SpheresState[type - DataTypes.Sphere1];
|
||||
case DataTypes.AllInitiandDead:
|
||||
foreach (ObjectGuid guid in InitiandGUIDs)
|
||||
{
|
||||
Creature cr = instance.GetCreature(guid);
|
||||
if (!cr || cr.IsAlive())
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
case DataTypes.JedogaTriggerSwitch:
|
||||
return SwitchTrigger;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void SetGuidData(uint type, ObjectGuid data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.AddJedogaVictim:
|
||||
JedogaSacrifices = data;
|
||||
break;
|
||||
case DataTypes.PlJedogaTarget:
|
||||
JedogaTarget = data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.ElderNadox:
|
||||
return ElderNadoxGUID;
|
||||
case DataTypes.PrinceTaldaram:
|
||||
return PrinceTaldaramGUID;
|
||||
case DataTypes.JedogaShadowseeker:
|
||||
return JedogaShadowseekerGUID;
|
||||
case DataTypes.Amanitar:
|
||||
return AmanitarGUID;
|
||||
case DataTypes.HeraldVolazj:
|
||||
return HeraldVolazjGUID;
|
||||
case DataTypes.PrinceTaldaramPlatform:
|
||||
return PrinceTaldaramPlatformGUID;
|
||||
case DataTypes.AddJedogaInitiand:
|
||||
{
|
||||
List<ObjectGuid> vInitiands = new List<ObjectGuid>();
|
||||
foreach (ObjectGuid guid in InitiandGUIDs)
|
||||
{
|
||||
Creature cr = instance.GetCreature(guid);
|
||||
if (cr && cr.IsAlive())
|
||||
vInitiands.Add(guid);
|
||||
}
|
||||
if (vInitiands.Empty())
|
||||
return ObjectGuid.Empty;
|
||||
|
||||
return vInitiands.SelectRandom();
|
||||
}
|
||||
case DataTypes.AddJedogaVictim:
|
||||
return JedogaSacrifices;
|
||||
case DataTypes.PlJedogaTarget:
|
||||
return JedogaTarget;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
public override bool SetBossState(uint type, EncounterState state)
|
||||
{
|
||||
if (!base.SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.JedogaShadowseeker:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
foreach (ObjectGuid guid in InitiandGUIDs)
|
||||
{
|
||||
Creature cr = instance.GetCreature(guid);
|
||||
if (cr)
|
||||
cr.DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WriteSaveDataMore(string data)
|
||||
{
|
||||
data += SpheresState[0] + ' ' + SpheresState[1];
|
||||
}
|
||||
|
||||
void ReadSaveDataMore(string data)
|
||||
{
|
||||
data += SpheresState[0];
|
||||
data += SpheresState[1];
|
||||
}
|
||||
|
||||
ObjectGuid ElderNadoxGUID;
|
||||
ObjectGuid PrinceTaldaramGUID;
|
||||
ObjectGuid JedogaShadowseekerGUID;
|
||||
ObjectGuid AmanitarGUID;
|
||||
ObjectGuid HeraldVolazjGUID;
|
||||
|
||||
ObjectGuid PrinceTaldaramPlatformGUID;
|
||||
ObjectGuid JedogaSacrifices;
|
||||
ObjectGuid JedogaTarget;
|
||||
|
||||
List<ObjectGuid> InitiandGUIDs = new List<ObjectGuid>();
|
||||
|
||||
uint[] SpheresState = new uint[2];
|
||||
byte SwitchTrigger;
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_ahnkahet_InstanceScript(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,649 @@
|
||||
/*
|
||||
* 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 : BossAI
|
||||
{
|
||||
public boss_anub_arak(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 bool CanAIAttack(Unit victim) { return true; } // do not check boundary here
|
||||
|
||||
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
|
||||
GameObject door2 = instance.GetGameObject(ANDataTypes.AnubarakWall2);
|
||||
if (door2)
|
||||
door2.SetGoState(GameObjectState.Active);
|
||||
|
||||
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);
|
||||
GameObject door2 = instance.GetGameObject(ANDataTypes.AnubarakWall2);
|
||||
if (door2)
|
||||
door2.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;
|
||||
}
|
||||
|
||||
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 : npc_anubarak_pet_template
|
||||
{
|
||||
public npc_anubarak_anub_ar_darter(Creature creature) : base(creature, false) { }
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
base.InitializeAI();
|
||||
DoCastAOE(SpellIds.Dart);
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anubarak_anub_ar_assassin : npc_anubarak_pet_template
|
||||
{
|
||||
public npc_anubarak_anub_ar_assassin(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;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anubarak_anub_ar_guardian : npc_anubarak_pet_template
|
||||
{
|
||||
public npc_anubarak_anub_ar_guardian(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;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anubarak_anub_ar_venomancer : npc_anubarak_pet_template
|
||||
{
|
||||
public npc_anubarak_anub_ar_venomancer(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;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anubarak_impale_target : NullCreatureAI
|
||||
{
|
||||
public npc_anubarak_impale_target(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();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_anubarak_pound : 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));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_anubarak_carrion_beetles : 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,866 @@
|
||||
/*
|
||||
* 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.KrikthirTheGatewatcher
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
// Krik'Thir The Gatewatcher
|
||||
public const uint SubbossAggroTrigger = 52343;
|
||||
public const uint Swarm = 52440;
|
||||
public const uint MindFlay = 52586;
|
||||
public const uint CurseOfFatigue = 52592;
|
||||
public const uint Frenzy = 28747;
|
||||
|
||||
// Watchers - Shared
|
||||
public const uint WebWrap = 52086;
|
||||
public const uint WebWrapWrapped = 52087;
|
||||
public const uint InfectedBite = 52469;
|
||||
|
||||
// Watcher Gashra
|
||||
public const uint Enrage = 52470;
|
||||
// Watcher Narjil
|
||||
public const uint BlindingWebs = 52524;
|
||||
// Watcher Silthik
|
||||
public const uint PoisonSpray = 52493;
|
||||
|
||||
// Anub'Ar Warrior
|
||||
public const uint Cleave = 49806;
|
||||
public const uint Strike = 52532;
|
||||
|
||||
// Anub'Ar Skirmisher
|
||||
public const uint Charge = 52538;
|
||||
public const uint Backstab = 52540;
|
||||
public const uint FixtateTrigger = 52536;
|
||||
public const uint FixtateTriggered = 52537;
|
||||
|
||||
// Anub'Ar Shadowcaster
|
||||
public const uint ShadowBolt = 52534;
|
||||
public const uint ShadowNova = 52535;
|
||||
|
||||
// Skittering Infector
|
||||
public const uint AcidSplash = 52446;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint DataPetGroup = 0;
|
||||
|
||||
// Krik'thir the Gatewatcher
|
||||
public const uint EventSendGroup = 1;
|
||||
public const uint EventSwarm = 2;
|
||||
public const uint EventMindFlay = 3;
|
||||
public const uint EventFrenzy = 4;
|
||||
}
|
||||
|
||||
struct ActionIds
|
||||
{
|
||||
public const int GashraDied = 0;
|
||||
public const int NarjilDied = 1;
|
||||
public const int SilthikDied = 2;
|
||||
public const int WatcherEngaged = 3;
|
||||
public const int PetEngaged = 4;
|
||||
public const int PetEvade = 5;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SaySlay = 1;
|
||||
public const uint SayDeath = 2;
|
||||
public const uint SaySwarm = 3;
|
||||
public const uint SayPrefight = 4;
|
||||
public const uint SaySendGroup = 5;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_krik_thir : BossAI
|
||||
{
|
||||
public boss_krik_thir(Creature creature) : base(creature, ANDataTypes.KrikthirTheGatewatcher) { }
|
||||
|
||||
void SummonAdds()
|
||||
{
|
||||
if (instance.GetBossState(ANDataTypes.KrikthirTheGatewatcher) == EncounterState.Done)
|
||||
return;
|
||||
|
||||
for (byte i = 1; i <= 3; ++i)
|
||||
{
|
||||
List<TempSummon> summons;
|
||||
me.SummonCreatureGroup(i, out summons);
|
||||
|
||||
foreach (TempSummon summon in summons)
|
||||
summon.GetAI().SetData(Misc.DataPetGroup, i);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
_hadFrenzy = false;
|
||||
_petsInCombat = false;
|
||||
_watchersActive = 0;
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
}
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
base.InitializeAI();
|
||||
SummonAdds();
|
||||
}
|
||||
|
||||
public override void JustRespawned()
|
||||
{
|
||||
base.JustRespawned();
|
||||
SummonAdds();
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (victim.IsTypeId(TypeId.Player))
|
||||
Talk(TextIds.SaySlay);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
summons.Clear();
|
||||
base.JustDied(killer);
|
||||
Talk(TextIds.SayDeath);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_petsInCombat = false;
|
||||
me.SetReactState(ReactStates.Aggressive);
|
||||
summons.DoZoneInCombat();
|
||||
|
||||
_events.CancelEvent(Misc.EventSendGroup);
|
||||
_events.ScheduleEvent(Misc.EventSwarm, TimeSpan.FromSeconds(5));
|
||||
_events.ScheduleEvent(Misc.EventMindFlay, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3));
|
||||
|
||||
base.EnterCombat(who);
|
||||
}
|
||||
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
if (!me.HasReactState(ReactStates.Passive))
|
||||
{
|
||||
base.MoveInLineOfSight(who);
|
||||
return;
|
||||
}
|
||||
|
||||
if (me.CanStartAttack(who, false) && me.IsWithinDistInMap(who, me.GetAttackDistance(who) + me.m_CombatDistance))
|
||||
EnterCombat(who);
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
_DespawnAtEvade();
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case -ANInstanceMisc.ActionGatewatcherGreet:
|
||||
if (!_hadGreet && me.IsAlive() && !me.IsInCombat() && !_petsInCombat)
|
||||
{
|
||||
_hadGreet = true;
|
||||
Talk(TextIds.SayPrefight);
|
||||
}
|
||||
break;
|
||||
case ActionIds.GashraDied:
|
||||
case ActionIds.NarjilDied:
|
||||
case ActionIds.SilthikDied:
|
||||
if (_watchersActive == 0) // something is wrong
|
||||
{
|
||||
EnterEvadeMode(EvadeReason.Other);
|
||||
return;
|
||||
}
|
||||
if ((--_watchersActive) == 0) // if there are no watchers currently in combat...
|
||||
_events.RescheduleEvent(Misc.EventSendGroup, TimeSpan.FromSeconds(5)); // ...send the next watcher after the targets sooner
|
||||
break;
|
||||
case ActionIds.WatcherEngaged:
|
||||
++_watchersActive;
|
||||
break;
|
||||
case ActionIds.PetEngaged:
|
||||
if (_petsInCombat || me.IsInCombat())
|
||||
break;
|
||||
_petsInCombat = true;
|
||||
Talk(TextIds.SayAggro);
|
||||
_events.ScheduleEvent(Misc.EventSendGroup, TimeSpan.FromSeconds(70));
|
||||
break;
|
||||
case ActionIds.PetEvade:
|
||||
EnterEvadeMode(EvadeReason.Other);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim() && !_petsInCombat)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
if (me.HealthBelowPct(10) && !_hadFrenzy)
|
||||
{
|
||||
_hadFrenzy = true;
|
||||
_events.ScheduleEvent(Misc.EventFrenzy, TimeSpan.FromSeconds(1));
|
||||
}
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Misc.EventSendGroup:
|
||||
DoCastAOE(SpellIds.SubbossAggroTrigger, true);
|
||||
_events.Repeat(TimeSpan.FromSeconds(70));
|
||||
break;
|
||||
case Misc.EventSwarm:
|
||||
DoCastAOE(SpellIds.Swarm);
|
||||
Talk(TextIds.SaySwarm);
|
||||
break;
|
||||
case Misc.EventMindFlay:
|
||||
DoCastVictim(SpellIds.MindFlay);
|
||||
_events.Repeat(TimeSpan.FromSeconds(9), TimeSpan.FromSeconds(11));
|
||||
break;
|
||||
case Misc.EventFrenzy:
|
||||
DoCastSelf(SpellIds.Frenzy);
|
||||
DoCastAOE(SpellIds.CurseOfFatigue);
|
||||
_events.Repeat(TimeSpan.FromSeconds(15));
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void SpellHit(Unit whose, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id == SpellIds.SubbossAggroTrigger)
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
public override void SpellHitTarget(Unit who, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id == SpellIds.SubbossAggroTrigger)
|
||||
Talk(TextIds.SaySendGroup);
|
||||
}
|
||||
|
||||
bool _hadGreet;
|
||||
bool _hadFrenzy;
|
||||
bool _petsInCombat;
|
||||
byte _watchersActive;
|
||||
}
|
||||
|
||||
class npc_gatewatcher_petAI : ScriptedAI
|
||||
{
|
||||
public npc_gatewatcher_petAI(Creature creature, bool isWatcher) : base(creature)
|
||||
{
|
||||
_instance = creature.GetInstanceScript();
|
||||
_isWatcher = isWatcher;
|
||||
}
|
||||
|
||||
public virtual void _EnterCombat() { }
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
if (_isWatcher)
|
||||
{
|
||||
_isWatcher = false;
|
||||
|
||||
TempSummon meSummon = me.ToTempSummon();
|
||||
if (meSummon)
|
||||
{
|
||||
Creature summoner = meSummon.GetSummonerCreatureBase();
|
||||
if (summoner)
|
||||
summoner.GetAI().DoAction(ActionIds.WatcherEngaged);
|
||||
}
|
||||
}
|
||||
|
||||
if (me.HasReactState(ReactStates.Passive))
|
||||
{
|
||||
List<Creature> others = new List<Creature>();
|
||||
me.GetCreatureListWithEntryInGrid(others, 0, 40.0f);
|
||||
foreach (Creature other in others)
|
||||
{
|
||||
if (other.GetAI().GetData(Misc.DataPetGroup) == _petGroup)
|
||||
{
|
||||
other.SetReactState(ReactStates.Aggressive);
|
||||
other.GetAI().AttackStart(who);
|
||||
}
|
||||
}
|
||||
|
||||
TempSummon meSummon = me.ToTempSummon();
|
||||
if (meSummon)
|
||||
{
|
||||
Creature summoner = meSummon.GetSummonerCreatureBase();
|
||||
if (summoner)
|
||||
summoner.GetAI().DoAction(ActionIds.PetEngaged);
|
||||
}
|
||||
}
|
||||
_EnterCombat();
|
||||
base.EnterCombat(who);
|
||||
}
|
||||
|
||||
public override void SetData(uint data, uint value)
|
||||
{
|
||||
if (data == Misc.DataPetGroup)
|
||||
{
|
||||
_petGroup = value;
|
||||
me.SetReactState(_petGroup != 0 ? ReactStates.Passive : ReactStates.Aggressive);
|
||||
}
|
||||
}
|
||||
|
||||
public override uint GetData(uint data)
|
||||
{
|
||||
if (data == Misc.DataPetGroup)
|
||||
return _petGroup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
if (!me.HasReactState(ReactStates.Passive))
|
||||
{
|
||||
base.MoveInLineOfSight(who);
|
||||
return;
|
||||
}
|
||||
|
||||
if (me.CanStartAttack(who, false) && me.IsWithinDistInMap(who, me.GetAttackDistance(who) + me.m_CombatDistance))
|
||||
EnterCombat(who);
|
||||
}
|
||||
|
||||
public override void SpellHit(Unit whose, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id == SpellIds.SubbossAggroTrigger)
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
TempSummon meSummon = me.ToTempSummon();
|
||||
if (meSummon)
|
||||
{
|
||||
Creature summoner = meSummon.GetSummonerCreatureBase();
|
||||
if (summoner)
|
||||
summoner.GetAI().DoAction(ActionIds.PetEvade);
|
||||
else
|
||||
me.DespawnOrUnsummon();
|
||||
return;
|
||||
}
|
||||
base.EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
protected InstanceScript _instance;
|
||||
uint _petGroup;
|
||||
bool _isWatcher;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_watcher_gashra : npc_gatewatcher_petAI
|
||||
{
|
||||
public npc_watcher_gashra(Creature creature) : base(creature, true)
|
||||
{
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
DoCastSelf(SpellIds.Enrage);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(20));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(19), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.WebWrap);
|
||||
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(19));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(11), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.InfectedBite);
|
||||
task.Repeat(TimeSpan.FromSeconds(23), TimeSpan.FromSeconds(27));
|
||||
});
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Creature krikthir = _instance.GetCreature(ANDataTypes.KrikthirTheGatewatcher);
|
||||
if (krikthir && krikthir.IsAlive())
|
||||
krikthir.GetAI().DoAction(ActionIds.GashraDied);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_watcher_narjil : npc_gatewatcher_petAI
|
||||
{
|
||||
public npc_watcher_narjil(Creature creature) : base(creature, true) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(18), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.BlindingWebs);
|
||||
task.Repeat(TimeSpan.FromSeconds(23), TimeSpan.FromSeconds(27));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.WebWrap);
|
||||
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(19));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(11), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.InfectedBite);
|
||||
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25));
|
||||
});
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Creature krikthir = _instance.GetCreature(ANDataTypes.KrikthirTheGatewatcher);
|
||||
if (krikthir && krikthir.IsAlive())
|
||||
krikthir.GetAI().DoAction(ActionIds.NarjilDied);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_watcher_silthik : npc_gatewatcher_petAI
|
||||
{
|
||||
public npc_watcher_silthik(Creature creature) : base(creature, true) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(19), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.PoisonSpray);
|
||||
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(19));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(11), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.WebWrap);
|
||||
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(17));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.InfectedBite);
|
||||
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(24));
|
||||
});
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Creature krikthir = _instance.GetCreature(ANDataTypes.KrikthirTheGatewatcher);
|
||||
if (krikthir && krikthir.IsAlive())
|
||||
krikthir.GetAI().DoAction(ActionIds.SilthikDied);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_warrior : npc_gatewatcher_petAI
|
||||
{
|
||||
public npc_anub_ar_warrior(Creature creature) : base(creature, false) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(9), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Cleave);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(16));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Strike);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_skirmisher : npc_gatewatcher_petAI
|
||||
{
|
||||
public npc_anub_ar_skirmisher(Creature creature) : base(creature, false) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Charge);
|
||||
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(9), task =>
|
||||
{
|
||||
if (me.GetVictim() && me.GetVictim().isInBack(me))
|
||||
DoCastVictim(SpellIds.Backstab);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(13));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void SpellHitTarget(Unit target, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id == SpellIds.Charge && target)
|
||||
DoCast(target, SpellIds.FixtateTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_shadowcaster : npc_gatewatcher_petAI
|
||||
{
|
||||
public npc_anub_ar_shadowcaster(Creature creature) : base(creature, false) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.ShadowBolt);
|
||||
task.Repeat(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(14), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.ShadowNova);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(16));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_skittering_swarmer : ScriptedAI
|
||||
{
|
||||
public npc_skittering_swarmer(Creature creature) : base(creature) { }
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
base.InitializeAI();
|
||||
Creature gatewatcher = me.GetInstanceScript().GetCreature(ANDataTypes.KrikthirTheGatewatcher);
|
||||
if (gatewatcher)
|
||||
{
|
||||
Unit target = gatewatcher.getAttackerForHelper();
|
||||
if (target)
|
||||
AttackStart(target);
|
||||
gatewatcher.GetAI().JustSummoned(me);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_skittering_infector : ScriptedAI
|
||||
{
|
||||
public npc_skittering_infector(Creature creature) : base(creature) { }
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
base.InitializeAI();
|
||||
Creature gatewatcher = me.GetInstanceScript().GetCreature(ANDataTypes.KrikthirTheGatewatcher);
|
||||
if (gatewatcher)
|
||||
{
|
||||
Unit target = gatewatcher.getAttackerForHelper();
|
||||
if (target)
|
||||
AttackStart(target);
|
||||
gatewatcher.GetAI().JustSummoned(me);
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
DoCastAOE(SpellIds.AcidSplash);
|
||||
base.JustDied(killer);
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_gatewatcher_web_wrap : NullCreatureAI
|
||||
{
|
||||
public npc_gatewatcher_web_wrap(Creature creature) : base(creature) { }
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
TempSummon meSummon = me.ToTempSummon();
|
||||
if (meSummon)
|
||||
{
|
||||
Unit summoner = meSummon.GetSummoner();
|
||||
if (summoner)
|
||||
summoner.RemoveAurasDueToSpell(SpellIds.WebWrapWrapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_gatewatcher_subboss_trigger : SpellScript
|
||||
{
|
||||
void HandleTargets(List<WorldObject> targetList)
|
||||
{
|
||||
// Remove any Watchers that are already in combat
|
||||
foreach (var obj in targetList.ToList())
|
||||
{
|
||||
Creature creature = obj.ToCreature();
|
||||
if (creature)
|
||||
if (creature.IsAlive() && !creature.IsInCombat())
|
||||
continue;
|
||||
|
||||
targetList.Remove(obj);
|
||||
}
|
||||
|
||||
// Default to Krik'thir himself if he isn't engaged
|
||||
WorldObject target = null;
|
||||
if (GetCaster() && !GetCaster().IsInCombat())
|
||||
target = GetCaster();
|
||||
// Unless there are Watchers that aren't engaged yet
|
||||
if (!targetList.Empty())
|
||||
{
|
||||
// If there are, pick one of them at random
|
||||
target = targetList.SelectRandom();
|
||||
}
|
||||
// And hit only that one
|
||||
targetList.Clear();
|
||||
if (target)
|
||||
targetList.Add(target);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(HandleTargets, 0, Targets.UnitSrcAreaEntry));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_anub_ar_skirmisher_fixtate : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.FixtateTriggered);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
target.CastSpell(GetCaster(), SpellIds.FixtateTriggered, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_gatewatcher_web_wrap : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.WebWrapWrapped);
|
||||
}
|
||||
|
||||
void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Expire)
|
||||
return;
|
||||
|
||||
Unit target = GetTarget();
|
||||
if (target)
|
||||
target.CastSpell(target, SpellIds.WebWrapWrapped, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.ModRoot, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_watch_him_die : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_watch_him_die() : base("achievement_watch_him_die") { }
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
InstanceScript instance = target.GetInstanceScript();
|
||||
if (instance == null)
|
||||
return false;
|
||||
|
||||
foreach (uint watcherData in new[] { ANDataTypes.WatcherGashra, ANDataTypes.WatcherNarjil, ANDataTypes.WatcherSilthik })
|
||||
{
|
||||
Creature watcher = instance.GetCreature(watcherData);
|
||||
if (watcher)
|
||||
if (watcher.IsAlive())
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,943 @@
|
||||
/*
|
||||
* 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.Combat;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Northrend.AzjolNerub.AzjolNerub.Nadronox
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
// Hadronox
|
||||
public const uint WebFrontDoors = 53177;
|
||||
public const uint WebSideDoors = 53185;
|
||||
public const uint LeechPoison = 53030;
|
||||
public const uint LeechPoisonHeal = 53800;
|
||||
public const uint AcidCloud = 53400;
|
||||
public const uint WebGrab = 57731;
|
||||
public const uint PierceArmor = 53418;
|
||||
|
||||
// Anub'Ar Opponent Summoning Spells
|
||||
public const uint SummonChampionPeriodic = 53035;
|
||||
public const uint SummonCryptFiendPeriodic = 53037;
|
||||
public const uint SummonNecromancerPeriodic = 53036;
|
||||
public const uint SummonChampionTop = 53064;
|
||||
public const uint SummonCryptFiendTop = 53065;
|
||||
public const uint SummonNecromancerTop = 53066;
|
||||
public const uint SummonChampionBottom = 53090;
|
||||
public const uint SummonCryptFiendBottom = 53091;
|
||||
public const uint SummonNecromancerBottom = 53092;
|
||||
|
||||
// Anub'Ar Crusher
|
||||
public const uint Smash = 53318;
|
||||
public const uint Frenzy = 53801;
|
||||
|
||||
// Anub'Ar Foes - Shared
|
||||
public const uint Taunt = 53798;
|
||||
|
||||
// Anub'Ar Champion
|
||||
public const uint Rend = 59343;
|
||||
public const uint Pummel = 59344;
|
||||
|
||||
// Anub'Ar Crypt Guard
|
||||
public const uint CrushingWebs = 59347;
|
||||
public const uint InfectedWound = 59348;
|
||||
|
||||
// Anub'Ar Necromancer
|
||||
public const uint ShadowBolt = 53333;
|
||||
public const uint AnimateBones1 = 53334;
|
||||
public const uint AnimateBones2 = 53336;
|
||||
}
|
||||
|
||||
enum SummonGroups
|
||||
{
|
||||
Crusher1 = 1,
|
||||
Crusher2 = 2,
|
||||
Crusher3 = 3
|
||||
}
|
||||
|
||||
struct ActionIds
|
||||
{
|
||||
public const int HadronoxMove = 1;
|
||||
public const int CrusherEngaged = 2;
|
||||
public const int PackWalk = 3;
|
||||
}
|
||||
|
||||
struct Data
|
||||
{
|
||||
public const uint CrusherPackId = 1;
|
||||
public const uint HadronoxEnteredCombat = 2;
|
||||
public const uint HadronoxWebbedDoors = 3;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint Crusher = 28922;
|
||||
public const uint WorldtriggerLarge = 23472;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayCrusherAggro = 1;
|
||||
public const uint EmoteCrusherFrenzy = 2;
|
||||
public const uint EmoteHadronoxMove = 1;
|
||||
}
|
||||
|
||||
// Movement IDs used by the permanently spawning Anub'ar opponents - they are done in sequence, as one finishes, the next one starts
|
||||
enum MovementIds
|
||||
{
|
||||
None = 0,
|
||||
Outside,
|
||||
Downstairs,
|
||||
Downstairs2,
|
||||
Hadronox, // this one might have us take a detour to avoid pathfinding "through" the floor...
|
||||
HadronoxReal // while this one will always make us movechase
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public static Position[] hadronoxStep =
|
||||
{
|
||||
new Position(515.5848f, 544.2007f, 673.6272f),
|
||||
new Position(562.191f , 514.068f , 696.4448f),
|
||||
new Position(610.3828f, 518.6407f, 695.9385f),
|
||||
new Position(530.42f , 560.003f, 733.0308f)
|
||||
};
|
||||
|
||||
public static Position[] crusherWaypoints =
|
||||
{
|
||||
new Position(529.6913f, 547.1257f, 731.9155f, 4.799650f),
|
||||
new Position(517.51f , 561.439f , 734.0306f, 4.520403f),
|
||||
new Position(543.414f , 551.728f , 732.0522f, 3.996804f)
|
||||
};
|
||||
|
||||
public static Position[] championWaypoints =
|
||||
{
|
||||
new Position(539.2076f, 549.7539f, 732.8668f, 4.55531f),
|
||||
new Position(527.3098f, 559.5197f, 732.9407f, 4.742493f),
|
||||
new Position()
|
||||
};
|
||||
|
||||
public static Position[] cryptFiendWaypoints =
|
||||
{
|
||||
new Position(520.3911f, 548.7895f, 732.0118f, 5.0091f),
|
||||
new Position(),
|
||||
new Position(550.9611f, 545.1674f, 731.9031f, 3.996804f)
|
||||
};
|
||||
|
||||
public static Position[] necromancerWaypoints =
|
||||
{
|
||||
new Position(),
|
||||
new Position(507.6937f, 563.3471f, 734.8986f, 4.520403f),
|
||||
new Position(535.1049f, 552.8961f, 732.8441f, 3.996804f),
|
||||
};
|
||||
|
||||
public static Position[] initialMoves =
|
||||
{
|
||||
new Position(485.314606f, 611.418640f, 771.428406f),
|
||||
new Position(575.760437f, 611.516418f, 771.427368f),
|
||||
new Position(588.930725f, 598.233276f, 739.142151f)
|
||||
};
|
||||
|
||||
public static Position[] downstairsMoves =
|
||||
{
|
||||
new Position(513.574341f, 587.022156f, 736.229065f),
|
||||
new Position(537.920410f, 580.436157f, 732.796692f),
|
||||
new Position(601.289246f, 583.259644f, 725.443054f),
|
||||
};
|
||||
|
||||
public static Position[] downstairsMoves2 =
|
||||
{
|
||||
new Position(571.498718f, 576.978333f, 727.582947f),
|
||||
new Position(571.498718f, 576.978333f, 727.582947f),
|
||||
new Position()
|
||||
};
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_hadronox : BossAI
|
||||
{
|
||||
public boss_hadronox(Creature creature) : base(creature, ANDataTypes.Hadronox) { }
|
||||
|
||||
bool IsInCombatWithPlayer()
|
||||
{
|
||||
List<HostileReference> refs = me.GetThreatManager().getThreatList();
|
||||
foreach (HostileReference hostileRef in refs)
|
||||
{
|
||||
Unit target = hostileRef.getTarget();
|
||||
if (target)
|
||||
if (target.IsControlledByPlayer())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetStep(byte step)
|
||||
{
|
||||
if (_lastPlayerCombatState)
|
||||
return;
|
||||
|
||||
_step = step;
|
||||
me.SetHomePosition(Misc.hadronoxStep[step]);
|
||||
me.GetMotionMaster().Clear();
|
||||
me.AttackStop();
|
||||
SetCombatMovement(false);
|
||||
me.GetMotionMaster().MovePoint(0, Misc.hadronoxStep[step]);
|
||||
}
|
||||
|
||||
void SummonCrusherPack(SummonGroups group)
|
||||
{
|
||||
List<TempSummon> summoned;
|
||||
me.SummonCreatureGroup((byte)group, out summoned);
|
||||
foreach (TempSummon summon in summoned)
|
||||
{
|
||||
summon.GetAI().SetData(Data.CrusherPackId, (uint)group);
|
||||
summon.GetAI().DoAction(ActionIds.PackWalk);
|
||||
}
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Point)
|
||||
return;
|
||||
SetCombatMovement(true);
|
||||
AttackStart(me.GetVictim());
|
||||
if (_step < Misc.hadronoxStep.Length - 1)
|
||||
return;
|
||||
DoCastAOE(SpellIds.WebFrontDoors);
|
||||
DoCastAOE(SpellIds.WebSideDoors);
|
||||
_doorsWebbed = true;
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
public override uint GetData(uint data)
|
||||
{
|
||||
if (data == Data.HadronoxEnteredCombat)
|
||||
return _enteredCombat ? 1 : 0u;
|
||||
if (data == Data.HadronoxWebbedDoors)
|
||||
return _doorsWebbed ? 1 : 0u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool CanAIAttack(Unit target)
|
||||
{
|
||||
// Prevent Hadronox from going too far from her current home position
|
||||
if (!target.IsControlledByPlayer() && target.GetDistance(me.GetHomePosition()) > 20.0f)
|
||||
return false;
|
||||
return base.CanAIAttack(target);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(7), task =>
|
||||
{
|
||||
DoCastAOE(SpellIds.LeechPoison);
|
||||
task.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(9));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(13), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.AcidCloud);
|
||||
task.Repeat(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(23));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(19), task =>
|
||||
{
|
||||
DoCastAOE(SpellIds.WebGrab);
|
||||
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(7), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.PierceArmor);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(1), task =>
|
||||
{
|
||||
if (IsInCombatWithPlayer() != _lastPlayerCombatState)
|
||||
{
|
||||
_lastPlayerCombatState = !_lastPlayerCombatState;
|
||||
if (_lastPlayerCombatState) // we are now in combat with players
|
||||
{
|
||||
if (!instance.CheckRequiredBosses(ANDataTypes.Hadronox))
|
||||
{
|
||||
EnterEvadeMode(EvadeReason.SequenceBreak);
|
||||
return;
|
||||
}
|
||||
// cancel current point movement if engaged by players
|
||||
if (me.GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Point)
|
||||
{
|
||||
me.GetMotionMaster().Clear();
|
||||
SetCombatMovement(true);
|
||||
AttackStart(me.GetVictim());
|
||||
}
|
||||
}
|
||||
else // we are no longer in combat with players - reset the encounter
|
||||
EnterEvadeMode(EvadeReason.NoHostiles);
|
||||
}
|
||||
task.Repeat(TimeSpan.FromSeconds(1));
|
||||
});
|
||||
|
||||
me.setActive(true);
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ActionIds.CrusherEngaged:
|
||||
if (_enteredCombat)
|
||||
break;
|
||||
instance.SetBossState(ANDataTypes.Hadronox, EncounterState.InProgress);
|
||||
_enteredCombat = true;
|
||||
SummonCrusherPack(SummonGroups.Crusher2);
|
||||
SummonCrusherPack(SummonGroups.Crusher3);
|
||||
break;
|
||||
case ActionIds.HadronoxMove:
|
||||
if (_step < Misc.hadronoxStep.Length - 1)
|
||||
{
|
||||
SetStep((byte)(_step + 1));
|
||||
Talk(TextIds.EmoteHadronoxMove);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
List<Creature> triggers = new List<Creature>();
|
||||
me.GetCreatureListWithEntryInGrid(triggers, CreatureIds.WorldtriggerLarge);
|
||||
foreach (Creature trigger in triggers)
|
||||
{
|
||||
if (trigger.HasAura(SpellIds.SummonChampionPeriodic) || trigger.HasAura(SpellIds.WebFrontDoors) || trigger.HasAura(SpellIds.WebSideDoors))
|
||||
_DespawnAtEvade(25, trigger);
|
||||
}
|
||||
_DespawnAtEvade(25);
|
||||
summons.DespawnAll();
|
||||
foreach (ObjectGuid gNerubian in _anubar)
|
||||
{
|
||||
Creature nerubian = ObjectAccessor.GetCreature(me, gNerubian);
|
||||
if (nerubian)
|
||||
nerubian.DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetGUID(ObjectGuid guid, int what)
|
||||
{
|
||||
_anubar.Add(guid);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
me.SetFloatValue(UnitFields.BoundingRadius, 9.0f);
|
||||
me.SetFloatValue(UnitFields.CombatReach, 9.0f);
|
||||
_enteredCombat = false;
|
||||
_doorsWebbed = false;
|
||||
_lastPlayerCombatState = false;
|
||||
SetStep(0);
|
||||
SetCombatMovement(true);
|
||||
SummonCrusherPack(SummonGroups.Crusher1);
|
||||
}
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
base.InitializeAI();
|
||||
if (me.IsAlive())
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void JustRespawned()
|
||||
{
|
||||
base.JustRespawned();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
// Safeguard to prevent Hadronox dying to NPCs
|
||||
public override void DamageTaken(Unit who, ref uint damage)
|
||||
{
|
||||
if (!who.IsControlledByPlayer() && me.HealthBelowPct(70))
|
||||
{
|
||||
if (me.HealthBelowPctDamaged(5, damage))
|
||||
damage = 0;
|
||||
else
|
||||
damage *= (uint)((me.GetHealthPct() - 5.0f) / 65.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
// Do not enter combat with zone
|
||||
}
|
||||
|
||||
bool _enteredCombat; // has a player entered combat with the first crusher pack? (talk and spawn two more packs)
|
||||
bool _doorsWebbed; // obvious - have we reached the top and webbed the doors shut? (trigger for hadronox denied achievement)
|
||||
bool _lastPlayerCombatState; // was there a player in our threat list the last time we checked (we check every second)
|
||||
byte _step;
|
||||
List<ObjectGuid> _anubar = new List<ObjectGuid>();
|
||||
}
|
||||
|
||||
class npc_hadronox_crusherPackAI : ScriptedAI
|
||||
{
|
||||
public npc_hadronox_crusherPackAI(Creature creature, Position[] positions) : base(creature)
|
||||
{
|
||||
_instance = creature.GetInstanceScript();
|
||||
_positions = positions;
|
||||
_myPack = 0;
|
||||
_doFacing = false;
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
if (action == ActionIds.PackWalk)
|
||||
{
|
||||
switch (_myPack)
|
||||
{
|
||||
case SummonGroups.Crusher1:
|
||||
case SummonGroups.Crusher2:
|
||||
case SummonGroups.Crusher3:
|
||||
me.GetMotionMaster().MovePoint(ActionIds.PackWalk, _positions[_myPack - SummonGroups.Crusher1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type == MovementGeneratorType.Point && id == ActionIds.PackWalk)
|
||||
_doFacing = true;
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
|
||||
if (hadronox)
|
||||
hadronox.GetAI().EnterEvadeMode(EvadeReason.Other);
|
||||
}
|
||||
|
||||
public override uint GetData(uint data)
|
||||
{
|
||||
if (data == Data.CrusherPackId)
|
||||
return (uint)_myPack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void SetData(uint data, uint value)
|
||||
{
|
||||
if (data == Data.CrusherPackId)
|
||||
{
|
||||
_myPack = (SummonGroups)value;
|
||||
me.SetReactState(_myPack != 0 ? ReactStates.Passive : ReactStates.Aggressive);
|
||||
}
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
if (me.HasReactState(ReactStates.Passive))
|
||||
{
|
||||
List<Creature> others = new List<Creature>();
|
||||
me.GetCreatureListWithEntryInGrid(others, 0, 40.0f);
|
||||
foreach (Creature other in others)
|
||||
{
|
||||
if (other.GetAI().GetData(Data.CrusherPackId) == (uint)_myPack)
|
||||
{
|
||||
other.SetReactState(ReactStates.Aggressive);
|
||||
other.GetAI().AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
_EnterCombat();
|
||||
base.EnterCombat(who);
|
||||
}
|
||||
|
||||
public virtual void _EnterCombat() { }
|
||||
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
if (!me.HasReactState(ReactStates.Passive))
|
||||
{
|
||||
base.MoveInLineOfSight(who);
|
||||
return;
|
||||
}
|
||||
|
||||
if (me.CanStartAttack(who, false) && me.IsWithinDistInMap(who, me.GetAttackDistance(who) + me.m_CombatDistance))
|
||||
EnterCombat(who);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (_doFacing)
|
||||
{
|
||||
_doFacing = false;
|
||||
me.SetFacingTo(_positions[_myPack - SummonGroups.Crusher1].GetOrientation());
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
protected InstanceScript _instance;
|
||||
Position[] _positions;
|
||||
protected SummonGroups _myPack;
|
||||
bool _doFacing;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_crusher : npc_hadronox_crusherPackAI
|
||||
{
|
||||
public npc_anub_ar_crusher(Creature creature) : base(creature, Misc.crusherWaypoints) { }
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Smash);
|
||||
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(21));
|
||||
});
|
||||
|
||||
if (_myPack != SummonGroups.Crusher1)
|
||||
return;
|
||||
|
||||
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
|
||||
if (hadronox)
|
||||
{
|
||||
if (hadronox.GetAI().GetData(Data.HadronoxEnteredCombat) != 0)
|
||||
return;
|
||||
hadronox.GetAI().DoAction(ActionIds.CrusherEngaged);
|
||||
}
|
||||
|
||||
Talk(TextIds.SayCrusherAggro);
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit source, ref uint damage)
|
||||
{
|
||||
if (_hadFrenzy || !me.HealthBelowPctDamaged(25, damage))
|
||||
return;
|
||||
_hadFrenzy = true;
|
||||
Talk(TextIds.EmoteCrusherFrenzy);
|
||||
DoCastSelf(SpellIds.Frenzy);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
|
||||
if (hadronox)
|
||||
hadronox.GetAI().DoAction(ActionIds.HadronoxMove);
|
||||
base.JustDied(killer);
|
||||
}
|
||||
|
||||
bool _hadFrenzy;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_crusher_champion : npc_hadronox_crusherPackAI
|
||||
{
|
||||
public npc_anub_ar_crusher_champion(Creature creature) : base(creature, Misc.championWaypoints) { }
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Rend);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Pummel);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(17));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_crusher_crypt_fiend : npc_hadronox_crusherPackAI
|
||||
{
|
||||
public npc_anub_ar_crusher_crypt_fiend(Creature creature) : base(creature, Misc.cryptFiendWaypoints) { }
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.CrushingWebs);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.InfectedWound);
|
||||
task.Repeat(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(25));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_crusher_necromancer : npc_hadronox_crusherPackAI
|
||||
{
|
||||
public npc_anub_ar_crusher_necromancer(Creature creature) : base(creature, Misc.necromancerWaypoints) { }
|
||||
|
||||
public override void _EnterCombat()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.ShadowBolt);
|
||||
task.Repeat(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(37), TimeSpan.FromSeconds(45), task =>
|
||||
{
|
||||
DoCastVictim(RandomHelper.URand(0, 1) != 0 ? SpellIds.AnimateBones2 : SpellIds.AnimateBones1);
|
||||
task.Repeat(TimeSpan.FromSeconds(35), TimeSpan.FromSeconds(50));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class npc_hadronox_foeAI : ScriptedAI
|
||||
{
|
||||
public npc_hadronox_foeAI(Creature creature) : base(creature)
|
||||
{
|
||||
_instance = creature.GetInstanceScript();
|
||||
_nextMovement = MovementIds.Outside;
|
||||
_mySpawn = 0;
|
||||
}
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
base.InitializeAI();
|
||||
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
|
||||
if (hadronox)
|
||||
hadronox.GetAI().SetGUID(me.GetGUID());
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type == MovementGeneratorType.Point)
|
||||
_nextMovement = (MovementIds)(id + 1);
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (_nextMovement != 0)
|
||||
{
|
||||
switch (_nextMovement)
|
||||
{
|
||||
case MovementIds.Outside:
|
||||
{
|
||||
float dist = float.PositiveInfinity;
|
||||
for (byte spawn = 0; spawn < Misc.initialMoves.Length; ++spawn)
|
||||
{
|
||||
float thisDist = Misc.initialMoves[spawn].GetExactDistSq(me);
|
||||
if (thisDist < dist)
|
||||
{
|
||||
_mySpawn = spawn;
|
||||
dist = thisDist;
|
||||
}
|
||||
}
|
||||
me.GetMotionMaster().MovePoint((uint)MovementIds.Outside, Misc.initialMoves[_mySpawn], false); // do not pathfind here, we have to pass through a "wall" of webbing
|
||||
break;
|
||||
}
|
||||
case MovementIds.Downstairs:
|
||||
me.GetMotionMaster().MovePoint((uint)MovementIds.Downstairs, Misc.downstairsMoves[_mySpawn]);
|
||||
break;
|
||||
case MovementIds.Downstairs2:
|
||||
if (Misc.downstairsMoves2[_mySpawn].GetPositionX() > 0.0f) // might be unset for this spawn - if yes, skip
|
||||
{
|
||||
me.GetMotionMaster().MovePoint((uint)MovementIds.Downstairs2, Misc.downstairsMoves2[_mySpawn]);
|
||||
break;
|
||||
}
|
||||
goto case MovementIds.Hadronox;
|
||||
// intentional missing break
|
||||
case MovementIds.Hadronox:
|
||||
case MovementIds.HadronoxReal:
|
||||
{
|
||||
float zCutoff = 702.0f;
|
||||
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
|
||||
if (hadronox && hadronox.IsAlive())
|
||||
{
|
||||
if (_nextMovement != MovementIds.HadronoxReal)
|
||||
{
|
||||
if (hadronox.GetPositionZ() < zCutoff)
|
||||
{
|
||||
me.GetMotionMaster().MovePoint((uint)MovementIds.Hadronox, Misc.hadronoxStep[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
AttackStart(hadronox);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_nextMovement = MovementIds.None;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
InstanceScript _instance;
|
||||
|
||||
MovementIds _nextMovement;
|
||||
byte _mySpawn;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_champion : npc_hadronox_foeAI
|
||||
{
|
||||
public npc_anub_ar_champion(Creature creature) : base(creature) { }
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Rend);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Pummel);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(17));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Taunt);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_crypt_fiend : npc_hadronox_foeAI
|
||||
{
|
||||
public npc_anub_ar_crypt_fiend(Creature creature) : base(creature) { }
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.CrushingWebs);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.InfectedWound);
|
||||
task.Repeat(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(25));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Taunt);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_anub_ar_necromancer : npc_hadronox_foeAI
|
||||
{
|
||||
public npc_anub_ar_necromancer(Creature creature) : base(creature) { }
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.ShadowBolt);
|
||||
task.Repeat(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(37), TimeSpan.FromSeconds(45), task =>
|
||||
{
|
||||
DoCastVictim(RandomHelper.URand(0, 1) != 0 ? SpellIds.AnimateBones2 : SpellIds.AnimateBones1);
|
||||
task.Repeat(TimeSpan.FromSeconds(35), TimeSpan.FromSeconds(50));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Taunt);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Script("spell_hadronox_periodic_summon_champion", SpellIds.SummonChampionTop, SpellIds.SummonChampionBottom)]
|
||||
[Script("spell_hadronox_periodic_summon_crypt_fiend", SpellIds.SummonCryptFiendTop, SpellIds.SummonCryptFiendBottom)]
|
||||
[Script("spell_hadronox_periodic_summon_necromancer", SpellIds.SummonNecromancerTop, SpellIds.SummonNecromancerBottom)]
|
||||
class spell_hadronox_periodic_summon_template : AuraScript
|
||||
{
|
||||
public spell_hadronox_periodic_summon_template(uint topSpellId, uint bottomSpellId) : base()
|
||||
{
|
||||
_topSpellId = topSpellId;
|
||||
_bottomSpellId = bottomSpellId;
|
||||
}
|
||||
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(_topSpellId, _bottomSpellId);
|
||||
}
|
||||
|
||||
void HandleApply(AuraEffect eff, AuraEffectHandleModes mode)
|
||||
{
|
||||
AuraEffect effect = GetAura().GetEffect(0);
|
||||
if (effect != null)
|
||||
effect.SetPeriodicTimer(RandomHelper.IRand(2, 17) * Time.InMilliseconds);
|
||||
}
|
||||
|
||||
void HandlePeriodic(AuraEffect eff)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
InstanceScript instance = caster.GetInstanceScript();
|
||||
if (instance == null)
|
||||
return;
|
||||
if (instance.GetBossState(ANDataTypes.Hadronox) == EncounterState.Done)
|
||||
GetAura().Remove();
|
||||
else
|
||||
{
|
||||
if (caster.GetPositionZ() >= 750.0f)
|
||||
caster.CastSpell(caster, _topSpellId, true);
|
||||
else
|
||||
caster.CastSpell(caster, _bottomSpellId, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(HandleApply, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.Real));
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodic, 0, AuraType.PeriodicDummy));
|
||||
}
|
||||
|
||||
uint _topSpellId;
|
||||
uint _bottomSpellId;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_hadronox_leeching_poison : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LeechPoisonHeal);
|
||||
}
|
||||
|
||||
void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.ByDeath)
|
||||
return;
|
||||
|
||||
if (GetTarget().IsGuardian())
|
||||
return;
|
||||
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
caster.CastSpell(caster, SpellIds.LeechPoisonHeal, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.PeriodicLeech, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_hadronox_web_doors : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SummonChampionPeriodic, SpellIds.SummonCryptFiendPeriodic, SpellIds.SummonNecromancerPeriodic);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
{
|
||||
target.RemoveAurasDueToSpell(SpellIds.SummonChampionPeriodic);
|
||||
target.RemoveAurasDueToSpell(SpellIds.SummonCryptFiendPeriodic);
|
||||
target.RemoveAurasDueToSpell(SpellIds.SummonNecromancerPeriodic);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.ApplyAura));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_hadronox_denied : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_hadronox_denied() : base("achievement_hadronox_denied") { }
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Creature cTarget = target.ToCreature();
|
||||
if (cTarget)
|
||||
if (cTarget.GetAI().GetData(Data.HadronoxWebbedDoors) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
|
||||
namespace Scripts.Northrend.AzjolNerub.AzjolNerub
|
||||
{
|
||||
struct ANDataTypes
|
||||
{
|
||||
// Encounter States/Boss Guids
|
||||
public const uint KrikthirTheGatewatcher = 0;
|
||||
public const uint Hadronox = 1;
|
||||
public const uint Anubarak = 2;
|
||||
|
||||
// Additional Data
|
||||
public const uint WatcherNarjil = 3;
|
||||
public const uint WatcherGashra = 4;
|
||||
public const uint WatcherSilthik = 5;
|
||||
public const uint AnubarakWall = 6;
|
||||
public const uint AnubarakWall2 = 7;
|
||||
}
|
||||
|
||||
struct ANCreatureIds
|
||||
{
|
||||
public const uint Krikthir = 28684;
|
||||
public const uint Hadronox = 28921;
|
||||
public const uint Anubarak = 29120;
|
||||
|
||||
public const uint WatcherNarjil = 28729;
|
||||
public const uint WatcherGashra = 28730;
|
||||
public const uint WatcherSilthik = 28731;
|
||||
}
|
||||
|
||||
struct ANGameObjectIds
|
||||
{
|
||||
public const uint KrikthirDoor = 192395;
|
||||
public const uint AnubarakDoor1 = 192396;
|
||||
public const uint AnubarakDoor2 = 192397;
|
||||
public const uint AnubarakDoor3 = 192398;
|
||||
}
|
||||
|
||||
// These are passed as -action to AI's DoAction to differentiate between them and boss scripts' own actions
|
||||
struct ANInstanceMisc
|
||||
{
|
||||
public const string DataHeader = "AN";
|
||||
public const uint EncounterCount = 3;
|
||||
|
||||
public const int ActionGatewatcherGreet = 1;
|
||||
|
||||
public static DoorData[] doorData =
|
||||
{
|
||||
new DoorData(ANGameObjectIds.KrikthirDoor, ANDataTypes.KrikthirTheGatewatcher, DoorType.Passage),
|
||||
new DoorData(ANGameObjectIds.AnubarakDoor1, ANDataTypes.Anubarak, DoorType.Room ),
|
||||
new DoorData(ANGameObjectIds.AnubarakDoor2, ANDataTypes.Anubarak, DoorType.Room ),
|
||||
new DoorData(ANGameObjectIds.AnubarakDoor3, ANDataTypes.Anubarak, DoorType.Room )
|
||||
};
|
||||
|
||||
public static ObjectData[] creatureData =
|
||||
{
|
||||
new ObjectData(ANCreatureIds.Krikthir, ANDataTypes.KrikthirTheGatewatcher ),
|
||||
new ObjectData(ANCreatureIds.Hadronox, ANDataTypes.Hadronox ),
|
||||
new ObjectData(ANCreatureIds.Anubarak, ANDataTypes.Anubarak ),
|
||||
new ObjectData(ANCreatureIds.WatcherNarjil, ANDataTypes.WatcherGashra ),
|
||||
new ObjectData(ANCreatureIds.WatcherGashra, ANDataTypes.WatcherSilthik ),
|
||||
new ObjectData(ANCreatureIds.WatcherSilthik, ANDataTypes.WatcherNarjil )
|
||||
};
|
||||
|
||||
public static ObjectData[] gameobjectData =
|
||||
{
|
||||
new ObjectData(ANGameObjectIds.AnubarakDoor1, ANDataTypes.AnubarakWall),
|
||||
new ObjectData(ANGameObjectIds.AnubarakDoor3, ANDataTypes.AnubarakWall2)
|
||||
};
|
||||
|
||||
public static BossBoundaryEntry[] boundaries =
|
||||
{
|
||||
new BossBoundaryEntry(ANDataTypes.KrikthirTheGatewatcher, new RectangleBoundary(400.0f, 580.0f, 623.5f, 810.0f)),
|
||||
new BossBoundaryEntry(ANDataTypes.Hadronox, new ZRangeBoundary(666.0f, 776.0f)),
|
||||
new BossBoundaryEntry(ANDataTypes.Anubarak, new CircleBoundary(new Position(550.6178f, 253.5917f), 26.0f))
|
||||
};
|
||||
}
|
||||
|
||||
[Script]
|
||||
class instance_azjol_nerub : InstanceMapScript
|
||||
{
|
||||
public instance_azjol_nerub() : base(nameof(instance_azjol_nerub), 601) { }
|
||||
|
||||
class instance_azjol_nerub_InstanceScript : InstanceScript
|
||||
{
|
||||
public instance_azjol_nerub_InstanceScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders(ANInstanceMisc.DataHeader);
|
||||
SetBossNumber(ANInstanceMisc.EncounterCount);
|
||||
LoadBossBoundaries(ANInstanceMisc.boundaries);
|
||||
LoadDoorData(ANInstanceMisc.doorData);
|
||||
LoadObjectData(ANInstanceMisc.creatureData, ANInstanceMisc.gameobjectData);
|
||||
}
|
||||
|
||||
public override void OnUnitDeath(Unit who)
|
||||
{
|
||||
base.OnUnitDeath(who);
|
||||
Creature creature = who.ToCreature();
|
||||
if (!creature || creature.IsCritter() || creature.IsControlledByPlayer())
|
||||
return;
|
||||
|
||||
Creature gatewatcher = GetCreature(ANDataTypes.KrikthirTheGatewatcher);
|
||||
if (gatewatcher)
|
||||
gatewatcher.GetAI().DoAction(-ANInstanceMisc.ActionGatewatcherGreet);
|
||||
}
|
||||
|
||||
public override bool CheckRequiredBosses(uint bossId, Player player)
|
||||
{
|
||||
if (_SkipCheckRequiredBosses(player))
|
||||
return true;
|
||||
|
||||
if (bossId > ANDataTypes.KrikthirTheGatewatcher && GetBossState(ANDataTypes.KrikthirTheGatewatcher) != EncounterState.Done)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_azjol_nerub_InstanceScript(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,650 @@
|
||||
/*
|
||||
* 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 Framework.Dynamic;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheChampion
|
||||
{
|
||||
struct TrialOfChampionSpells
|
||||
{
|
||||
//Vehicle
|
||||
public const uint CHARGE = 63010;
|
||||
public const uint SHIELD_BREAKER = 68504;
|
||||
public const uint SHIELD = 66482;
|
||||
|
||||
// Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
|
||||
public const uint MORTAL_STRIKE = 68783;
|
||||
public const uint MORTAL_STRIKE_H = 68784;
|
||||
public const uint BLADESTORM = 63784;
|
||||
public const uint INTERCEPT = 67540;
|
||||
public const uint ROLLING_THROW = 47115; //not implemented in the AI yet...
|
||||
|
||||
// Ambrose Boltspark && Eressea Dawnsinger || Mage
|
||||
public const uint FIREBALL = 66042;
|
||||
public const uint FIREBALL_H = 68310;
|
||||
public const uint BLAST_WAVE = 66044;
|
||||
public const uint BLAST_WAVE_H = 68312;
|
||||
public const uint HASTE = 66045;
|
||||
public const uint POLYMORPH = 66043;
|
||||
public const uint POLYMORPH_H = 68311;
|
||||
|
||||
// Colosos && Runok Wildmane || Shaman
|
||||
public const uint CHAIN_LIGHTNING = 67529;
|
||||
public const uint CHAIN_LIGHTNING_H = 68319;
|
||||
public const uint EARTH_SHIELD = 67530;
|
||||
public const uint HEALING_WAVE = 67528;
|
||||
public const uint HEALING_WAVE_H = 68318;
|
||||
public const uint HEX_OF_MENDING = 67534;
|
||||
|
||||
// Jaelyne Evensong && Zul'tore || Hunter
|
||||
public const uint DISENGAGE = 68340; //not implemented in the AI yet...
|
||||
public const uint LIGHTNING_ARROWS = 66083;
|
||||
public const uint MULTI_SHOT = 66081;
|
||||
public const uint SHOOT = 65868;
|
||||
public const uint SHOOT_H = 67988;
|
||||
|
||||
// Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
|
||||
public const uint EVISCERATE = 67709;
|
||||
public const uint EVISCERATE_H = 68317;
|
||||
public const uint FAN_OF_KNIVES = 67706;
|
||||
public const uint POISON_BOTTLE = 67701;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class generic_vehicleAI_toc5 : npc_escortAI
|
||||
{
|
||||
public generic_vehicleAI_toc5(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
SetDespawnAtEnd(false);
|
||||
uiWaypointPath = 0;
|
||||
|
||||
instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiChargeTimer = 5000;
|
||||
uiShieldBreakerTimer = 8000;
|
||||
uiBuffTimer = RandomHelper.URand(30000, 60000);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void SetData(uint uiType, uint uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case 1:
|
||||
AddWaypoint(0, 747.36f, 634.07f, 411.572f);
|
||||
AddWaypoint(1, 780.43f, 607.15f, 411.82f);
|
||||
AddWaypoint(2, 785.99f, 599.41f, 411.92f);
|
||||
AddWaypoint(3, 778.44f, 601.64f, 411.79f);
|
||||
uiWaypointPath = 1;
|
||||
break;
|
||||
case 2:
|
||||
AddWaypoint(0, 747.35f, 634.07f, 411.57f);
|
||||
AddWaypoint(1, 768.72f, 581.01f, 411.92f);
|
||||
AddWaypoint(2, 763.55f, 590.52f, 411.71f);
|
||||
uiWaypointPath = 2;
|
||||
break;
|
||||
case 3:
|
||||
AddWaypoint(0, 747.35f, 634.07f, 411.57f);
|
||||
AddWaypoint(1, 784.02f, 645.33f, 412.39f);
|
||||
AddWaypoint(2, 775.67f, 641.91f, 411.91f);
|
||||
uiWaypointPath = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uiType <= 3)
|
||||
Start(false, true);
|
||||
}
|
||||
|
||||
public override void WaypointReached(uint waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 2:
|
||||
if (uiWaypointPath == 3 || uiWaypointPath == 2)
|
||||
instance.SetData((uint)Data.DATA_MOVEMENT_DONE, instance.GetData((uint)Data.DATA_MOVEMENT_DONE) + 1);
|
||||
break;
|
||||
case 3:
|
||||
instance.SetData((uint)Data.DATA_MOVEMENT_DONE, instance.GetData((uint)Data.DATA_MOVEMENT_DONE) + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
DoCastSpellShield();
|
||||
}
|
||||
|
||||
void DoCastSpellShield()
|
||||
{
|
||||
for (byte i = 0; i < 3; ++i)
|
||||
DoCast(me, TrialOfChampionSpells.SHIELD, true);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint uiDiff)
|
||||
{
|
||||
base.UpdateAI(uiDiff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiBuffTimer <= uiDiff)
|
||||
{
|
||||
if (!me.HasAura(TrialOfChampionSpells.SHIELD))
|
||||
DoCastSpellShield();
|
||||
|
||||
uiBuffTimer = RandomHelper.URand(30000, 45000);
|
||||
}
|
||||
else
|
||||
uiBuffTimer -= uiDiff;
|
||||
|
||||
if (uiChargeTimer <= uiDiff)
|
||||
{
|
||||
var players = me.GetMap().GetPlayers();
|
||||
if (!players.Empty())
|
||||
{
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player && !player.IsGameMaster() && me.IsInRange(player, 8.0f, 25.0f, false))
|
||||
{
|
||||
DoResetThreat();
|
||||
me.AddThreat(player, 1.0f);
|
||||
DoCast(player, TrialOfChampionSpells.CHARGE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
uiChargeTimer = 5000;
|
||||
}
|
||||
else
|
||||
uiChargeTimer -= uiDiff;
|
||||
|
||||
//dosen't work at all
|
||||
if (uiShieldBreakerTimer <= uiDiff)
|
||||
{
|
||||
Vehicle pVehicle = me.GetVehicleKit();
|
||||
if (!pVehicle)
|
||||
return;
|
||||
|
||||
Unit pPassenger = pVehicle.GetPassenger(0);
|
||||
if (pPassenger)
|
||||
{
|
||||
var players = me.GetMap().GetPlayers();
|
||||
if (!players.Empty())
|
||||
{
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player && !player.IsGameMaster() && me.IsInRange(player, 10.0f, 30.0f, false))
|
||||
{
|
||||
pPassenger.CastSpell(player, TrialOfChampionSpells.SHIELD_BREAKER, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
uiShieldBreakerTimer = 7000;
|
||||
}
|
||||
else
|
||||
uiShieldBreakerTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
uint uiChargeTimer;
|
||||
uint uiShieldBreakerTimer;
|
||||
uint uiBuffTimer;
|
||||
|
||||
uint uiWaypointPath;
|
||||
}
|
||||
|
||||
abstract class boss_basic_toc5AI : ScriptedAI
|
||||
{
|
||||
public boss_basic_toc5AI(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature.GetInstanceScript();
|
||||
|
||||
bDone = false;
|
||||
bHome = false;
|
||||
|
||||
uiPhase = 0;
|
||||
uiPhaseTimer = 0;
|
||||
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
// THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.ImmuneToPc);
|
||||
}
|
||||
|
||||
public abstract void Initialize();
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void JustReachedHome()
|
||||
{
|
||||
base.JustReachedHome();
|
||||
|
||||
if (!bHome)
|
||||
return;
|
||||
|
||||
uiPhaseTimer = 15000;
|
||||
uiPhase = 1;
|
||||
|
||||
bHome = false;
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
instance.SetData((uint)Data.BOSS_GRAND_CHAMPIONS, (uint)EncounterState.Done);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!bDone && GrandChampionsOutVehicle(me))
|
||||
{
|
||||
bDone = true;
|
||||
|
||||
if (me.GetGUID() == instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_1))
|
||||
me.SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
|
||||
else if (me.GetGUID() == instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_2))
|
||||
me.SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
|
||||
else if (me.GetGUID() == instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_3))
|
||||
me.SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
|
||||
|
||||
EnterEvadeMode();
|
||||
bHome = true;
|
||||
}
|
||||
|
||||
if (uiPhaseTimer <= diff)
|
||||
{
|
||||
if (uiPhase == 1)
|
||||
{
|
||||
AggroAllPlayers(me);
|
||||
uiPhase = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
uiPhaseTimer -= diff;
|
||||
}
|
||||
|
||||
public bool InVehicle()
|
||||
{
|
||||
return !me.m_movementInfo.transport.guid.IsEmpty();
|
||||
}
|
||||
|
||||
void AggroAllPlayers(Creature temp)
|
||||
{
|
||||
var PlList = temp.GetMap().GetPlayers();
|
||||
|
||||
if (PlList.Empty())
|
||||
return;
|
||||
|
||||
foreach (var player in PlList)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
if (player.IsGameMaster())
|
||||
continue;
|
||||
|
||||
if (player.IsAlive())
|
||||
{
|
||||
temp.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.ImmuneToPc);
|
||||
temp.SetReactState(ReactStates.Aggressive);
|
||||
temp.SetInCombatWith(player);
|
||||
player.SetInCombatWith(temp);
|
||||
temp.AddThreat(player, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GrandChampionsOutVehicle(Creature me)
|
||||
{
|
||||
InstanceScript instance = me.GetInstanceScript();
|
||||
|
||||
if (instance == null)
|
||||
return false;
|
||||
|
||||
Creature pGrandChampion1 = ObjectAccessor.GetCreature(me, instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_1));
|
||||
Creature pGrandChampion2 = ObjectAccessor.GetCreature(me, instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_2));
|
||||
Creature pGrandChampion3 = ObjectAccessor.GetCreature(me, instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_3));
|
||||
|
||||
if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
|
||||
{
|
||||
if (pGrandChampion1.m_movementInfo.transport.guid.IsEmpty() &&
|
||||
pGrandChampion2.m_movementInfo.transport.guid.IsEmpty() &&
|
||||
pGrandChampion3.m_movementInfo.transport.guid.IsEmpty())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TaskScheduler NonCombatEvents = new TaskScheduler();
|
||||
|
||||
public InstanceScript instance;
|
||||
|
||||
public byte uiPhase;
|
||||
public uint uiPhaseTimer;
|
||||
|
||||
bool bDone;
|
||||
public bool bHome;
|
||||
}
|
||||
|
||||
[Script]
|
||||
// Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
|
||||
class boss_warrior_toc5 : boss_basic_toc5AI
|
||||
{
|
||||
public boss_warrior_toc5(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastVictim(TrialOfChampionSpells.BLADESTORM);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), task =>
|
||||
{
|
||||
var players = me.GetMap().GetPlayers();
|
||||
if (!players.Empty())
|
||||
{
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player && !player.IsGameMaster() && me.IsInRange(player, 8.0f, 25.0f, false))
|
||||
{
|
||||
DoResetThreat();
|
||||
me.AddThreat(player, 5.0f);
|
||||
DoCast(player, TrialOfChampionSpells.INTERCEPT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
task.Repeat(TimeSpan.FromSeconds(7));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
DoCastVictim(TrialOfChampionSpells.MORTAL_STRIKE);
|
||||
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim() || InVehicle())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Script]
|
||||
// Ambrose Boltspark && Eressea Dawnsinger || Mage
|
||||
class boss_mage_toc5 : boss_basic_toc5AI
|
||||
{
|
||||
public boss_mage_toc5(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
DoCastVictim(TrialOfChampionSpells.FIREBALL);
|
||||
task.Repeat(TimeSpan.FromSeconds(5));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, TrialOfChampionSpells.POLYMORPH);
|
||||
task.Repeat(TimeSpan.FromSeconds(8));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
DoCastAOE(TrialOfChampionSpells.BLAST_WAVE, false);
|
||||
task.Repeat(TimeSpan.FromSeconds(13));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(22), task =>
|
||||
{
|
||||
me.InterruptNonMeleeSpells(true);
|
||||
|
||||
DoCast(me, TrialOfChampionSpells.HASTE);
|
||||
task.Repeat(TimeSpan.FromSeconds(22));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim() || InVehicle())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
// Colosos && Runok Wildmane || Shaman
|
||||
class boss_shaman_toc5 : boss_basic_toc5AI
|
||||
{
|
||||
public boss_shaman_toc5(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(16), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, TrialOfChampionSpells.CHAIN_LIGHTNING);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(16));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
bool bChance = RandomHelper.randChance(50);
|
||||
|
||||
if (!bChance)
|
||||
{
|
||||
Unit pFriend = DoSelectLowestHpFriendly(40);
|
||||
if (pFriend)
|
||||
DoCast(pFriend, TrialOfChampionSpells.HEALING_WAVE);
|
||||
}
|
||||
else
|
||||
DoCast(me, TrialOfChampionSpells.HEALING_WAVE);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(12));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35), task =>
|
||||
{
|
||||
DoCast(me, TrialOfChampionSpells.EARTH_SHIELD);
|
||||
task.Repeat(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25), task =>
|
||||
{
|
||||
DoCastVictim(TrialOfChampionSpells.HEX_OF_MENDING, true);
|
||||
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25));
|
||||
});
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
DoCast(me, TrialOfChampionSpells.EARTH_SHIELD);
|
||||
DoCast(who, TrialOfChampionSpells.HEX_OF_MENDING);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim() || InVehicle())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
// Jaelyne Evensong && Zul'tore || Hunter
|
||||
class boss_hunter_toc5 : boss_basic_toc5AI
|
||||
{
|
||||
public boss_hunter_toc5(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), task =>
|
||||
{
|
||||
DoCastAOE(TrialOfChampionSpells.LIGHTNING_ARROWS, false);
|
||||
task.Repeat(TimeSpan.FromSeconds(7));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
ObjectGuid uiTargetGUID = ObjectGuid.Empty;
|
||||
Unit target = SelectTarget(SelectAggroTarget.Farthest, 0, 30.0f);
|
||||
if (target)
|
||||
{
|
||||
uiTargetGUID = target.GetGUID();
|
||||
DoCast(target, TrialOfChampionSpells.SHOOT);
|
||||
}
|
||||
|
||||
bool bShoot = true;
|
||||
task.Repeat(TimeSpan.FromSeconds(12));
|
||||
task.Schedule(TimeSpan.FromSeconds(3), task1 =>
|
||||
{
|
||||
if (bShoot)
|
||||
{
|
||||
me.InterruptNonMeleeSpells(true);
|
||||
|
||||
Unit target1 = Global.ObjAccessor.GetUnit(me, uiTargetGUID);
|
||||
if (target1 && me.IsInRange(target1, 5.0f, 30.0f, false))
|
||||
{
|
||||
DoCast(target1, TrialOfChampionSpells.MULTI_SHOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
var players = me.GetMap().GetPlayers();
|
||||
if (!players.Empty())
|
||||
{
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player && !player.IsGameMaster() && me.IsInRange(player, 5.0f, 30.0f, false))
|
||||
{
|
||||
DoCast(player, TrialOfChampionSpells.MULTI_SHOT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bShoot = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim() || InVehicle())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
// Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
|
||||
class boss_rouge_toc5 : boss_basic_toc5AI
|
||||
{
|
||||
public boss_rouge_toc5(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
DoCastVictim(TrialOfChampionSpells.EVISCERATE);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(8));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(14), task =>
|
||||
{
|
||||
DoCastAOE(TrialOfChampionSpells.FAN_OF_KNIVES, false);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(14));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(19), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, TrialOfChampionSpells.POISON_BOTTLE);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(19));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim() || !me.m_movementInfo.transport.guid.IsEmpty())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
+339
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* 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 Framework.GameMath;
|
||||
using Framework.IO;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Game.AI;
|
||||
|
||||
namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheChampion
|
||||
{
|
||||
[Script]
|
||||
class instance_trial_of_the_champion : InstanceMapScript
|
||||
{
|
||||
public instance_trial_of_the_champion() : base("instance_trial_of_the_champion", 650) { }
|
||||
|
||||
class instance_trial_of_the_champion_InstanceMapScript : InstanceScript
|
||||
{
|
||||
public instance_trial_of_the_champion_InstanceMapScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("TC");
|
||||
uiMovementDone = 0;
|
||||
uiGrandChampionsDeaths = 0;
|
||||
uiArgentSoldierDeaths = 0;
|
||||
|
||||
//bDone = false;
|
||||
}
|
||||
|
||||
public override bool IsEncounterInProgress()
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == EncounterState.InProgress)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
var players = instance.GetPlayers();
|
||||
Team TeamInInstance = 0;
|
||||
|
||||
if (!players.Empty())
|
||||
{
|
||||
Player player = players.First();
|
||||
if (player)
|
||||
TeamInInstance = player.GetTeam();
|
||||
}
|
||||
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
// Champions
|
||||
case VehicleIds.MOKRA_SKILLCRUSHER_MOUNT:
|
||||
if (TeamInInstance == Team.Horde)
|
||||
creature.UpdateEntry(VehicleIds.MARSHAL_JACOB_ALERIUS_MOUNT);
|
||||
break;
|
||||
case VehicleIds.ERESSEA_DAWNSINGER_MOUNT:
|
||||
if (TeamInInstance == Team.Horde)
|
||||
creature.UpdateEntry(VehicleIds.AMBROSE_BOLTSPARK_MOUNT);
|
||||
break;
|
||||
case VehicleIds.RUNOK_WILDMANE_MOUNT:
|
||||
if (TeamInInstance == Team.Horde)
|
||||
creature.UpdateEntry(VehicleIds.COLOSOS_MOUNT);
|
||||
break;
|
||||
case VehicleIds.ZUL_TORE_MOUNT:
|
||||
if (TeamInInstance == Team.Horde)
|
||||
creature.UpdateEntry(VehicleIds.EVENSONG_MOUNT);
|
||||
break;
|
||||
case VehicleIds.DEATHSTALKER_VESCERI_MOUNT:
|
||||
if (TeamInInstance == Team.Horde)
|
||||
creature.UpdateEntry(VehicleIds.LANA_STOUTHAMMER_MOUNT);
|
||||
break;
|
||||
// Coliseum Announcer || Just NPC_JAEREN must be spawned.
|
||||
case CreatureIds.JAEREN:
|
||||
uiAnnouncerGUID = creature.GetGUID();
|
||||
if (TeamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.ARELAS);
|
||||
break;
|
||||
case VehicleIds.ARGENT_WARHORSE:
|
||||
case VehicleIds.ARGENT_BATTLEWORG:
|
||||
VehicleList.Add(creature.GetGUID());
|
||||
break;
|
||||
case CreatureIds.EADRIC:
|
||||
case CreatureIds.PALETRESS:
|
||||
uiArgentChampionGUID = creature.GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GameObjectIds.MAIN_GATE:
|
||||
uiMainGateGUID = go.GetGUID();
|
||||
break;
|
||||
case GameObjectIds.CHAMPIONS_LOOT:
|
||||
case GameObjectIds.CHAMPIONS_LOOT_H:
|
||||
uiChampionLootGUID = go.GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetData(uint uiType, uint uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case (uint)Data.DATA_MOVEMENT_DONE:
|
||||
uiMovementDone = (ushort)uiData;
|
||||
if (uiMovementDone == 3)
|
||||
{
|
||||
Creature pAnnouncer = instance.GetCreature(uiAnnouncerGUID);
|
||||
if (pAnnouncer)
|
||||
pAnnouncer.GetAI().SetData((uint)Data.DATA_IN_POSITION, 0);
|
||||
}
|
||||
break;
|
||||
case (uint)Data.BOSS_GRAND_CHAMPIONS:
|
||||
m_auiEncounter[0] = (EncounterState)uiData;
|
||||
if (uiData == (uint)EncounterState.InProgress)
|
||||
{
|
||||
foreach (var guid in VehicleList)
|
||||
{
|
||||
Creature summon = instance.GetCreature(guid);
|
||||
if (summon)
|
||||
summon.RemoveFromWorld();
|
||||
}
|
||||
}
|
||||
else if (uiData == (uint)EncounterState.Done)
|
||||
{
|
||||
++uiGrandChampionsDeaths;
|
||||
if (uiGrandChampionsDeaths == 3)
|
||||
{
|
||||
Creature pAnnouncer = instance.GetCreature(uiAnnouncerGUID);
|
||||
if (pAnnouncer)
|
||||
{
|
||||
pAnnouncer.GetMotionMaster().MovePoint(0, 748.309f, 619.487f, 411.171f);
|
||||
pAnnouncer.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
pAnnouncer.SummonGameObject(instance.IsHeroic() ? GameObjectIds.CHAMPIONS_LOOT_H : GameObjectIds.CHAMPIONS_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, Quaternion.WAxis, 90000);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (uint)Data.DATA_ARGENT_SOLDIER_DEFEATED:
|
||||
uiArgentSoldierDeaths = (byte)uiData;
|
||||
if (uiArgentSoldierDeaths == 9)
|
||||
{
|
||||
Creature pBoss = instance.GetCreature(uiArgentChampionGUID);
|
||||
if (pBoss)
|
||||
{
|
||||
pBoss.GetMotionMaster().MovePoint(0, 746.88f, 618.74f, 411.06f);
|
||||
pBoss.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
pBoss.SetReactState(ReactStates.Aggressive);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (uint)Data.BOSS_ARGENT_CHALLENGE_E:
|
||||
{
|
||||
m_auiEncounter[1] = (EncounterState)uiData;
|
||||
Creature pAnnouncer = instance.GetCreature(uiAnnouncerGUID);
|
||||
if (pAnnouncer)
|
||||
{
|
||||
pAnnouncer.GetMotionMaster().MovePoint(0, 748.309f, 619.487f, 411.171f);
|
||||
pAnnouncer.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
pAnnouncer.SummonGameObject(instance.IsHeroic() ? GameObjectIds.EADRIC_LOOT_H : GameObjectIds.EADRIC_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, Quaternion.WAxis, 90000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (uint)Data.BOSS_ARGENT_CHALLENGE_P:
|
||||
{
|
||||
m_auiEncounter[2] = (EncounterState)uiData;
|
||||
Creature pAnnouncer = instance.GetCreature(uiAnnouncerGUID);
|
||||
if (pAnnouncer)
|
||||
{
|
||||
pAnnouncer.GetMotionMaster().MovePoint(0, 748.309f, 619.487f, 411.171f);
|
||||
pAnnouncer.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
pAnnouncer.SummonGameObject(instance.IsHeroic() ? GameObjectIds.PALETRESS_LOOT_H : GameObjectIds.PALETRESS_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, Quaternion.WAxis, 90000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (uiData == (uint)EncounterState.Done)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
public override uint GetData(uint uiData)
|
||||
{
|
||||
switch (uiData)
|
||||
{
|
||||
case (uint)Data.BOSS_GRAND_CHAMPIONS:
|
||||
return (uint)m_auiEncounter[0];
|
||||
case (uint)Data.BOSS_ARGENT_CHALLENGE_E:
|
||||
return (uint)m_auiEncounter[1];
|
||||
case (uint)Data.BOSS_ARGENT_CHALLENGE_P:
|
||||
return (uint)m_auiEncounter[2];
|
||||
case (uint)Data.BOSS_BLACK_KNIGHT:
|
||||
return (uint)m_auiEncounter[3];
|
||||
|
||||
case (uint)Data.DATA_MOVEMENT_DONE:
|
||||
return uiMovementDone;
|
||||
case (uint)Data.DATA_ARGENT_SOLDIER_DEFEATED:
|
||||
return uiArgentSoldierDeaths;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint uiData)
|
||||
{
|
||||
switch (uiData)
|
||||
{
|
||||
case (uint)Data64.DATA_ANNOUNCER:
|
||||
return uiAnnouncerGUID;
|
||||
case (uint)Data64.DATA_MAIN_GATE:
|
||||
return uiMainGateGUID;
|
||||
|
||||
case (uint)Data64.DATA_GRAND_CHAMPION_1:
|
||||
return uiGrandChampion1GUID;
|
||||
case (uint)Data64.DATA_GRAND_CHAMPION_2:
|
||||
return uiGrandChampion2GUID;
|
||||
case (uint)Data64.DATA_GRAND_CHAMPION_3:
|
||||
return uiGrandChampion3GUID;
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
public override void SetGuidData(uint uiType, ObjectGuid uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case (uint)Data64.DATA_GRAND_CHAMPION_1:
|
||||
uiGrandChampion1GUID = uiData;
|
||||
break;
|
||||
case (uint)Data64.DATA_GRAND_CHAMPION_2:
|
||||
uiGrandChampion2GUID = uiData;
|
||||
break;
|
||||
case (uint)Data64.DATA_GRAND_CHAMPION_3:
|
||||
uiGrandChampion3GUID = uiData;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA();
|
||||
|
||||
string str_data = string.Format("T C {0} {1} {2} {3} {4} {5}", m_auiEncounter[0], m_auiEncounter[1], m_auiEncounter[2], m_auiEncounter[3], uiGrandChampionsDeaths, uiMovementDone);
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE();
|
||||
return str_data;
|
||||
}
|
||||
|
||||
public override void Load(string str)
|
||||
{
|
||||
if (str.IsEmpty())
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL();
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(str);
|
||||
|
||||
StringArguments loadStream = new StringArguments(str);
|
||||
string dataHead = loadStream.NextString();
|
||||
|
||||
if (dataHead[0] == 'T' && dataHead[1] == 'C')
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
{
|
||||
m_auiEncounter[i] = (EncounterState)loadStream.NextUInt32();
|
||||
if (m_auiEncounter[i] == EncounterState.InProgress)
|
||||
m_auiEncounter[i] = EncounterState.NotStarted;
|
||||
|
||||
}
|
||||
|
||||
uiGrandChampionsDeaths = loadStream.NextUInt16();
|
||||
uiMovementDone = loadStream.NextUInt16();
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL();
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE();
|
||||
}
|
||||
|
||||
EncounterState[] m_auiEncounter = new EncounterState[4];
|
||||
|
||||
ushort uiMovementDone;
|
||||
ushort uiGrandChampionsDeaths;
|
||||
byte uiArgentSoldierDeaths;
|
||||
|
||||
ObjectGuid uiAnnouncerGUID;
|
||||
ObjectGuid uiMainGateGUID;
|
||||
//ObjectGuid uiGrandChampionVehicle1GUID;
|
||||
//ObjectGuid uiGrandChampionVehicle2GUID;
|
||||
//ObjectGuid uiGrandChampionVehicle3GUID;
|
||||
ObjectGuid uiGrandChampion1GUID;
|
||||
ObjectGuid uiGrandChampion2GUID;
|
||||
ObjectGuid uiGrandChampion3GUID;
|
||||
ObjectGuid uiChampionLootGUID;
|
||||
ObjectGuid uiArgentChampionGUID;
|
||||
|
||||
List<ObjectGuid> VehicleList = new List<ObjectGuid>();
|
||||
|
||||
//bool bDone;
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_trial_of_the_champion_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
public static T GetTrialOfTheChampionAI<T>(Creature creature) where T : CreatureAI
|
||||
{
|
||||
return GetInstanceAI<T>(creature, "instance_trial_of_the_champion");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,588 @@
|
||||
/*
|
||||
* 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 System.Collections.Generic;
|
||||
|
||||
|
||||
namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheChampion
|
||||
{
|
||||
struct TrialOfTheChampionConst
|
||||
{
|
||||
public const uint SAY_INTRO_1 = 0;
|
||||
public const uint SAY_INTRO_2 = 1;
|
||||
public const uint SAY_INTRO_3 = 2;
|
||||
public const uint SAY_AGGRO = 3;
|
||||
public const uint SAY_PHASE_2 = 4;
|
||||
public const uint SAY_PHASE_3 = 5;
|
||||
public const uint SAY_KILL_PLAYER = 6;
|
||||
public const uint SAY_DEATH = 7;
|
||||
|
||||
public const string GOSSIP_START_EVENT1 = "I'm ready to start challenge.";
|
||||
public const string GOSSIP_START_EVENT2 = "I'm ready for the next challenge.";
|
||||
}
|
||||
|
||||
enum Data
|
||||
{
|
||||
BOSS_GRAND_CHAMPIONS,
|
||||
BOSS_ARGENT_CHALLENGE_E,
|
||||
BOSS_ARGENT_CHALLENGE_P,
|
||||
BOSS_BLACK_KNIGHT,
|
||||
DATA_MOVEMENT_DONE,
|
||||
DATA_LESSER_CHAMPIONS_DEFEATED,
|
||||
DATA_START,
|
||||
DATA_IN_POSITION,
|
||||
DATA_ARGENT_SOLDIER_DEFEATED
|
||||
};
|
||||
|
||||
enum Data64
|
||||
{
|
||||
DATA_ANNOUNCER,
|
||||
DATA_MAIN_GATE,
|
||||
|
||||
DATA_GRAND_CHAMPION_VEHICLE_1,
|
||||
DATA_GRAND_CHAMPION_VEHICLE_2,
|
||||
DATA_GRAND_CHAMPION_VEHICLE_3,
|
||||
|
||||
DATA_GRAND_CHAMPION_1,
|
||||
DATA_GRAND_CHAMPION_2,
|
||||
DATA_GRAND_CHAMPION_3
|
||||
};
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
// Horde Champions
|
||||
public const uint MOKRA = 35572;
|
||||
public const uint ERESSEA = 35569;
|
||||
public const uint RUNOK = 35571;
|
||||
public const uint ZULTORE = 35570;
|
||||
public const uint VISCERI = 35617;
|
||||
|
||||
// Alliance Champions
|
||||
public const uint JACOB = 34705;
|
||||
public const uint AMBROSE = 34702;
|
||||
public const uint COLOSOS = 34701;
|
||||
public const uint JAELYNE = 34657;
|
||||
public const uint LANA = 34703;
|
||||
|
||||
public const uint EADRIC = 35119;
|
||||
public const uint PALETRESS = 34928;
|
||||
|
||||
public const uint ARGENT_LIGHWIELDER = 35309;
|
||||
public const uint ARGENT_MONK = 35305;
|
||||
public const uint PRIESTESS = 35307;
|
||||
|
||||
public const uint BLACK_KNIGHT = 35451;
|
||||
|
||||
public const uint RISEN_JAEREN = 35545;
|
||||
public const uint RISEN_ARELAS = 35564;
|
||||
|
||||
public const uint JAEREN = 35004;
|
||||
public const uint ARELAS = 35005;
|
||||
}
|
||||
|
||||
struct GameObjectIds
|
||||
{
|
||||
public const uint MAIN_GATE = 195647;
|
||||
|
||||
public const uint CHAMPIONS_LOOT = 195709;
|
||||
public const uint CHAMPIONS_LOOT_H = 195710;
|
||||
|
||||
public const uint EADRIC_LOOT = 195374;
|
||||
public const uint EADRIC_LOOT_H = 195375;
|
||||
|
||||
public const uint PALETRESS_LOOT = 195323;
|
||||
public const uint PALETRESS_LOOT_H = 195324;
|
||||
}
|
||||
|
||||
struct VehicleIds
|
||||
{
|
||||
//Grand Champions Alliance Vehicles
|
||||
public const uint MARSHAL_JACOB_ALERIUS_MOUNT = 35637;
|
||||
public const uint AMBROSE_BOLTSPARK_MOUNT = 35633;
|
||||
public const uint COLOSOS_MOUNT = 35768;
|
||||
public const uint EVENSONG_MOUNT = 34658;
|
||||
public const uint LANA_STOUTHAMMER_MOUNT = 35636;
|
||||
//Faction Champions (ALLIANCE)
|
||||
public const uint DARNASSIA_NIGHTSABER = 33319;
|
||||
public const uint EXODAR_ELEKK = 33318;
|
||||
public const uint STORMWIND_STEED = 33217;
|
||||
public const uint GNOMEREGAN_MECHANOSTRIDER = 33317;
|
||||
public const uint IRONFORGE_RAM = 33316;
|
||||
//Grand Champions Horde Vehicles
|
||||
public const uint MOKRA_SKILLCRUSHER_MOUNT = 35638;
|
||||
public const uint ERESSEA_DAWNSINGER_MOUNT = 35635;
|
||||
public const uint RUNOK_WILDMANE_MOUNT = 35640;
|
||||
public const uint ZUL_TORE_MOUNT = 35641;
|
||||
public const uint DEATHSTALKER_VESCERI_MOUNT = 35634;
|
||||
//Faction Champions (HORDE)
|
||||
public const uint FORSAKE_WARHORSE = 33324;
|
||||
public const uint THUNDER_BLUFF_KODO = 33322;
|
||||
public const uint ORGRIMMAR_WOLF = 33320;
|
||||
public const uint SILVERMOON_HAWKSTRIDER = 33323;
|
||||
public const uint DARKSPEAR_RAPTOR = 33321;
|
||||
|
||||
public const uint ARGENT_WARHORSE = 35644;
|
||||
public const uint ARGENT_BATTLEWORG = 36558;
|
||||
|
||||
public const uint BLACK_KNIGHT = 35491;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_announcer_toc5 : CreatureScript
|
||||
{
|
||||
public npc_announcer_toc5() : base("npc_announcer_toc5") { }
|
||||
|
||||
class npc_announcer_toc5AI : ScriptedAI
|
||||
{
|
||||
public npc_announcer_toc5AI(Creature creature) : base(creature)
|
||||
{
|
||||
instance = creature.GetInstanceScript();
|
||||
|
||||
uiSummonTimes = 0;
|
||||
uiLesserChampions = 0;
|
||||
|
||||
uiFirstBoss = 0;
|
||||
uiSecondBoss = 0;
|
||||
uiThirdBoss = 0;
|
||||
|
||||
uiArgentChampion = 0;
|
||||
|
||||
uiPhase = 0;
|
||||
uiTimer = 0;
|
||||
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
me.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
|
||||
SetGrandChampionsForEncounter();
|
||||
SetArgentChampion();
|
||||
}
|
||||
|
||||
void NextStep(uint uiTimerStep, bool bNextStep = true, byte uiPhaseStep = 0)
|
||||
{
|
||||
uiTimer = uiTimerStep;
|
||||
if (bNextStep)
|
||||
++uiPhase;
|
||||
else
|
||||
uiPhase = uiPhaseStep;
|
||||
}
|
||||
|
||||
public override void SetData(uint uiType, uint uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case (uint)Data.DATA_START:
|
||||
DoSummonGrandChampion(uiFirstBoss);
|
||||
NextStep(10000, false, 1);
|
||||
break;
|
||||
case (uint)Data.DATA_IN_POSITION: //movement EncounterState.Done.
|
||||
me.GetMotionMaster().MovePoint(1, 735.81f, 661.92f, 412.39f);
|
||||
GameObject go = ObjectAccessor.GetGameObject(me, instance.GetGuidData((uint)Data64.DATA_MAIN_GATE));
|
||||
if (go)
|
||||
instance.HandleGameObject(go.GetGUID(), false);
|
||||
NextStep(10000, false, 3);
|
||||
break;
|
||||
case (uint)Data.DATA_LESSER_CHAMPIONS_DEFEATED:
|
||||
{
|
||||
++uiLesserChampions;
|
||||
List<ObjectGuid> TempList = new List<ObjectGuid>();
|
||||
if (uiLesserChampions == 3 || uiLesserChampions == 6)
|
||||
{
|
||||
switch (uiLesserChampions)
|
||||
{
|
||||
case 3:
|
||||
TempList = Champion2List;
|
||||
break;
|
||||
case 6:
|
||||
TempList = Champion3List;
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var guid in TempList)
|
||||
{
|
||||
Creature summon = ObjectAccessor.GetCreature(me, guid);
|
||||
if (summon)
|
||||
AggroAllPlayers(summon);
|
||||
}
|
||||
}
|
||||
else if (uiLesserChampions == 9)
|
||||
StartGrandChampionsAttack();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StartGrandChampionsAttack()
|
||||
{
|
||||
Creature pGrandChampion1 = ObjectAccessor.GetCreature(me, uiVehicle1GUID);
|
||||
Creature pGrandChampion2 = ObjectAccessor.GetCreature(me, uiVehicle2GUID);
|
||||
Creature pGrandChampion3 = ObjectAccessor.GetCreature(me, uiVehicle3GUID);
|
||||
|
||||
if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
|
||||
{
|
||||
AggroAllPlayers(pGrandChampion1);
|
||||
AggroAllPlayers(pGrandChampion2);
|
||||
AggroAllPlayers(pGrandChampion3);
|
||||
}
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType uiType, uint uiPointId)
|
||||
{
|
||||
if (uiType != MovementGeneratorType.Point)
|
||||
return;
|
||||
|
||||
if (uiPointId == 1)
|
||||
me.SetFacingTo(4.714f);
|
||||
}
|
||||
|
||||
void DoSummonGrandChampion(uint uiBoss)
|
||||
{
|
||||
++uiSummonTimes;
|
||||
uint VEHICLE_TO_SUMMON1 = 0;
|
||||
uint VEHICLE_TO_SUMMON2 = 0;
|
||||
switch (uiBoss)
|
||||
{
|
||||
case 0:
|
||||
VEHICLE_TO_SUMMON1 = VehicleIds.MOKRA_SKILLCRUSHER_MOUNT;
|
||||
VEHICLE_TO_SUMMON2 = VehicleIds.ORGRIMMAR_WOLF;
|
||||
break;
|
||||
case 1:
|
||||
VEHICLE_TO_SUMMON1 = VehicleIds.ERESSEA_DAWNSINGER_MOUNT;
|
||||
VEHICLE_TO_SUMMON2 = VehicleIds.SILVERMOON_HAWKSTRIDER;
|
||||
break;
|
||||
case 2:
|
||||
VEHICLE_TO_SUMMON1 = VehicleIds.RUNOK_WILDMANE_MOUNT;
|
||||
VEHICLE_TO_SUMMON2 = VehicleIds.THUNDER_BLUFF_KODO;
|
||||
break;
|
||||
case 3:
|
||||
VEHICLE_TO_SUMMON1 = VehicleIds.ZUL_TORE_MOUNT;
|
||||
VEHICLE_TO_SUMMON2 = VehicleIds.DARKSPEAR_RAPTOR;
|
||||
break;
|
||||
case 4:
|
||||
VEHICLE_TO_SUMMON1 = VehicleIds.DEATHSTALKER_VESCERI_MOUNT;
|
||||
VEHICLE_TO_SUMMON2 = VehicleIds.FORSAKE_WARHORSE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
Creature pBoss = me.SummonCreature(VEHICLE_TO_SUMMON1, SpawnPosition);
|
||||
if (pBoss)
|
||||
{
|
||||
ObjectGuid uiGrandChampionBoss = ObjectGuid.Empty;
|
||||
Vehicle pVehicle = pBoss.GetVehicleKit();
|
||||
if (pVehicle)
|
||||
{
|
||||
Unit unit = pVehicle.GetPassenger(0);
|
||||
if (unit)
|
||||
uiGrandChampionBoss = unit.GetGUID();
|
||||
}
|
||||
|
||||
switch (uiSummonTimes)
|
||||
{
|
||||
case 1:
|
||||
uiVehicle1GUID = pBoss.GetGUID();
|
||||
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_VEHICLE_1, uiVehicle1GUID);
|
||||
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_1, uiGrandChampionBoss);
|
||||
break;
|
||||
case 2:
|
||||
|
||||
uiVehicle2GUID = pBoss.GetGUID();
|
||||
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_VEHICLE_2, uiVehicle2GUID);
|
||||
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_2, uiGrandChampionBoss);
|
||||
break;
|
||||
case 3:
|
||||
uiVehicle3GUID = pBoss.GetGUID();
|
||||
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_VEHICLE_3, uiVehicle3GUID);
|
||||
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_3, uiGrandChampionBoss);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
pBoss.GetAI().SetData(uiSummonTimes, 0);
|
||||
|
||||
for (byte i = 0; i < 3; ++i)
|
||||
{
|
||||
Creature pAdd = me.SummonCreature(VEHICLE_TO_SUMMON2, SpawnPosition, TempSummonType.CorpseDespawn);
|
||||
if (pAdd)
|
||||
{
|
||||
switch (uiSummonTimes)
|
||||
{
|
||||
case 1:
|
||||
Champion1List.Add(pAdd.GetGUID());
|
||||
break;
|
||||
case 2:
|
||||
Champion2List.Add(pAdd.GetGUID());
|
||||
break;
|
||||
case 3:
|
||||
Champion3List.Add(pAdd.GetGUID());
|
||||
break;
|
||||
}
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
pAdd.GetMotionMaster().MoveFollow(pBoss, 2.0f, MathFunctions.PI);
|
||||
break;
|
||||
case 1:
|
||||
pAdd.GetMotionMaster().MoveFollow(pBoss, 2.0f, MathFunctions.PI / 2);
|
||||
break;
|
||||
case 2:
|
||||
pAdd.GetMotionMaster().MoveFollow(pBoss, 2.0f, MathFunctions.PI / 2 + MathFunctions.PI);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoStartArgentChampionEncounter()
|
||||
{
|
||||
me.GetMotionMaster().MovePoint(1, 735.81f, 661.92f, 412.39f);
|
||||
|
||||
if (me.SummonCreature(uiArgentChampion, SpawnPosition))
|
||||
{
|
||||
for (byte i = 0; i < 3; ++i)
|
||||
{
|
||||
Creature lightwielderTrash = me.SummonCreature(CreatureIds.ARGENT_LIGHWIELDER, SpawnPosition);
|
||||
if (lightwielderTrash)
|
||||
lightwielderTrash.GetAI().SetData(i, 0);
|
||||
|
||||
Creature monkTrash = me.SummonCreature(CreatureIds.ARGENT_MONK, SpawnPosition);
|
||||
if (monkTrash)
|
||||
monkTrash.GetAI().SetData(i, 0);
|
||||
|
||||
Creature priestessTrash = me.SummonCreature(CreatureIds.PRIESTESS, SpawnPosition);
|
||||
if (priestessTrash)
|
||||
priestessTrash.GetAI().SetData(i, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetGrandChampionsForEncounter()
|
||||
{
|
||||
uiFirstBoss = RandomHelper.URand(0, 4);
|
||||
|
||||
while (uiSecondBoss == uiFirstBoss || uiThirdBoss == uiFirstBoss || uiThirdBoss == uiSecondBoss)
|
||||
{
|
||||
uiSecondBoss = RandomHelper.URand(0, 4);
|
||||
uiThirdBoss = RandomHelper.URand(0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void SetArgentChampion()
|
||||
{
|
||||
byte uiTempBoss = (byte)RandomHelper.URand(0, 1);
|
||||
|
||||
switch (uiTempBoss)
|
||||
{
|
||||
case 0:
|
||||
uiArgentChampion = CreatureIds.EADRIC;
|
||||
break;
|
||||
case 1:
|
||||
uiArgentChampion = CreatureIds.PALETRESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void StartEncounter()
|
||||
{
|
||||
me.RemoveFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
|
||||
if (instance.GetData((uint)Data.BOSS_BLACK_KNIGHT) == (uint)EncounterState.NotStarted)
|
||||
{
|
||||
if (instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_E) == (uint)EncounterState.NotStarted && instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_P) == (uint)EncounterState.NotStarted)
|
||||
{
|
||||
if (instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.NotStarted)
|
||||
SetData((uint)Data.DATA_START, 0);
|
||||
|
||||
if (instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.Done)
|
||||
DoStartArgentChampionEncounter();
|
||||
}
|
||||
|
||||
if ((instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.Done &&
|
||||
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_E) == (uint)EncounterState.Done) ||
|
||||
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_P) == (uint)EncounterState.Done)
|
||||
me.SummonCreature(VehicleIds.BLACK_KNIGHT, 769.834f, 651.915f, 447.035f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void AggroAllPlayers(Creature temp)
|
||||
{
|
||||
var PlList = me.GetMap().GetPlayers();
|
||||
|
||||
if (PlList.Empty())
|
||||
return;
|
||||
|
||||
foreach (var player in PlList)
|
||||
{
|
||||
if (player.IsGameMaster())
|
||||
continue;
|
||||
|
||||
if (player.IsAlive())
|
||||
{
|
||||
temp.SetHomePosition(me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), me.GetOrientation());
|
||||
temp.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
temp.SetReactState(ReactStates.Aggressive);
|
||||
temp.SetInCombatWith(player);
|
||||
player.SetInCombatWith(temp);
|
||||
temp.AddThreat(player, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
base.UpdateAI(diff);
|
||||
|
||||
if (uiTimer <= diff)
|
||||
{
|
||||
switch (uiPhase)
|
||||
{
|
||||
case 1:
|
||||
DoSummonGrandChampion(uiSecondBoss);
|
||||
NextStep(10000, true);
|
||||
break;
|
||||
case 2:
|
||||
DoSummonGrandChampion(uiThirdBoss);
|
||||
NextStep(0, false);
|
||||
break;
|
||||
case 3:
|
||||
if (!Champion1List.Empty())
|
||||
{
|
||||
foreach (var guid in Champion1List)
|
||||
{
|
||||
Creature summon = ObjectAccessor.GetCreature(me, guid);
|
||||
if (summon)
|
||||
AggroAllPlayers(summon);
|
||||
}
|
||||
NextStep(0, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
uiTimer -= diff;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
if (instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.NotStarted)
|
||||
{
|
||||
summon.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
summon.SetReactState(ReactStates.Passive);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SummonedCreatureDespawn(Creature summon)
|
||||
{
|
||||
switch (summon.GetEntry())
|
||||
{
|
||||
case VehicleIds.DARNASSIA_NIGHTSABER:
|
||||
case VehicleIds.EXODAR_ELEKK:
|
||||
case VehicleIds.STORMWIND_STEED:
|
||||
case VehicleIds.GNOMEREGAN_MECHANOSTRIDER:
|
||||
case VehicleIds.IRONFORGE_RAM:
|
||||
case VehicleIds.FORSAKE_WARHORSE:
|
||||
case VehicleIds.THUNDER_BLUFF_KODO:
|
||||
case VehicleIds.ORGRIMMAR_WOLF:
|
||||
case VehicleIds.SILVERMOON_HAWKSTRIDER:
|
||||
case VehicleIds.DARKSPEAR_RAPTOR:
|
||||
SetData((uint)Data.DATA_LESSER_CHAMPIONS_DEFEATED, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
byte uiSummonTimes;
|
||||
byte uiLesserChampions;
|
||||
|
||||
uint uiArgentChampion;
|
||||
|
||||
uint uiFirstBoss;
|
||||
uint uiSecondBoss;
|
||||
uint uiThirdBoss;
|
||||
|
||||
uint uiPhase;
|
||||
uint uiTimer;
|
||||
|
||||
ObjectGuid uiVehicle1GUID;
|
||||
ObjectGuid uiVehicle2GUID;
|
||||
ObjectGuid uiVehicle3GUID;
|
||||
|
||||
List<ObjectGuid> Champion1List = new List<ObjectGuid>();
|
||||
List<ObjectGuid> Champion2List = new List<ObjectGuid>();
|
||||
List<ObjectGuid> Champion3List = new List<ObjectGuid>();
|
||||
|
||||
Position SpawnPosition = new Position(746.261f, 657.401f, 411.681f, 4.65f);
|
||||
}
|
||||
|
||||
public override bool OnGossipHello(Player player, Creature creature)
|
||||
{
|
||||
InstanceScript instance = creature.GetInstanceScript();
|
||||
|
||||
if (instance != null &&
|
||||
((instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.Done &&
|
||||
instance.GetData((uint)Data.BOSS_BLACK_KNIGHT) == (uint)EncounterState.Done &&
|
||||
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_E) == (uint)EncounterState.Done) ||
|
||||
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_P) == (uint)EncounterState.Done))
|
||||
return false;
|
||||
|
||||
if (instance != null &&
|
||||
instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.NotStarted &&
|
||||
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_E) == (uint)EncounterState.NotStarted &&
|
||||
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_P) == (uint)EncounterState.NotStarted &&
|
||||
instance.GetData((uint)Data.BOSS_BLACK_KNIGHT) == (uint)EncounterState.NotStarted)
|
||||
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, TrialOfTheChampionConst.GOSSIP_START_EVENT1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
|
||||
else if (instance != null)
|
||||
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, TrialOfTheChampionConst.GOSSIP_START_EVENT2, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
|
||||
|
||||
player.SEND_GOSSIP_MENU(player.GetGossipTextId(creature), creature.GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnGossipSelect(Player player, Creature creature, uint sender, uint action)
|
||||
{
|
||||
player.PlayerTalkClass.ClearMenus();
|
||||
if (action == eTradeskill.GossipActionInfoDef + 1)
|
||||
{
|
||||
player.CLOSE_GOSSIP_MENU();
|
||||
((npc_announcer_toc5AI)creature.GetAI()).StartEncounter();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override CreatureAI GetAI(Creature creature)
|
||||
{
|
||||
return instance_trial_of_the_champion.GetTrialOfTheChampionAI<npc_announcer_toc5AI>(creature);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* 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.Collections.Generic;
|
||||
|
||||
namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheCrusader
|
||||
{
|
||||
struct Jaraxxus
|
||||
{
|
||||
public const uint SayIntro = 0;
|
||||
public const uint SayAggro = 1;
|
||||
public const uint EmoteLegionFlame = 2;
|
||||
public const uint EmoteNetherPortal = 3;
|
||||
public const uint SayMistressOfPain = 4;
|
||||
public const uint EmoteIncinerate = 5;
|
||||
public const uint SayIncinerate = 6;
|
||||
public const uint EmoteInfernalEruption = 7;
|
||||
public const uint SayInfernalEruption = 8;
|
||||
public const uint SayKillPlayer = 9;
|
||||
public const uint SayDeath = 10;
|
||||
public const uint SayBerserk = 11;
|
||||
|
||||
public const uint NpcLegionFlame = 34784;
|
||||
public const uint NpcInfernalVolcano = 34813;
|
||||
public const uint NpcFelInfernal = 34815; // Immune To All Cc On Heroic (Stuns; Banish; Interrupt; Etc)
|
||||
public const uint NpcNetherPortal = 34825;
|
||||
public const uint NpcMistressOfPain = 34826;
|
||||
|
||||
public const uint SpellLegionFlame = 66197; // Player Should Run Away From Raid Because He Triggers Legion Flame
|
||||
public const uint SpellLegionFlameEffect = 66201; // Used By Trigger Npc
|
||||
public const uint SpellNetherPower = 66228; // +20% Of Spell Damage Per Stack; Stackable Up To 5/10 Times; Must Be Dispelled/Stealed
|
||||
public const uint SpellFelLighting = 66528; // Jumps To Nearby Targets
|
||||
public const uint SpellFelFireball = 66532; // Does Heavy Damage To The Tank; Interruptable
|
||||
public const uint SpellIncinerateFlesh = 66237; // Target Must Be Healed Or Will Trigger Burning Inferno
|
||||
public const uint SpellBurningInferno = 66242; // Triggered By Incinerate Flesh
|
||||
public const uint SpellInfernalEruption = 66258; // Summons Infernal Volcano
|
||||
public const uint SpellInfernalEruptionEffect = 66252; // Summons Felflame Infernal (3 At Normal And Inifinity At Heroic)
|
||||
public const uint SpellNetherPortal = 66269; // Summons Nether Portal
|
||||
public const uint SpellNetherPortalEffect = 66263; // Summons Mistress Of Pain (1 At Normal And Infinity At Heroic)
|
||||
|
||||
public const uint SpellBerserk = 64238; // Unused
|
||||
|
||||
// Mistress Of Pain Spells
|
||||
public const uint SpellShivanSlash = 67098;
|
||||
public const uint SpellSpinningStrike = 66283;
|
||||
public const uint SpellMistressKiss = 66336;
|
||||
public const uint SpellFelInferno = 67047;
|
||||
public const uint SpellFelStreak = 66494;
|
||||
public const int SpellLordHittin = 66326; // Special Effect Preventing More Specific Spells Be Cast On The Same Player Within 10 Seconds
|
||||
public const uint SpellMistressKissDamageSilence = 66359;
|
||||
|
||||
// Lord Jaraxxus
|
||||
public const uint EventFelFireball = 1;
|
||||
public const uint EventFelLightning = 2;
|
||||
public const uint EventIncinerateFlesh = 3;
|
||||
public const uint EventNetherPower = 4;
|
||||
public const uint EventLegionFlame = 5;
|
||||
public const uint EventSummonoNetherPortal = 6;
|
||||
public const uint EventSummonInfernalEruption = 7;
|
||||
|
||||
// Mistress Of Pain
|
||||
public const uint EventShivanSlash = 8;
|
||||
public const uint EventSpinningStrike = 9;
|
||||
public const uint EventMistressKiss = 10;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_jaraxxus : BossAI
|
||||
{
|
||||
public boss_jaraxxus(Creature creature) : base(creature, DataTypes.BossJaraxxus) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
_events.ScheduleEvent(Jaraxxus.EventFelFireball, 5 * Time.InMilliseconds);
|
||||
_events.ScheduleEvent(Jaraxxus.EventFelLightning, RandomHelper.URand(10 * Time.InMilliseconds, 15 * Time.InMilliseconds));
|
||||
_events.ScheduleEvent(Jaraxxus.EventIncinerateFlesh, RandomHelper.URand(20 * Time.InMilliseconds, 25 * Time.InMilliseconds));
|
||||
_events.ScheduleEvent(Jaraxxus.EventNetherPower, 40 * Time.InMilliseconds);
|
||||
_events.ScheduleEvent(Jaraxxus.EventLegionFlame, 30 * Time.InMilliseconds);
|
||||
_events.ScheduleEvent(Jaraxxus.EventSummonoNetherPortal, 20 * Time.InMilliseconds);
|
||||
_events.ScheduleEvent(Jaraxxus.EventSummonInfernalEruption, 80 * Time.InMilliseconds);
|
||||
}
|
||||
|
||||
public override void JustReachedHome()
|
||||
{
|
||||
_JustReachedHome();
|
||||
instance.SetBossState(DataTypes.BossJaraxxus, EncounterState.Fail);
|
||||
DoCast(me, Spells.JaraxxusChains);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.IsTypeId(TypeId.Player))
|
||||
{
|
||||
Talk(Jaraxxus.SayKillPlayer);
|
||||
instance.SetData(DataTypes.TributeToImmortalityEligible, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(Jaraxxus.SayDeath);
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summoned)
|
||||
{
|
||||
summons.Summon(summoned);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(Jaraxxus.SayAggro);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Jaraxxus.EventFelFireball:
|
||||
DoCastVictim(Jaraxxus.SpellFelFireball);
|
||||
_events.ScheduleEvent(Jaraxxus.EventFelFireball, RandomHelper.URand(10 * Time.InMilliseconds, 15 * Time.InMilliseconds));
|
||||
return;
|
||||
case Jaraxxus.EventFelLightning:
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true, -Jaraxxus.SpellLordHittin);
|
||||
if (target)
|
||||
DoCast(target, Jaraxxus.SpellFelLighting);
|
||||
_events.ScheduleEvent(Jaraxxus.EventFelLightning, RandomHelper.URand(10 * Time.InMilliseconds, 15 * Time.InMilliseconds));
|
||||
return;
|
||||
}
|
||||
case Jaraxxus.EventIncinerateFlesh:
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 0.0f, true, -Jaraxxus.SpellLordHittin);
|
||||
if (target)
|
||||
{
|
||||
Talk(Jaraxxus.EmoteIncinerate, target);
|
||||
Talk(Jaraxxus.SayIncinerate);
|
||||
DoCast(target, Jaraxxus.SpellInfernalEruption);
|
||||
}
|
||||
_events.ScheduleEvent(Jaraxxus.EventIncinerateFlesh, RandomHelper.URand(20 * Time.InMilliseconds, 25 * Time.InMilliseconds));
|
||||
return;
|
||||
}
|
||||
case Jaraxxus.EventNetherPower:
|
||||
me.CastCustomSpell(Jaraxxus.SpellNetherPower, SpellValueMod.AuraStack, RaidMode(5, 10, 5, 10), me, true);
|
||||
_events.ScheduleEvent(Jaraxxus.EventNetherPower, 40 * Time.InMilliseconds);
|
||||
return;
|
||||
case Jaraxxus.EventLegionFlame:
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 0.0f, true, -Jaraxxus.SpellLordHittin);
|
||||
if (target)
|
||||
{
|
||||
Talk(Jaraxxus.EmoteLegionFlame, target);
|
||||
DoCast(target, Jaraxxus.SpellLegionFlame);
|
||||
}
|
||||
_events.ScheduleEvent(Jaraxxus.EventLegionFlame, 30 * Time.InMilliseconds);
|
||||
return;
|
||||
}
|
||||
case Jaraxxus.EventSummonoNetherPortal:
|
||||
Talk(Jaraxxus.EmoteNetherPortal);
|
||||
Talk(Jaraxxus.SayMistressOfPain);
|
||||
DoCast(Jaraxxus.SpellNetherPortal);
|
||||
_events.ScheduleEvent(Jaraxxus.EventSummonoNetherPortal, 2 * Time.Minute * Time.InMilliseconds);
|
||||
return;
|
||||
case Jaraxxus.EventSummonInfernalEruption:
|
||||
Talk(Jaraxxus.EmoteInfernalEruption);
|
||||
Talk(Jaraxxus.SayInfernalEruption);
|
||||
DoCast(Jaraxxus.SpellInfernalEruption);
|
||||
_events.ScheduleEvent(Jaraxxus.EventSummonInfernalEruption, 2 * Time.Minute * Time.InMilliseconds);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_legion_flame : ScriptedAI
|
||||
{
|
||||
public npc_legion_flame(Creature creature) : base(creature)
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
_instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
||||
me.SetInCombatWithZone();
|
||||
DoCast(Jaraxxus.SpellLegionFlameEffect);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
UpdateVictim();
|
||||
if (_instance.GetBossState(DataTypes.BossJaraxxus) != EncounterState.InProgress)
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
InstanceScript _instance;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_infernal_volcano : ScriptedAI
|
||||
{
|
||||
public npc_infernal_volcano(Creature creature) : base(creature)
|
||||
{
|
||||
_summons = new SummonList(me);
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
|
||||
if (!IsHeroic())
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
|
||||
else
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
|
||||
|
||||
_summons.DespawnAll();
|
||||
}
|
||||
|
||||
public override void IsSummonedBy(Unit summoner)
|
||||
{
|
||||
DoCast(Jaraxxus.SpellInfernalEruptionEffect);
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summoned)
|
||||
{
|
||||
_summons.Summon(summoned);
|
||||
// makes immediate corpse despawn of summoned Felflame Infernals
|
||||
summoned.SetCorpseDelay(0);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
// used to despawn corpse immediately
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff) { }
|
||||
|
||||
SummonList _summons;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_fel_infernal : ScriptedAI
|
||||
{
|
||||
public npc_fel_infernal(Creature creature) : base(creature)
|
||||
{
|
||||
_instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_felStreakTimer = 30 * Time.InMilliseconds;
|
||||
me.SetInCombatWithZone();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (_instance.GetBossState(DataTypes.BossJaraxxus) != EncounterState.InProgress)
|
||||
{
|
||||
me.DespawnOrUnsummon();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (_felStreakTimer <= diff)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
|
||||
if (target)
|
||||
DoCast(target, Jaraxxus.SpellFelStreak);
|
||||
_felStreakTimer = 30 * Time.InMilliseconds;
|
||||
}
|
||||
else
|
||||
_felStreakTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
uint _felStreakTimer;
|
||||
InstanceScript _instance;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_nether_portal : ScriptedAI
|
||||
{
|
||||
public npc_nether_portal(Creature creature) : base(creature)
|
||||
{
|
||||
_summons = new SummonList(me);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
|
||||
if (!IsHeroic())
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
|
||||
else
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
|
||||
|
||||
_summons.DespawnAll();
|
||||
}
|
||||
|
||||
public override void IsSummonedBy(Unit summoner)
|
||||
{
|
||||
DoCast(Jaraxxus.SpellNetherPortalEffect);
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summoned)
|
||||
{
|
||||
_summons.Summon(summoned);
|
||||
// makes immediate corpse despawn of summoned Mistress of Pain
|
||||
summoned.SetCorpseDelay(0);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
// used to despawn corpse immediately
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff) { }
|
||||
|
||||
SummonList _summons;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_mistress_of_pain : ScriptedAI
|
||||
{
|
||||
public npc_mistress_of_pain(Creature creature) : base(creature)
|
||||
{
|
||||
_instance = creature.GetInstanceScript();
|
||||
_instance.SetData(DataTypes.MistressOfPainCount, DataTypes.Increase);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.ScheduleEvent(Jaraxxus.EventShivanSlash, 30 * Time.InMilliseconds);
|
||||
_events.ScheduleEvent(Jaraxxus.EventSpinningStrike, 30 * Time.InMilliseconds);
|
||||
if (IsHeroic())
|
||||
_events.ScheduleEvent(Jaraxxus.EventMistressKiss, 15 * Time.InMilliseconds);
|
||||
me.SetInCombatWithZone();
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_instance.SetData(DataTypes.MistressOfPainCount, DataTypes.Decrease);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (_instance.GetBossState(DataTypes.BossJaraxxus) != EncounterState.InProgress)
|
||||
{
|
||||
me.DespawnOrUnsummon();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Jaraxxus.EventShivanSlash:
|
||||
DoCastVictim(Jaraxxus.SpellShivanSlash);
|
||||
_events.ScheduleEvent(Jaraxxus.EventShivanSlash, 30 * Time.InMilliseconds);
|
||||
return;
|
||||
case Jaraxxus.EventSpinningStrike:
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
|
||||
if (target)
|
||||
DoCast(target, Jaraxxus.SpellSpinningStrike);
|
||||
_events.ScheduleEvent(Jaraxxus.EventSpinningStrike, 30 * Time.InMilliseconds);
|
||||
return;
|
||||
case Jaraxxus.EventMistressKiss:
|
||||
DoCast(me, Jaraxxus.SpellMistressKiss);
|
||||
_events.ScheduleEvent(Jaraxxus.EventMistressKiss, 30 * Time.InMilliseconds);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
InstanceScript _instance;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_mistress_kiss : AuraScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
return ValidateSpellInfo(Jaraxxus.SpellMistressKissDamageSilence);
|
||||
}
|
||||
|
||||
void HandleDummyTick(AuraEffect aurEff)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
Unit target = GetTarget();
|
||||
if (caster && target)
|
||||
{
|
||||
if (target.HasUnitState(UnitState.Casting))
|
||||
{
|
||||
caster.CastSpell(target, Jaraxxus.SpellMistressKissDamageSilence, true);
|
||||
target.RemoveAurasDueToSpell(GetSpellInfo().Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleDummyTick, 0, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_mistress_kiss_area : SpellScript
|
||||
{
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
// get a list of players with mana
|
||||
targets.RemoveAll(unit => unit.IsTypeId(TypeId.Player) && unit.ToPlayer().getPowerType() == PowerType.Mana);
|
||||
if (targets.Empty())
|
||||
return;
|
||||
|
||||
WorldObject target = targets.SelectRandom();
|
||||
targets.Clear();
|
||||
targets.Add(target);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
GetCaster().CastSpell(GetHitUnit(), (uint)GetEffectValue(), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEnemy));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+409
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Maps;
|
||||
|
||||
namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheCrusader
|
||||
{
|
||||
struct DataTypes
|
||||
{
|
||||
public const uint BossBeasts = 0;
|
||||
public const uint BossJaraxxus = 1;
|
||||
public const uint BossCrusaders = 2;
|
||||
public const uint BossValkiries = 3;
|
||||
public const uint BossLichKing = 4; // Not Really A Boss But Oh Well
|
||||
public const uint BossAnubarak = 5;
|
||||
public const uint MaxEncounters = 6;
|
||||
|
||||
public const uint Counter = 8;
|
||||
public const uint Event = 9;
|
||||
|
||||
public const uint EventTimer = 101;
|
||||
public const uint EventNpc = 102;
|
||||
public const uint NorthrendBeasts = 103;
|
||||
|
||||
public const uint SnoboldCount = 301;
|
||||
public const uint MistressOfPainCount = 302;
|
||||
public const uint TributeToImmortalityEligible = 303;
|
||||
|
||||
public const uint Increase = 501;
|
||||
public const uint Decrease = 502;
|
||||
}
|
||||
|
||||
struct Spells
|
||||
{
|
||||
public const uint WilfredPortal = 68424;
|
||||
public const uint JaraxxusChains = 67924;
|
||||
public const uint CorpseTeleport = 69016;
|
||||
public const uint DestroyFloorKnockup = 68193;
|
||||
}
|
||||
|
||||
struct WorldStateIds
|
||||
{
|
||||
public const uint Show = 4390;
|
||||
public const uint Count = 4389;
|
||||
}
|
||||
|
||||
enum AnnouncerMessages
|
||||
{
|
||||
Beasts = 724001,
|
||||
Jaraxxus = 724002,
|
||||
Crusaders = 724003,
|
||||
Valkiries = 724004,
|
||||
LichKing = 724005,
|
||||
Anubarak = 724006
|
||||
}
|
||||
|
||||
public struct CreatureIds
|
||||
{
|
||||
public const uint Barrent = 34816;
|
||||
public const uint Tirion = 34996;
|
||||
public const uint TirionFordring = 36095;
|
||||
public const uint ArgentMage = 36097;
|
||||
public const uint Fizzlebang = 35458;
|
||||
public const uint Garrosh = 34995;
|
||||
public const uint Varian = 34990;
|
||||
public const uint LichKing = 35877;
|
||||
|
||||
public const uint Thrall = 34994;
|
||||
public const uint Proudmoore = 34992;
|
||||
public const uint WilfredPortal = 17965;
|
||||
public const uint Trigger = 35651;
|
||||
|
||||
public const uint Icehowl = 34797;
|
||||
public const uint Gormok = 34796;
|
||||
public const uint Dreadscale = 34799;
|
||||
public const uint Acidmaw = 35144;
|
||||
|
||||
public const uint Jaraxxus = 34780;
|
||||
|
||||
public const uint ChampionsController = 34781;
|
||||
|
||||
public const uint AllianceDeathKnight = 34461;
|
||||
public const uint AllianceDruidBalance = 34460;
|
||||
public const uint AllianceDruidRestoration = 34469;
|
||||
public const uint AllianceHunter = 34467;
|
||||
public const uint AllianceMage = 34468;
|
||||
public const uint AlliancePaladinHoly = 34465;
|
||||
public const uint AlliancePaladinRetribution = 34471;
|
||||
public const uint AlliancePriestDiscipline = 34466;
|
||||
public const uint AlliancePriestShadow = 34473;
|
||||
public const uint AllianceRogue = 34472;
|
||||
public const uint AllianceShamanEnhancement = 34463;
|
||||
public const uint AllianceShamanRestoration = 34470;
|
||||
public const uint AllianceWarlock = 34474;
|
||||
public const uint AllianceWarrior = 34475;
|
||||
|
||||
public const uint HordeDeathKnight = 34458;
|
||||
public const uint HordeDruidBalance = 34451;
|
||||
public const uint HordeDruidRestoration = 34459;
|
||||
public const uint HordeHunter = 34448;
|
||||
public const uint HordeMage = 34449;
|
||||
public const uint HordePaladinHoly = 34445;
|
||||
public const uint HordePaladinRetribution = 34456;
|
||||
public const uint HordePriestDiscipline = 34447;
|
||||
public const uint HordePriestShadow = 34441;
|
||||
public const uint HordeRogue = 34454;
|
||||
public const uint HordeShamanEnhancement = 34455;
|
||||
public const uint HordeShamanRestoration = 34444;
|
||||
public const uint HordeWarlock = 34450;
|
||||
public const uint HordeWarrior = 34453;
|
||||
|
||||
public const uint Lightbane = 34497;
|
||||
public const uint Darkbane = 34496;
|
||||
|
||||
public const uint DarkEssence = 34567;
|
||||
public const uint LightEssence = 34568;
|
||||
|
||||
public const uint Anubarak = 34564;
|
||||
}
|
||||
|
||||
struct GameObjectIds
|
||||
{
|
||||
public const uint CrusadersCache10 = 195631;
|
||||
public const uint CrusadersCache25 = 195632;
|
||||
public const uint CrusadersCache10H = 195633;
|
||||
public const uint CrusadersCache25H = 195635;
|
||||
|
||||
// Tribute Chest (Heroic)
|
||||
// 10-Man Modes
|
||||
public const uint TributeChest10h25 = 195668; // 10man 01-24 Attempts
|
||||
public const uint TributeChest10h45 = 195667; // 10man 25-44 Attempts
|
||||
public const uint TributeChest10h50 = 195666; // 10man 45-49 Attempts
|
||||
public const uint TributeChest10h99 = 195665; // 10man 50 Attempts
|
||||
// 25-Man Modes
|
||||
public const uint TributeChest25h25 = 195672; // 25man 01-24 Attempts
|
||||
public const uint TributeChest25h45 = 195671; // 25man 25-44 Attempts
|
||||
public const uint TributeChest25h50 = 195670; // 25man 45-49 Attempts
|
||||
public const uint TributeChest25h99 = 195669; // 25man 50 Attempts
|
||||
|
||||
public const uint ArgentColiseumFloor = 195527; //20943
|
||||
public const uint MainGateDoor = 195647;
|
||||
public const uint EastPortcullis = 195648;
|
||||
public const uint WebDoor = 195485;
|
||||
public const uint PortalToDalaran = 195682;
|
||||
}
|
||||
|
||||
struct AchievementData
|
||||
{
|
||||
// Northrend Beasts
|
||||
public const uint UpperBackPain10Player = 11779;
|
||||
public const uint UpperBackPain10PlayerHeroic = 11802;
|
||||
public const uint UpperBackPain25Player = 11780;
|
||||
public const uint UpperBackPain25PlayerHeroic = 11801;
|
||||
// Lord Jaraxxus
|
||||
public const uint ThreeSixtyPainSpike10Player = 11838;
|
||||
public const uint ThreeSixtyPainSpike10PlayerHeroic = 11861;
|
||||
public const uint ThreeSixtyPainSpike25Player = 11839;
|
||||
public const uint ThreeSixtyPainSpike25PlayerHeroic = 11862;
|
||||
// Tribute
|
||||
public const uint ATributeToSkill10Player = 12344;
|
||||
public const uint ATributeToSkill25Player = 12338;
|
||||
public const uint ATributeToMadSkill10Player = 12347;
|
||||
public const uint ATributeToMadSkill25Player = 12341;
|
||||
public const uint ATributeToInsanity10Player = 12349;
|
||||
public const uint ATributeToInsanity25Player = 12343;
|
||||
public const uint ATributeToImmortalityHorde = 12358;
|
||||
public const uint ATributeToImmortalityAlliance = 12359;
|
||||
public const uint ATributeToDedicatedInsanity = 12360;
|
||||
public const uint RealmFirstGrandCrusader = 12350;
|
||||
|
||||
// Dummy Spells - Not Existing In Dbc But We Don'T Need That
|
||||
public const uint SpellWormsKilledIn10Seconds = 68523;
|
||||
public const uint SpellChampionsKilledInMinute = 68620;
|
||||
public const uint SpellDefeatFactionChampions = 68184;
|
||||
public const uint SpellTraitorKing10 = 68186;
|
||||
public const uint SpellTraitorKing25 = 68515;
|
||||
|
||||
// Timed Events
|
||||
public const uint EventStartTwinsFight = 21853;
|
||||
}
|
||||
|
||||
struct NorthrendBeasts
|
||||
{
|
||||
public const uint GormokInProgress = 1000;
|
||||
public const uint GormokDone = 1001;
|
||||
public const uint SnakesInProgress = 2000;
|
||||
public const uint DreadscaleSubmerged = 2001;
|
||||
public const uint AcidmawSubmerged = 2002;
|
||||
public const uint SnakesSpecial = 2003;
|
||||
public const uint SnakesDone = 2004;
|
||||
public const uint IcehowlInProgress = 3000;
|
||||
public const uint IcehowlDone = 3001;
|
||||
}
|
||||
|
||||
struct Texts
|
||||
{
|
||||
// Highlord Tirion Fordring - 34996
|
||||
public const uint Stage_0_01 = 0;
|
||||
public const uint Stage_0_02 = 1;
|
||||
public const uint Stage_0_04 = 2;
|
||||
public const uint Stage_0_05 = 3;
|
||||
public const uint Stage_0_06 = 4;
|
||||
public const uint Stage_0_Wipe = 5;
|
||||
public const uint Stage_1_01 = 6;
|
||||
public const uint Stage_1_07 = 7;
|
||||
public const uint Stage_1_08 = 8;
|
||||
public const uint Stage_1_11 = 9;
|
||||
public const uint Stage_2_01 = 10;
|
||||
public const uint Stage_2_03 = 11;
|
||||
public const uint Stage_2_06 = 12;
|
||||
public const uint Stage_3_01 = 13;
|
||||
public const uint Stage_3_02 = 14;
|
||||
public const uint Stage_4_01 = 15;
|
||||
public const uint Stage_4_03 = 16;
|
||||
|
||||
// Varian Wrynn
|
||||
public const uint Stage_0_03a = 0;
|
||||
public const uint Stage_1_10 = 1;
|
||||
public const uint Stage_2_02a = 2;
|
||||
public const uint Stage_2_04a = 3;
|
||||
public const uint Stage_2_05a = 4;
|
||||
public const uint Stage_3_03a = 5;
|
||||
|
||||
// Garrosh
|
||||
public const uint Stage_0_03h = 0;
|
||||
public const uint Stage_1_09 = 1;
|
||||
public const uint Stage_2_02h = 2;
|
||||
public const uint Stage_2_04h = 3;
|
||||
public const uint Stage_2_05h = 4;
|
||||
public const uint Stage_3_03h = 5;
|
||||
|
||||
// Wilfred Fizzlebang
|
||||
public const uint Stage_1_02 = 0;
|
||||
public const uint Stage_1_03 = 1;
|
||||
public const uint Stage_1_04 = 2;
|
||||
public const uint Stage_1_06 = 3;
|
||||
|
||||
// Lord Jaraxxus
|
||||
public const uint Stage_1_05 = 0;
|
||||
|
||||
// The Lich King
|
||||
public const uint Stage_4_02 = 0;
|
||||
public const uint Stage_4_05 = 1;
|
||||
public const uint Stage_4_04 = 2;
|
||||
|
||||
// Highlord Tirion Fordring - 36095
|
||||
public const uint Stage_4_06 = 0;
|
||||
public const uint Stage_4_07 = 1;
|
||||
}
|
||||
|
||||
struct MiscData
|
||||
{
|
||||
public const uint DespawnTime = 300000;
|
||||
|
||||
public const uint DisplayIdDestroyedFloor = 9060;
|
||||
|
||||
public static BossBoundaryEntry[] boundaries =
|
||||
{
|
||||
new BossBoundaryEntry(DataTypes.BossBeasts, new CircleBoundary(new Position(563.26f, 139.6f), 75.0)),
|
||||
new BossBoundaryEntry(DataTypes.BossJaraxxus, new CircleBoundary(new Position(563.26f, 139.6f), 75.0)),
|
||||
new BossBoundaryEntry(DataTypes.BossCrusaders, new CircleBoundary(new Position(563.26f, 139.6f), 75.0)),
|
||||
new BossBoundaryEntry(DataTypes.BossValkiries, new CircleBoundary(new Position(563.26f, 139.6f), 75.0)),
|
||||
new BossBoundaryEntry(DataTypes.BossAnubarak, new EllipseBoundary(new Position(746.0f, 135.0f), 100.0, 75.0))
|
||||
};
|
||||
|
||||
public static _Messages[] _GossipMessage =
|
||||
{
|
||||
new _Messages(AnnouncerMessages.Beasts, eTradeskill.GossipActionInfoDef + 1, false, DataTypes.BossBeasts),
|
||||
new _Messages(AnnouncerMessages.Jaraxxus, eTradeskill.GossipActionInfoDef + 2, false, DataTypes.BossJaraxxus),
|
||||
new _Messages(AnnouncerMessages.Crusaders, eTradeskill.GossipActionInfoDef + 3, false, DataTypes.BossCrusaders),
|
||||
new _Messages(AnnouncerMessages.Valkiries, eTradeskill.GossipActionInfoDef + 4, false, DataTypes.BossValkiries),
|
||||
new _Messages(AnnouncerMessages.LichKing, eTradeskill.GossipActionInfoDef + 5, false, DataTypes.BossAnubarak),
|
||||
new _Messages(AnnouncerMessages.Anubarak, eTradeskill.GossipActionInfoDef + 6, true, DataTypes.BossAnubarak)
|
||||
};
|
||||
|
||||
public static Position[] ToCSpawnLoc =
|
||||
{
|
||||
new Position(563.912f, 261.625f, 394.73f, 4.70437f), // 0 Center
|
||||
new Position( 575.451f, 261.496f, 394.73f, 4.6541f), // 1 Left
|
||||
new Position( 549.951f, 261.55f, 394.73f, 4.74835f) // 2 Right
|
||||
};
|
||||
|
||||
public static Position[] ToCCommonLoc =
|
||||
{
|
||||
new Position(559.257996f, 90.266197f, 395.122986f, 0), // 0 Barrent
|
||||
|
||||
new Position(563.672974f, 139.571f, 393.837006f, 0), // 1 Center
|
||||
new Position(563.833008f, 187.244995f, 394.5f, 0), // 2 Backdoor
|
||||
new Position(577.347839f, 195.338888f, 395.14f, 0), // 3 - Right
|
||||
new Position(550.955933f, 195.338888f, 395.14f, 0), // 4 - Left
|
||||
new Position(563.833008f, 195.244995f, 394.585561f, 0), // 5 - Center
|
||||
new Position(573.5f, 180.5f, 395.14f, 0), // 6 Move 0 Right
|
||||
new Position(553.5f, 180.5f, 395.14f, 0), // 7 Move 0 Left
|
||||
new Position(573.0f, 170.0f, 395.14f, 0), // 8 Move 1 Right
|
||||
new Position(555.5f, 170.0f, 395.14f, 0), // 9 Move 1 Left
|
||||
new Position(563.8f, 216.1f, 395.1f, 0), // 10 Behind the door
|
||||
|
||||
new Position(575.042358f, 195.260727f, 395.137146f, 0), // 5
|
||||
new Position(552.248901f, 195.331955f, 395.132658f, 0), // 6
|
||||
new Position(573.342285f, 195.515823f, 395.135956f, 0), // 7
|
||||
new Position(554.239929f, 195.825577f, 395.137909f, 0), // 8
|
||||
new Position(571.042358f, 195.260727f, 395.137146f, 0), // 9
|
||||
new Position(556.720581f, 195.015472f, 395.132658f, 0), // 10
|
||||
new Position(569.534119f, 195.214478f, 395.139526f, 0), // 11
|
||||
new Position(569.231201f, 195.941071f, 395.139526f, 0), // 12
|
||||
new Position(558.811610f, 195.985779f, 394.671661f, 0), // 13
|
||||
new Position(567.641724f, 195.351501f, 394.659943f, 0), // 14
|
||||
new Position(560.633972f, 195.391708f, 395.137543f, 0), // 15
|
||||
new Position(565.816956f, 195.477921f, 395.136810f, 0) // 16
|
||||
};
|
||||
|
||||
public static Position[] JaraxxusLoc =
|
||||
{
|
||||
new Position(508.104767f, 138.247345f, 395.128052f, 0), // 0 - Fizzlebang start location
|
||||
new Position(548.610596f, 139.807800f, 394.321838f, 0), // 1 - fizzlebang end
|
||||
new Position(581.854187f, 138.0f, 394.319f, 0), // 2 - Portal Right
|
||||
new Position(550.558838f, 138.0f, 394.319f, 0) // 3 - Portal Left
|
||||
};
|
||||
|
||||
public static Position[] FactionChampionLoc =
|
||||
{
|
||||
new Position(514.231f, 105.569f, 418.234f, 0), // 0 - Horde Initial Pos 0
|
||||
new Position(508.334f, 115.377f, 418.234f, 0), // 1 - Horde Initial Pos 1
|
||||
new Position(506.454f, 126.291f, 418.234f, 0), // 2 - Horde Initial Pos 2
|
||||
new Position(506.243f, 106.596f, 421.592f, 0), // 3 - Horde Initial Pos 3
|
||||
new Position(499.885f, 117.717f, 421.557f, 0), // 4 - Horde Initial Pos 4
|
||||
|
||||
new Position(613.127f, 100.443f, 419.74f, 0), // 5 - Ally Initial Pos 0
|
||||
new Position(621.126f, 128.042f, 418.231f, 0), // 6 - Ally Initial Pos 1
|
||||
new Position(618.829f, 113.606f, 418.232f, 0), // 7 - Ally Initial Pos 2
|
||||
new Position(625.845f, 112.914f, 421.575f, 0), // 8 - Ally Initial Pos 3
|
||||
new Position(615.566f, 109.653f, 418.234f, 0), // 9 - Ally Initial Pos 4
|
||||
|
||||
new Position(535.469f, 113.012f, 394.66f, 0), // 10 - Horde Final Pos 0
|
||||
new Position(526.417f, 137.465f, 394.749f, 0), // 11 - Horde Final Pos 1
|
||||
new Position(528.108f, 111.057f, 395.289f, 0), // 12 - Horde Final Pos 2
|
||||
new Position(519.92f, 134.285f, 395.289f, 0), // 13 - Horde Final Pos 3
|
||||
new Position(533.648f, 119.148f, 394.646f, 0), // 14 - Horde Final Pos 4
|
||||
new Position(531.399f, 125.63f, 394.708f, 0), // 15 - Horde Final Pos 5
|
||||
new Position(528.958f, 131.47f, 394.73f, 0), // 16 - Horde Final Pos 6
|
||||
new Position(526.309f, 116.667f, 394.833f, 0), // 17 - Horde Final Pos 7
|
||||
new Position(524.238f, 122.411f, 394.819f, 0), // 18 - Horde Final Pos 8
|
||||
new Position(521.901f, 128.488f, 394.832f, 0) // 19 - Horde Final Pos 9
|
||||
};
|
||||
|
||||
public static Position[] TwinValkyrsLoc =
|
||||
{
|
||||
new Position(586.060242f, 117.514809f, 394.41f, 0), // 0 - Dark essence 1
|
||||
new Position(541.602112f, 161.879837f, 394.41f, 0), // 1 - Dark essence 2
|
||||
new Position(541.021118f, 117.262932f, 394.41f, 0), // 2 - Light essence 1
|
||||
new Position(586.200562f, 162.145523f, 394.41f, 0) // 3 - Light essence 2
|
||||
};
|
||||
|
||||
public static Position[] LichKingLoc =
|
||||
{
|
||||
new Position(563.549f, 152.474f, 394.393f, 0), // 0 - Lich king start
|
||||
new Position(563.547f, 141.613f, 393.908f, 0) // 1 - Lich king end
|
||||
};
|
||||
|
||||
public static Position[] AnubarakLoc =
|
||||
{
|
||||
new Position(787.932556f, 133.289780f, 142.612152f, 0), // 0 - Anub'arak start location
|
||||
new Position(695.240051f, 137.834824f, 142.200000f, 0), // 1 - Anub'arak move point location
|
||||
new Position(694.886353f, 102.484665f, 142.119614f, 0), // 3 - Nerub Spawn
|
||||
new Position(694.500671f, 185.363968f, 142.117905f, 0), // 5 - Nerub Spawn
|
||||
new Position(731.987244f, 83.3824690f, 142.119614f, 0), // 2 - Nerub Spawn
|
||||
new Position(740.184509f, 193.443390f, 142.117584f, 0) // 4 - Nerub Spawn
|
||||
};
|
||||
|
||||
public static Position[] EndSpawnLoc =
|
||||
{
|
||||
new Position(648.9167f, 131.0208f, 141.6161f, 0), // 0 - Highlord Tirion Fordring
|
||||
new Position(649.1614f, 142.0399f, 141.3057f, 0), // 1 - Argent Mage
|
||||
new Position(644.6250f, 149.2743f, 140.6015f, 0) // 2 - Portal to Dalaran
|
||||
};
|
||||
}
|
||||
|
||||
struct _Messages
|
||||
{
|
||||
public _Messages(AnnouncerMessages _msg, uint _id, bool _state, uint _encounter)
|
||||
{
|
||||
msgnum = _msg;
|
||||
id = _id;
|
||||
state = _state;
|
||||
encounter = _encounter;
|
||||
}
|
||||
|
||||
public AnnouncerMessages msgnum;
|
||||
public uint id;
|
||||
public bool state;
|
||||
public uint encounter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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 Framework.Database;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Game.Mails;
|
||||
using Game.Scripting;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Northrend
|
||||
{
|
||||
struct DalaranConst
|
||||
{
|
||||
//Mageguard
|
||||
public const uint SpellTrespasserA = 54028;
|
||||
public const uint SpellTrespasserH = 54029;
|
||||
|
||||
public const uint SpellSunreaverDisguiseFemale = 70973;
|
||||
public const uint SpellSunreaverDisguiseMale = 70974;
|
||||
public const uint SpellSilverConenantDisguiseFemale = 70971;
|
||||
public const uint SpellSilverConenantDisguiseMale = 70972;
|
||||
|
||||
public const int NpcAplleboughA = 29547;
|
||||
public const int NpcSweetberryH = 29715;
|
||||
|
||||
//Minigob
|
||||
public const int SpellManabonked = 61834;
|
||||
public const int SpellTeleportVisual = 51347;
|
||||
public const int SpellImprovedBlink = 61995;
|
||||
|
||||
public const int EventSelectTarget = 1;
|
||||
public const int EventBlink = 2;
|
||||
public const int EventDespawnVisual = 3;
|
||||
public const int EventDespawn = 4;
|
||||
|
||||
public const int MailMinigobEntry = 264;
|
||||
public const int MailDeliverDelayMin = 5 * Time.Minute;
|
||||
public const int MailDeliverDelayMax = 15 * Time.Minute;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_mageguard_dalaran : ScriptedAI
|
||||
{
|
||||
public npc_mageguard_dalaran(Creature creature) : base(creature)
|
||||
{
|
||||
creature.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
creature.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchools.Normal, true);
|
||||
creature.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
|
||||
}
|
||||
|
||||
public override void Reset() { }
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
|
||||
public override void AttackStart(Unit who) { }
|
||||
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
if (!who || !who.IsInWorld || who.GetZoneId() != 4395)
|
||||
return;
|
||||
|
||||
if (!me.IsWithinDist(who, 65.0f, false))
|
||||
return;
|
||||
|
||||
Player player = who.GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
|
||||
if (!player || player.IsGameMaster() || player.IsBeingTeleported() ||
|
||||
// If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass
|
||||
player.HasAura(DalaranConst.SpellSunreaverDisguiseFemale) || player.HasAura(DalaranConst.SpellSunreaverDisguiseMale) ||
|
||||
player.HasAura(DalaranConst.SpellSilverConenantDisguiseFemale) || player.HasAura(DalaranConst.SpellSilverConenantDisguiseMale))
|
||||
return;
|
||||
|
||||
switch (me.GetEntry())
|
||||
{
|
||||
case 29254:
|
||||
if (player.GetTeam() == Team.Horde) // Horde unit found in Alliance area
|
||||
{
|
||||
if (GetClosestCreatureWithEntry(me, DalaranConst.NpcAplleboughA, 32.0f))
|
||||
{
|
||||
if (me.isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me
|
||||
DoCast(who, DalaranConst.SpellTrespasserA); // Teleport the Horde unit out
|
||||
}
|
||||
else // In my line of sight, and "indoors"
|
||||
DoCast(who, DalaranConst.SpellTrespasserA); // Teleport the Horde unit out
|
||||
}
|
||||
break;
|
||||
case 29255:
|
||||
if (player.GetTeam() == Team.Alliance) // Alliance unit found in Horde area
|
||||
{
|
||||
if (GetClosestCreatureWithEntry(me, DalaranConst.NpcSweetberryH, 32.0f))
|
||||
{
|
||||
if (me.isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me
|
||||
DoCast(who, DalaranConst.SpellTrespasserH); // Teleport the Alliance unit out
|
||||
}
|
||||
else // In my line of sight, and "indoors"
|
||||
DoCast(who, DalaranConst.SpellTrespasserH); // Teleport the Alliance unit out
|
||||
}
|
||||
break;
|
||||
}
|
||||
me.SetOrientation(me.GetHomePosition().GetOrientation());
|
||||
return;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff) { }
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_minigob_manabonk : ScriptedAI
|
||||
{
|
||||
public npc_minigob_manabonk(Creature creature) : base(creature)
|
||||
{
|
||||
me.setActive(true);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
me.SetVisible(false);
|
||||
_events.ScheduleEvent(DalaranConst.EventSelectTarget, Time.InMilliseconds);
|
||||
}
|
||||
|
||||
Player SelectTargetInDalaran()
|
||||
{
|
||||
List<Player> PlayerInDalaranList = new List<Player>();
|
||||
|
||||
var players = me.GetMap().GetPlayers();
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player.GetZoneId() == me.GetZoneId() && !player.IsFlying() && !player.IsMounted() && !player.IsGameMaster())
|
||||
PlayerInDalaranList.Add(player);
|
||||
}
|
||||
|
||||
if (PlayerInDalaranList.Empty())
|
||||
return null;
|
||||
|
||||
return PlayerInDalaranList.SelectRandom();
|
||||
}
|
||||
|
||||
void SendMailToPlayer(Player player)
|
||||
{
|
||||
SQLTransaction trans = new SQLTransaction();
|
||||
uint deliverDelay = RandomHelper.URand(DalaranConst.MailDeliverDelayMin, DalaranConst.MailDeliverDelayMax);
|
||||
new MailDraft(DalaranConst.MailMinigobEntry, true).SendMailTo(trans, new MailReceiver(player), new MailSender(MailMessageType.Creature, me.GetEntry()), MailCheckMask.None, deliverDelay);
|
||||
DB.Characters.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case DalaranConst.EventSelectTarget:
|
||||
me.SetVisible(true);
|
||||
DoCast(me, DalaranConst.SpellTeleportVisual);
|
||||
Player player = SelectTargetInDalaran();
|
||||
if (player)
|
||||
{
|
||||
me.NearTeleportTo(player.GetPositionX(), player.GetPositionY(), player.GetPositionZ(), 0.0f);
|
||||
DoCast(player, DalaranConst.SpellManabonked);
|
||||
SendMailToPlayer(player);
|
||||
}
|
||||
_events.ScheduleEvent(DalaranConst.EventBlink, 3 * Time.InMilliseconds);
|
||||
break;
|
||||
case DalaranConst.EventBlink:
|
||||
{
|
||||
DoCast(me, DalaranConst.SpellImprovedBlink);
|
||||
Position pos = me.GetRandomNearPosition(RandomHelper.FRand(15, 40));
|
||||
me.GetMotionMaster().MovePoint(0, pos.posX, pos.posY, pos.posZ);
|
||||
_events.ScheduleEvent(DalaranConst.EventDespawn, 3 * Time.InMilliseconds);
|
||||
_events.ScheduleEvent(DalaranConst.EventDespawnVisual, (uint)(2.5 * Time.InMilliseconds));
|
||||
break;
|
||||
}
|
||||
case DalaranConst.EventDespawnVisual:
|
||||
DoCast(me, DalaranConst.SpellTeleportVisual);
|
||||
break;
|
||||
case DalaranConst.EventDespawn:
|
||||
me.DespawnOrUnsummon();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* 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 System;
|
||||
|
||||
namespace Scripts.Northrend.DraktharonKeep.KingDred
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint BellowingRoar = 22686; // Fears The Group; Can Be Resisted/Dispelled
|
||||
public const uint GrievousBite = 48920;
|
||||
public const uint ManglingSlash = 48873; // Cast On The Current Tank; Adds Debuf
|
||||
public const uint FearsomeRoar = 48849;
|
||||
public const uint PiercingSlash = 48878; // Debuff --> Armor Reduced By 75%
|
||||
public const uint RaptorCall = 59416; // Dummy
|
||||
public const uint GutRip = 49710;
|
||||
public const uint Rend = 13738;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const int ActionRaptorKilled = 1;
|
||||
public const uint DataRaptorsKilled = 2;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_king_dred : BossAI
|
||||
{
|
||||
public boss_king_dred(Creature creature) : base(creature, DTKDataTypes.KingDred)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
raptorsKilled = 0;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
_Reset();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(33), task =>
|
||||
{
|
||||
DoCastAOE(SpellIds.BellowingRoar);
|
||||
task.Repeat();
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.GrievousBite);
|
||||
task.Repeat();
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(18.5), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.ManglingSlash);
|
||||
task.Repeat();
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastAOE(SpellIds.FearsomeRoar);
|
||||
task.Repeat();
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(17), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.PiercingSlash);
|
||||
task.Repeat();
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.RaptorCall);
|
||||
|
||||
float x, y, z;
|
||||
me.GetClosePoint(out x, out y, out z, me.GetObjectSize() / 3, 10.0f);
|
||||
me.SummonCreature(RandomHelper.RAND(DTKCreatureIds.DrakkariGutripper, DTKCreatureIds.DrakkariScytheclaw), x, y, z, 0, TempSummonType.DeadDespawn, 1000);
|
||||
task.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
if (action == Misc.ActionRaptorKilled)
|
||||
++raptorsKilled;
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
if (type == Misc.DataRaptorsKilled)
|
||||
return raptorsKilled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
byte raptorsKilled;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_drakkari_gutripper : ScriptedAI
|
||||
{
|
||||
public npc_drakkari_gutripper(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = me.GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.GutRip, false);
|
||||
task.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Creature dred = ObjectAccessor.GetCreature(me, instance.GetGuidData(DTKDataTypes.KingDred));
|
||||
if (dred)
|
||||
dred.GetAI().DoAction(Misc.ActionRaptorKilled);
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_drakkari_scytheclaw : ScriptedAI
|
||||
{
|
||||
public npc_drakkari_scytheclaw(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = me.GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Rend, false);
|
||||
task.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Creature dred = ObjectAccessor.GetCreature(me, instance.GetGuidData(DTKDataTypes.KingDred));
|
||||
if (dred)
|
||||
dred.GetAI().DoAction(Misc.ActionRaptorKilled);
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_king_dred : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_king_dred() : base("achievement_king_dred") { }
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Creature dred = target.ToCreature();
|
||||
if (dred)
|
||||
if (dred.GetAI().GetData(Misc.DataRaptorsKilled) >= 6)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace Scripts.Northrend.DraktharonKeep.Novos
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SayKill = 1;
|
||||
public const uint SayDeath = 2;
|
||||
public const uint SaySummoningAdds = 3; // Unused
|
||||
public const uint SayArcaneField = 4;
|
||||
public const uint EmoteSummoningAdds = 5; // Unused
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint BeamChannel = 52106;
|
||||
public const uint ArcaneField = 47346;
|
||||
|
||||
public const uint SummonRisenShadowcaster = 49105;
|
||||
public const uint SummonFetidTrollCorpse = 49103;
|
||||
public const uint SummonHulkingCorpse = 49104;
|
||||
public const uint SummonCrystalHandler = 49179; //not used
|
||||
public const uint SummonCopyOfMinions = 59933; //not used
|
||||
|
||||
public const uint ArcaneBlast = 49198;
|
||||
public const uint Blizzard = 49034;
|
||||
public const uint Frostbolt = 49037;
|
||||
public const uint WrathOfMisery = 50089;
|
||||
public const uint SummonMinions = 59910;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const int ActionResetCrystals = 0;
|
||||
public const int ActionActivateCrystal = 1;
|
||||
public const int ActionDeactivate = 2;
|
||||
public const uint EventAttack = 3;
|
||||
public const uint EventSummonMinions = 4;
|
||||
public const uint EventSummonRisenShadowcaster = 5;
|
||||
public const uint EventSummonFetidTrollCorpse = 6;
|
||||
public const uint EventSummonHulkingCorpse = 7;
|
||||
public const uint EventSummonCrystalHandler = 8;
|
||||
public const uint DataNovosAchiev = 9;
|
||||
|
||||
public static SummonerInfo[] summoners =
|
||||
{
|
||||
new SummonerInfo(EventSummonRisenShadowcaster, 7),
|
||||
new SummonerInfo(EventSummonFetidTrollCorpse, 3),
|
||||
new SummonerInfo(EventSummonHulkingCorpse, 30),
|
||||
new SummonerInfo(EventSummonCrystalHandler, 15)
|
||||
};
|
||||
|
||||
public struct SummonerInfo
|
||||
{
|
||||
public SummonerInfo(uint _eventid, uint _timer)
|
||||
{
|
||||
eventId = _eventid;
|
||||
timer = _timer;
|
||||
}
|
||||
|
||||
public uint eventId;
|
||||
public uint timer;
|
||||
}
|
||||
|
||||
public static Position[] SummonPositions =
|
||||
{
|
||||
new Position(-306.8209f, -703.7687f, 27.2919f, 3.401838f),
|
||||
new Position(-421.395f, -705.7863f, 28.57594f, 4.830696f),
|
||||
new Position(-308.1955f, -704.8419f, 27.2919f, 3.010279f),
|
||||
new Position(-424.1306f, -705.7354f, 28.57594f, 5.325676f)
|
||||
};
|
||||
|
||||
public const float MaxYCoordOhNovosMAX = -771.95f;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_novos : BossAI
|
||||
{
|
||||
public boss_novos(Creature creature) : base(creature, DTKDataTypes.Novos)
|
||||
{
|
||||
Initialize();
|
||||
_bubbled = false;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_ohNovos = true;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
|
||||
Initialize();
|
||||
SetCrystalsStatus(false);
|
||||
SetSummonerStatus(false);
|
||||
SetBubbled(false);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit victim)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(TextIds.SayAggro);
|
||||
|
||||
SetCrystalsStatus(true);
|
||||
SetSummonerStatus(true);
|
||||
SetBubbled(true);
|
||||
}
|
||||
|
||||
public override void AttackStart(Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (me.Attack(target, true))
|
||||
DoStartNoMovement(target);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.IsTypeId(TypeId.Player))
|
||||
Talk(TextIds.SayKill);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(TextIds.SayDeath);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim() || _bubbled)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Misc.EventSummonMinions:
|
||||
DoCast(SpellIds.SummonMinions);
|
||||
_events.ScheduleEvent(Misc.EventSummonMinions, 15000);
|
||||
break;
|
||||
case Misc.EventAttack:
|
||||
Unit victim = SelectTarget(SelectAggroTarget.Random);
|
||||
if (victim)
|
||||
DoCast(victim, RandomHelper.RAND(SpellIds.ArcaneBlast, SpellIds.Blizzard, SpellIds.Frostbolt, SpellIds.WrathOfMisery));
|
||||
_events.ScheduleEvent(Misc.EventAttack, 3000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
if (action == DTKDataTypes.ActionCrystalHandlerDied)
|
||||
{
|
||||
Talk(TextIds.SayArcaneField);
|
||||
SetSummonerStatus(false);
|
||||
SetBubbled(false);
|
||||
_events.ScheduleEvent(Misc.EventAttack, 3000);
|
||||
if (IsHeroic())
|
||||
_events.ScheduleEvent(Misc.EventSummonMinions, 15000);
|
||||
}
|
||||
}
|
||||
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
base.MoveInLineOfSight(who);
|
||||
|
||||
if (!_ohNovos || !who || !who.IsTypeId(TypeId.Player) || who.GetPositionY() > Misc.MaxYCoordOhNovosMAX)
|
||||
return;
|
||||
|
||||
uint entry = who.GetEntry();
|
||||
if (entry == DTKCreatureIds.HulkingCorpse || entry == DTKCreatureIds.RisenShadowcaster || entry == DTKCreatureIds.FetidTrollCorpse)
|
||||
_ohNovos = false;
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
return type == Misc.DataNovosAchiev && _ohNovos ? 1 : 0u;
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
me.Yell(TextIds.SaySummoningAdds, summon);
|
||||
me.TextEmote(TextIds.EmoteSummoningAdds, summon);
|
||||
|
||||
summon.SelectNearestTargetInAttackDistance(50f);
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SetBubbled(bool state)
|
||||
{
|
||||
_bubbled = state;
|
||||
if (!state)
|
||||
{
|
||||
if (me.HasFlag(UnitFields.Flags, UnitFlags.NonAttackable))
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
me.CastStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!me.HasFlag(UnitFields.Flags, UnitFlags.NonAttackable))
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
DoCast(SpellIds.ArcaneField);
|
||||
}
|
||||
}
|
||||
|
||||
void SetSummonerStatus(bool active)
|
||||
{
|
||||
for (byte i = 0; i < 4; i++)
|
||||
{
|
||||
ObjectGuid guid = instance.GetGuidData(DTKDataTypes.NovosSummoner1 + i);
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
Creature crystalChannelTarget = ObjectAccessor.GetCreature(me, guid);
|
||||
if (crystalChannelTarget)
|
||||
{
|
||||
if (active)
|
||||
crystalChannelTarget.GetAI().SetData(Misc.summoners[i].eventId, Misc.summoners[i].timer);
|
||||
else
|
||||
crystalChannelTarget.GetAI().Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetCrystalsStatus(bool active)
|
||||
{
|
||||
for (byte i = 0; i < 4; i++)
|
||||
{
|
||||
ObjectGuid guid = instance.GetGuidData(DTKDataTypes.NovosCrystal1 + i);
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
GameObject crystal = ObjectAccessor.GetGameObject(me, guid);
|
||||
if (crystal)
|
||||
SetCrystalStatus(crystal, active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetCrystalStatus(GameObject crystal, bool active)
|
||||
{
|
||||
crystal.SetGoState(active ? GameObjectState.Active : GameObjectState.Ready);
|
||||
|
||||
Creature crystalChannelTarget = crystal.FindNearestCreature(DTKCreatureIds.CrystalChannelTarget, 5.0f);
|
||||
if (crystalChannelTarget)
|
||||
{
|
||||
if (active)
|
||||
crystalChannelTarget.CastSpell(null, SpellIds.BeamChannel);
|
||||
else if (crystalChannelTarget.HasUnitState(UnitState.Casting))
|
||||
crystalChannelTarget.CastStop();
|
||||
}
|
||||
}
|
||||
|
||||
bool _ohNovos;
|
||||
bool _bubbled;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_crystal_channel_target : ScriptedAI
|
||||
{
|
||||
public npc_crystal_channel_target(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.Reset();
|
||||
_crystalHandlerCount = 0;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Misc.EventSummonCrystalHandler:
|
||||
me.SummonCreature(DTKCreatureIds.CrystalHandler, Misc.SummonPositions[_crystalHandlerCount++]);
|
||||
if (_crystalHandlerCount < 4)
|
||||
_events.Repeat(TimeSpan.FromSeconds(15));
|
||||
break;
|
||||
case Misc.EventSummonRisenShadowcaster:
|
||||
DoCast(SpellIds.SummonRisenShadowcaster);
|
||||
_events.Repeat(TimeSpan.FromSeconds(7));
|
||||
break;
|
||||
case Misc.EventSummonFetidTrollCorpse:
|
||||
DoCast(SpellIds.SummonFetidTrollCorpse);
|
||||
_events.Repeat(TimeSpan.FromSeconds(3));
|
||||
break;
|
||||
case Misc.EventSummonHulkingCorpse:
|
||||
DoCast(SpellIds.SummonHulkingCorpse);
|
||||
_events.Repeat(TimeSpan.FromSeconds(30));
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void SetData(uint id, uint value)
|
||||
{
|
||||
_events.ScheduleEvent(id, TimeSpan.FromSeconds(value));
|
||||
}
|
||||
|
||||
public override void SummonedCreatureDies(Creature summon, Unit killer)
|
||||
{
|
||||
if (_crystalHandlerCount < 4)
|
||||
return;
|
||||
|
||||
InstanceScript instance = me.GetInstanceScript();
|
||||
if (instance != null)
|
||||
{
|
||||
ObjectGuid guid = instance.GetGuidData(DTKDataTypes.Novos);
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
Creature novos = ObjectAccessor.GetCreature(me, guid);
|
||||
if (novos)
|
||||
novos.GetAI().DoAction(DTKDataTypes.ActionCrystalHandlerDied);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
InstanceScript instance = me.GetInstanceScript();
|
||||
if (instance != null)
|
||||
{
|
||||
ObjectGuid guid = instance.GetGuidData(DTKDataTypes.Novos);
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
Creature novos = ObjectAccessor.GetCreature(me, guid);
|
||||
if (novos)
|
||||
novos.GetAI().JustSummoned(summon);
|
||||
}
|
||||
}
|
||||
|
||||
if (summon)
|
||||
summon.GetMotionMaster().MovePath(summon.GetEntry() * 100, false);
|
||||
}
|
||||
|
||||
uint _crystalHandlerCount;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_oh_novos : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_oh_novos() : base("achievement_oh_novos") { }
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
return target && target.IsTypeId(TypeId.Unit) && target.ToCreature().GetAI().GetData(Misc.DataNovosAchiev) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_novos_summon_minions : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SummonCopyOfMinions);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
for (byte i = 0; i < 2; ++i)
|
||||
GetCaster().CastSpell((Unit)null, SpellIds.SummonCopyOfMinions, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
|
||||
namespace Scripts.Northrend.DraktharonKeep.TharonJa
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
// Skeletal Spells (Phase 1)
|
||||
public const uint CurseOfLife = 49527;
|
||||
public const uint RainOfFire = 49518;
|
||||
public const uint ShadowVolley = 49528;
|
||||
public const uint DecayFlesh = 49356; // Cast At End Of Phase 1; Starts Phase 2
|
||||
// Flesh Spells (Phase 2)
|
||||
public const uint GiftOfTharonJa = 52509;
|
||||
public const uint ClearGiftOfTharonJa = 53242;
|
||||
public const uint EyeBeam = 49544;
|
||||
public const uint LightningBreath = 49537;
|
||||
public const uint PoisonCloud = 49548;
|
||||
public const uint ReturnFlesh = 53463; // Channeled Spell Ending Phase Two And Returning To Phase 1. This Ability Will Stun The Party For 6 Seconds.
|
||||
public const uint AchievementCheck = 61863;
|
||||
public const uint FleshVisual = 52582;
|
||||
public const uint Dummy = 49551;
|
||||
}
|
||||
|
||||
struct EventIds
|
||||
{
|
||||
public const uint CurseOfLife = 1;
|
||||
public const uint RainOfFire = 2;
|
||||
public const uint ShadowVolley = 3;
|
||||
|
||||
public const uint EyeBeam = 4;
|
||||
public const uint LightningBreath = 5;
|
||||
public const uint PoisonCloud = 6;
|
||||
|
||||
public const uint DecayFlesh = 7;
|
||||
public const uint GoingFlesh = 8;
|
||||
public const uint ReturnFlesh = 9;
|
||||
public const uint GoingSkeletal = 10;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SayKill = 1;
|
||||
public const uint SayFlesh = 2;
|
||||
public const uint SaySkeleton = 3;
|
||||
public const uint SayDeath = 4;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint ModelFlesh = 27073;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_tharon_ja : BossAI
|
||||
{
|
||||
public boss_tharon_ja(Creature creature) : base(creature, DTKDataTypes.TharonJa) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
me.RestoreDisplayId();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
Talk(TextIds.SayAggro);
|
||||
_EnterCombat();
|
||||
|
||||
_events.ScheduleEvent(EventIds.DecayFlesh, TimeSpan.FromSeconds(20));
|
||||
_events.ScheduleEvent(EventIds.CurseOfLife, TimeSpan.FromSeconds(1));
|
||||
_events.ScheduleEvent(EventIds.RainOfFire, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(18));
|
||||
_events.ScheduleEvent(EventIds.ShadowVolley, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10));
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.IsTypeId(TypeId.Player))
|
||||
Talk(TextIds.SayKill);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
|
||||
Talk(TextIds.SayDeath);
|
||||
DoCastAOE(SpellIds.ClearGiftOfTharonJa, true);
|
||||
DoCastAOE(SpellIds.AchievementCheck, true);
|
||||
}
|
||||
|
||||
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.CurseOfLife:
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.CurseOfLife);
|
||||
_events.ScheduleEvent(EventIds.CurseOfLife, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
|
||||
}
|
||||
return;
|
||||
case EventIds.ShadowVolley:
|
||||
DoCastVictim(SpellIds.ShadowVolley);
|
||||
_events.ScheduleEvent(EventIds.ShadowVolley, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10));
|
||||
return;
|
||||
case EventIds.RainOfFire:
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.RainOfFire);
|
||||
_events.ScheduleEvent(EventIds.RainOfFire, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(18));
|
||||
}
|
||||
return;
|
||||
case EventIds.LightningBreath:
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.LightningBreath);
|
||||
_events.ScheduleEvent(EventIds.LightningBreath, TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(7));
|
||||
}
|
||||
return;
|
||||
case EventIds.EyeBeam:
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.EyeBeam);
|
||||
_events.ScheduleEvent(EventIds.EyeBeam, TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(6));
|
||||
}
|
||||
return;
|
||||
case EventIds.PoisonCloud:
|
||||
DoCastAOE(SpellIds.PoisonCloud);
|
||||
_events.ScheduleEvent(EventIds.PoisonCloud, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(12));
|
||||
return;
|
||||
case EventIds.DecayFlesh:
|
||||
DoCastAOE(SpellIds.DecayFlesh);
|
||||
_events.ScheduleEvent(EventIds.GoingFlesh, TimeSpan.FromSeconds(6));
|
||||
return;
|
||||
case EventIds.GoingFlesh:
|
||||
Talk(TextIds.SayFlesh);
|
||||
me.SetDisplayId(Misc.ModelFlesh);
|
||||
DoCastAOE(SpellIds.GiftOfTharonJa, true);
|
||||
DoCast(me, SpellIds.FleshVisual, true);
|
||||
DoCast(me, SpellIds.Dummy, true);
|
||||
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EventIds.ReturnFlesh, TimeSpan.FromSeconds(20));
|
||||
_events.ScheduleEvent(EventIds.LightningBreath, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(4));
|
||||
_events.ScheduleEvent(EventIds.EyeBeam, TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8));
|
||||
_events.ScheduleEvent(EventIds.PoisonCloud, TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(7));
|
||||
break;
|
||||
case EventIds.ReturnFlesh:
|
||||
DoCastAOE(SpellIds.ReturnFlesh);
|
||||
_events.ScheduleEvent(EventIds.GoingSkeletal, 6000);
|
||||
return;
|
||||
case EventIds.GoingSkeletal:
|
||||
Talk(TextIds.SaySkeleton);
|
||||
me.RestoreDisplayId();
|
||||
DoCastAOE(SpellIds.ClearGiftOfTharonJa, true);
|
||||
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EventIds.DecayFlesh, TimeSpan.FromSeconds(20));
|
||||
_events.ScheduleEvent(EventIds.CurseOfLife, TimeSpan.FromSeconds(1));
|
||||
_events.ScheduleEvent(EventIds.RainOfFire, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(18));
|
||||
_events.ScheduleEvent(EventIds.ShadowVolley, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_tharon_ja_clear_gift_of_tharon_ja : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.GiftOfTharonJa);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
target.RemoveAura(SpellIds.GiftOfTharonJa);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
|
||||
namespace Scripts.Northrend.DraktharonKeep.Trollgore
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint InfectedWound = 49637;
|
||||
public const uint Crush = 49639;
|
||||
public const uint CorpseExplode = 49555;
|
||||
public const uint CorpseExplodeDamage = 49618;
|
||||
public const uint Consume = 49380;
|
||||
public const uint ConsumeBuff = 49381;
|
||||
public const uint ConsumeBuffH = 59805;
|
||||
|
||||
public const uint SummonInvaderA = 49456;
|
||||
public const uint SummonInvaderB = 49457;
|
||||
public const uint SummonInvaderC = 49458; // Can'T Find Any Sniffs
|
||||
|
||||
public const uint InvaderTaunt = 49405;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SayKill = 1;
|
||||
public const uint SayConsume = 2;
|
||||
public const uint SayExplode = 3;
|
||||
public const uint SayDeath = 4;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint DataConsumptionJunction = 1;
|
||||
public const uint PointLanding = 1;
|
||||
|
||||
public static Position Landing = new Position(-263.0534f, -660.8658f, 26.50903f, 0.0f);
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_trollgore : BossAI
|
||||
{
|
||||
public boss_trollgore(Creature creature) : base(creature, DTKDataTypes.Trollgore)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_consumptionJunction = true;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(TextIds.SayAggro);
|
||||
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
Talk(TextIds.SayConsume);
|
||||
DoCastAOE(SpellIds.Consume);
|
||||
task.Repeat();
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Crush);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.InfectedWound);
|
||||
task.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(3), task =>
|
||||
{
|
||||
Talk(TextIds.SayExplode);
|
||||
DoCastAOE(SpellIds.CorpseExplode);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(40), task =>
|
||||
{
|
||||
for (byte i = 0; i < 3; ++i)
|
||||
{
|
||||
Creature trigger = ObjectAccessor.GetCreature(me, instance.GetGuidData(DTKDataTypes.TrollgoreInvaderSummoner1 + i));
|
||||
if (trigger)
|
||||
trigger.CastSpell(trigger, RandomHelper.RAND(SpellIds.SummonInvaderA, SpellIds.SummonInvaderB, SpellIds.SummonInvaderC), true, null, null, me.GetGUID());
|
||||
}
|
||||
|
||||
task.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
if (_consumptionJunction)
|
||||
{
|
||||
Aura ConsumeAura = me.GetAura(DungeonMode(SpellIds.ConsumeBuff, SpellIds.ConsumeBuffH));
|
||||
if (ConsumeAura != null && ConsumeAura.GetStackAmount() > 9)
|
||||
_consumptionJunction = false;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(TextIds.SayDeath);
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
if (type == Misc.DataConsumptionJunction)
|
||||
return _consumptionJunction ? 1 : 0u;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (victim.IsTypeId(TypeId.Player))
|
||||
Talk(TextIds.SayKill);
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
summon.GetMotionMaster().MovePoint(Misc.PointLanding, Misc.Landing);
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
bool _consumptionJunction;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_drakkari_invader : ScriptedAI
|
||||
{
|
||||
public npc_drakkari_invader(Creature creature) : base(creature) { }
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint pointId)
|
||||
{
|
||||
if (type == MovementGeneratorType.Point && pointId == Misc.PointLanding)
|
||||
{
|
||||
me.Dismount();
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.ImmuneToNpc);
|
||||
DoCastAOE(SpellIds.InvaderTaunt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 49380, 59803 - Consume
|
||||
class spell_trollgore_consume : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ConsumeBuff);
|
||||
}
|
||||
|
||||
void HandleConsume(uint effIndex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
target.CastSpell(GetCaster(), SpellIds.ConsumeBuff, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleConsume, 1, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 49555, 59807 - Corpse Explode
|
||||
class spell_trollgore_corpse_explode : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.CorpseExplodeDamage);
|
||||
}
|
||||
|
||||
void PeriodicTick(AuraEffect aurEff)
|
||||
{
|
||||
if (aurEff.GetTickNumber() == 2)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
caster.CastSpell(GetTarget(), SpellIds.CorpseExplodeDamage, true, null, aurEff);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Creature target = GetTarget().ToCreature();
|
||||
if (target)
|
||||
target.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(PeriodicTick, 0, AuraType.Dummy));
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(HandleRemove, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 49405 - Invader Taunt Trigger
|
||||
class spell_trollgore_invader_taunt : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo((uint)spellInfo.GetEffect(0).CalcValue());
|
||||
}
|
||||
|
||||
void HandleTaunt(uint effIndex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
target.CastSpell(GetCaster(), (uint)GetEffectValue(), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleTaunt, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_consumption_junction : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_consumption_junction() : base("achievement_consumption_junction") { }
|
||||
|
||||
public override bool OnCheck(Player source, Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Creature Trollgore = target.ToCreature();
|
||||
if (Trollgore)
|
||||
if (Trollgore.GetAI().GetData(Misc.DataConsumptionJunction) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* 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 Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
|
||||
namespace Scripts.Northrend.DraktharonKeep
|
||||
{
|
||||
struct DTKDataTypes
|
||||
{
|
||||
// Encounter States/Boss Guids
|
||||
public const uint Trollgore = 0;
|
||||
public const uint Novos = 1;
|
||||
public const uint KingDred = 2;
|
||||
public const uint TharonJa = 3;
|
||||
|
||||
// Additional Data
|
||||
//public const uint KingDredAchiev;
|
||||
|
||||
public const uint TrollgoreInvaderSummoner1 = 4;
|
||||
public const uint TrollgoreInvaderSummoner2 = 5;
|
||||
public const uint TrollgoreInvaderSummoner3 = 6;
|
||||
|
||||
public const uint NovosCrystal1 = 7;
|
||||
public const uint NovosCrystal2 = 8;
|
||||
public const uint NovosCrystal3 = 9;
|
||||
public const uint NovosCrystal4 = 10;
|
||||
public const uint NovosSummoner1 = 11;
|
||||
public const uint NovosSummoner2 = 12;
|
||||
public const uint NovosSummoner3 = 13;
|
||||
public const uint NovosSummoner4 = 14;
|
||||
|
||||
public const int ActionCrystalHandlerDied = 15;
|
||||
}
|
||||
|
||||
struct DTKCreatureIds
|
||||
{
|
||||
public const uint Trollgore = 26630;
|
||||
public const uint Novos = 26631;
|
||||
public const uint KingDred = 27483;
|
||||
public const uint TharonJa = 26632;
|
||||
|
||||
// Trollgore
|
||||
public const uint DrakkariInvaderA = 27709;
|
||||
public const uint DrakkariInvaderB = 27753;
|
||||
public const uint DrakkariInvaderC = 27754;
|
||||
|
||||
// Novos
|
||||
public const uint CrystalChannelTarget = 26712;
|
||||
public const uint CrystalHandler = 26627;
|
||||
public const uint HulkingCorpse = 27597;
|
||||
public const uint FetidTrollCorpse = 27598;
|
||||
public const uint RisenShadowcaster = 27600;
|
||||
|
||||
// King Dred
|
||||
public const uint DrakkariGutripper = 26641;
|
||||
public const uint DrakkariScytheclaw = 26628;
|
||||
|
||||
public const uint WorldTrigger = 22515;
|
||||
}
|
||||
|
||||
struct DTKGameObjectIds
|
||||
{
|
||||
public const uint NovosCrystal1 = 189299;
|
||||
public const uint NovosCrystal2 = 189300;
|
||||
public const uint NovosCrystal3 = 189301;
|
||||
public const uint NovosCrystal4 = 189302;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class instance_drak_tharon_keep : InstanceMapScript
|
||||
{
|
||||
public instance_drak_tharon_keep() : base(nameof(instance_drak_tharon_keep), 600) { }
|
||||
|
||||
class instance_drak_tharon_keep_InstanceScript : InstanceScript
|
||||
{
|
||||
public instance_drak_tharon_keep_InstanceScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("DTK");
|
||||
SetBossNumber(4);
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case DTKCreatureIds.Trollgore:
|
||||
TrollgoreGUID = creature.GetGUID();
|
||||
break;
|
||||
case DTKCreatureIds.Novos:
|
||||
NovosGUID = creature.GetGUID();
|
||||
break;
|
||||
case DTKCreatureIds.KingDred:
|
||||
KingDredGUID = creature.GetGUID();
|
||||
break;
|
||||
case DTKCreatureIds.TharonJa:
|
||||
TharonJaGUID = creature.GetGUID();
|
||||
break;
|
||||
case DTKCreatureIds.WorldTrigger:
|
||||
InitializeTrollgoreInvaderSummoner(creature);
|
||||
break;
|
||||
case DTKCreatureIds.CrystalChannelTarget:
|
||||
InitializeNovosSummoner(creature);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case DTKGameObjectIds.NovosCrystal1:
|
||||
NovosCrystalGUIDs[0] = go.GetGUID();
|
||||
break;
|
||||
case DTKGameObjectIds.NovosCrystal2:
|
||||
NovosCrystalGUIDs[1] = go.GetGUID();
|
||||
break;
|
||||
case DTKGameObjectIds.NovosCrystal3:
|
||||
NovosCrystalGUIDs[2] = go.GetGUID();
|
||||
break;
|
||||
case DTKGameObjectIds.NovosCrystal4:
|
||||
NovosCrystalGUIDs[3] = go.GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeTrollgoreInvaderSummoner(Creature creature)
|
||||
{
|
||||
float y = creature.GetPositionY();
|
||||
float z = creature.GetPositionZ();
|
||||
|
||||
if (z < 50.0f)
|
||||
return;
|
||||
|
||||
if (y < -650.0f && y > -660.0f)
|
||||
TrollgoreInvaderSummonerGuids[0] = creature.GetGUID();
|
||||
else if (y < -660.0f && y > -670.0f)
|
||||
TrollgoreInvaderSummonerGuids[1] = creature.GetGUID();
|
||||
else if (y < -675.0f && y > -685.0f)
|
||||
TrollgoreInvaderSummonerGuids[2] = creature.GetGUID();
|
||||
}
|
||||
|
||||
void InitializeNovosSummoner(Creature creature)
|
||||
{
|
||||
float x = creature.GetPositionX();
|
||||
float y = creature.GetPositionY();
|
||||
float z = creature.GetPositionZ();
|
||||
|
||||
if (x < -374.0f && x > -379.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f)
|
||||
NovosSummonerGUIDs[0] = creature.GetGUID();
|
||||
else if (x < -379.0f && x > -385.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f)
|
||||
NovosSummonerGUIDs[1] = creature.GetGUID();
|
||||
else if (x < -374.0f && x > -385.0f && y > -827.0f && y < -820.0f && z < 60.0f && z > 58.0f)
|
||||
NovosSummonerGUIDs[2] = creature.GetGUID();
|
||||
else if (x < -338.0f && x > -380.0f && y > -727.0f && y < 721.0f && z < 30.0f && z > 26.0f)
|
||||
NovosSummonerGUIDs[3] = creature.GetGUID();
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DTKDataTypes.Trollgore:
|
||||
return TrollgoreGUID;
|
||||
case DTKDataTypes.Novos:
|
||||
return NovosGUID;
|
||||
case DTKDataTypes.KingDred:
|
||||
return KingDredGUID;
|
||||
case DTKDataTypes.TharonJa:
|
||||
return TharonJaGUID;
|
||||
case DTKDataTypes.TrollgoreInvaderSummoner1:
|
||||
case DTKDataTypes.TrollgoreInvaderSummoner2:
|
||||
case DTKDataTypes.TrollgoreInvaderSummoner3:
|
||||
return TrollgoreInvaderSummonerGuids[type - DTKDataTypes.TrollgoreInvaderSummoner1];
|
||||
case DTKDataTypes.NovosCrystal1:
|
||||
case DTKDataTypes.NovosCrystal2:
|
||||
case DTKDataTypes.NovosCrystal3:
|
||||
case DTKDataTypes.NovosCrystal4:
|
||||
return NovosCrystalGUIDs[type - DTKDataTypes.NovosCrystal1];
|
||||
case DTKDataTypes.NovosSummoner1:
|
||||
case DTKDataTypes.NovosSummoner2:
|
||||
case DTKDataTypes.NovosSummoner3:
|
||||
case DTKDataTypes.NovosSummoner4:
|
||||
return NovosSummonerGUIDs[type - DTKDataTypes.NovosSummoner1];
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
ObjectGuid TrollgoreGUID;
|
||||
ObjectGuid NovosGUID;
|
||||
ObjectGuid KingDredGUID;
|
||||
ObjectGuid TharonJaGUID;
|
||||
|
||||
ObjectGuid[] TrollgoreInvaderSummonerGuids = new ObjectGuid[3];
|
||||
ObjectGuid[] NovosCrystalGUIDs = new ObjectGuid[4];
|
||||
ObjectGuid[] NovosSummonerGUIDs = new ObjectGuid[4];
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_drak_tharon_keep_InstanceScript(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls.Bronjahm
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SaySlay = 1;
|
||||
public const uint SayDeath = 2;
|
||||
public const uint SaySoulStorm = 3;
|
||||
public const uint SayCorruptSoul = 4;
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint MagicSBane = 68793;
|
||||
public const uint ShadowBolt = 70043;
|
||||
public const uint CorruptSoul = 68839;
|
||||
public const uint ConsumeSoul = 68861;
|
||||
public const uint Teleport = 68988;
|
||||
public const uint Fear = 68950;
|
||||
public const uint Soulstorm = 68872;
|
||||
public const uint SoulstormChannel = 69008; // Pre-Fight
|
||||
public const uint SoulstormVisual = 68870; // Pre-Cast Soulstorm
|
||||
public const uint PurpleBanishVisual = 68862; // Used By Soul Fragment (Aura)
|
||||
}
|
||||
|
||||
struct EventIds
|
||||
{
|
||||
public const uint MagicBane = 1;
|
||||
public const uint ShadowBolt = 2;
|
||||
public const uint CorruptSoul = 3;
|
||||
public const uint Soulstorm = 4;
|
||||
public const uint Fear = 5;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint DataSoulPower = 1;
|
||||
|
||||
public const byte Phase1 = 1;
|
||||
public const byte Phase2 = 2;
|
||||
|
||||
public static uint[] SoulstormVisualSpells =
|
||||
{
|
||||
68904,
|
||||
68886,
|
||||
68905,
|
||||
68896,
|
||||
68906,
|
||||
68897,
|
||||
68907,
|
||||
68898
|
||||
};
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_bronjahm : BossAI
|
||||
{
|
||||
public boss_bronjahm(Creature creature) : base(creature, DataType.Bronjahm)
|
||||
{
|
||||
DoCast(me, SpellIds.SoulstormChannel, true);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
_events.SetPhase(Misc.Phase1);
|
||||
_events.ScheduleEvent(EventIds.ShadowBolt, 2000);
|
||||
_events.ScheduleEvent(EventIds.MagicBane, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(20));
|
||||
_events.ScheduleEvent(EventIds.CorruptSoul, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35), 0, Misc.Phase1);
|
||||
}
|
||||
|
||||
public override void JustReachedHome()
|
||||
{
|
||||
_JustReachedHome();
|
||||
DoCast(me, SpellIds.SoulstormChannel, true);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(TextIds.SayAggro);
|
||||
me.RemoveAurasDueToSpell(SpellIds.SoulstormChannel);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(TextIds.SayDeath);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.GetTypeId() == TypeId.Player)
|
||||
Talk(TextIds.SaySlay);
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (_events.IsInPhase(Misc.Phase1) && !HealthAbovePct(30))
|
||||
{
|
||||
_events.SetPhase(Misc.Phase2);
|
||||
DoCast(me, SpellIds.Teleport);
|
||||
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16), 0, Misc.Phase2);
|
||||
_events.ScheduleEvent(EventIds.Soulstorm, 100, 0, Misc.Phase2);
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
if (summon.GetEntry() == CreatureIds.CorruptedSoulFragment)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
summon.SetReactState(ReactStates.Passive);
|
||||
summon.GetMotionMaster().MoveFollow(me, me.GetObjectSize(), 0.0f);
|
||||
summon.CastSpell(summon, SpellIds.PurpleBanishVisual, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
if (type == Misc.DataSoulPower)
|
||||
{
|
||||
uint count = 0;
|
||||
foreach (ObjectGuid guid in summons)
|
||||
{
|
||||
Creature summon = ObjectAccessor.GetCreature(me, guid);
|
||||
if (summon)
|
||||
if (summon.GetEntry() == CreatureIds.CorruptedSoulFragment && summon.IsAlive())
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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.MagicBane:
|
||||
DoCastAOE(SpellIds.MagicSBane);
|
||||
_events.ScheduleEvent(EventIds.MagicBane, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(20));
|
||||
break;
|
||||
case EventIds.ShadowBolt:
|
||||
if (_events.IsInPhase(Misc.Phase2))
|
||||
{
|
||||
DoCastVictim(SpellIds.ShadowBolt);
|
||||
_events.ScheduleEvent(EventIds.ShadowBolt, TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!me.IsWithinMeleeRange(me.GetVictim()))
|
||||
DoCastVictim(SpellIds.ShadowBolt);
|
||||
_events.ScheduleEvent(EventIds.ShadowBolt, TimeSpan.FromMilliseconds(2));
|
||||
}
|
||||
break;
|
||||
case EventIds.CorruptSoul:
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 0.0f, true);
|
||||
if (target)
|
||||
{
|
||||
Talk(TextIds.SayCorruptSoul);
|
||||
DoCast(target, SpellIds.CorruptSoul);
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.CorruptSoul, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35), 0, Misc.Phase1);
|
||||
break;
|
||||
case EventIds.Soulstorm:
|
||||
Talk(TextIds.SaySoulStorm);
|
||||
me.CastSpell(me, SpellIds.SoulstormVisual, true);
|
||||
me.CastSpell(me, SpellIds.Soulstorm, false);
|
||||
break;
|
||||
case EventIds.Fear:
|
||||
me.CastCustomSpell(SpellIds.Fear, SpellValueMod.MaxTargets, 1, null, false);
|
||||
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12), 0, Misc.Phase2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
});
|
||||
|
||||
if (!_events.IsInPhase(Misc.Phase2))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_corrupted_soul_fragment : ScriptedAI
|
||||
{
|
||||
public npc_corrupted_soul_fragment(Creature creature) : base(creature)
|
||||
{
|
||||
instance = me.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void IsSummonedBy(Unit summoner)
|
||||
{
|
||||
Creature bronjahm = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataType.Bronjahm));
|
||||
if (bronjahm)
|
||||
bronjahm.GetAI().JustSummoned(me);
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Follow)
|
||||
return;
|
||||
|
||||
if (instance.GetGuidData(DataType.Bronjahm).GetCounter() != id)
|
||||
return;
|
||||
|
||||
me.CastSpell((Unit)null, SpellIds.ConsumeSoul, true);
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_bronjahm_magic_bane : SpellScript
|
||||
{
|
||||
void RecalculateDamage()
|
||||
{
|
||||
if (GetHitUnit().getPowerType() != PowerType.Mana)
|
||||
return;
|
||||
|
||||
int maxDamage = GetCaster().GetMap().IsHeroic() ? 15000 : 10000;
|
||||
int newDamage = GetHitDamage() + (GetHitUnit().GetMaxPower(PowerType.Mana) / 2);
|
||||
|
||||
SetHitDamage(Math.Min(maxDamage, newDamage));
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnHit.Add(new HitHandler(RecalculateDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_bronjahm_consume_soul : SpellScript
|
||||
{
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
GetHitUnit().CastSpell(GetHitUnit(), (uint)GetEffectValue(), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_bronjahm_soulstorm_visual : AuraScript
|
||||
{
|
||||
void HandlePeriodicTick(AuraEffect aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastSpell(GetTarget(), Misc.SoulstormVisualSpells[aurEff.GetTickNumber() % 8], true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodicTick, 0, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_bronjahm_soulstorm_targeting : SpellScript
|
||||
{
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
targets.RemoveAll(target =>
|
||||
{
|
||||
return caster.GetExactDist2d(target) <= 10.0f;
|
||||
});
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, SpellConst.EffectAll, Targets.UnitDestAreaEnemy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_bronjahm_soul_power : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_bronjahm_soul_power() : base("achievement_bronjahm_soul_power") { }
|
||||
|
||||
public override bool OnCheck(Player source, Unit target)
|
||||
{
|
||||
return target && target.GetAI().GetData(Misc.DataSoulPower) >= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Game.Entities;
|
||||
using Framework.Constants;
|
||||
using Game.Scripting;
|
||||
using Game.AI;
|
||||
using Game.Spells;
|
||||
|
||||
namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls.DevourerOfSouls
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayFaceAggro = 0;
|
||||
public const byte SayFaceAngerSlay = 1;
|
||||
public const byte SayFaceSorrowSlay = 2;
|
||||
public const byte SayFaceDesireSlay = 3;
|
||||
public const uint SayFaceDeath = 4;
|
||||
public const uint EmoteMirroredSoul = 5;
|
||||
public const uint EmoteUnleashSoul = 6;
|
||||
public const uint SayFaceUnleashSoul = 7;
|
||||
public const uint EmoteWailingSoul = 8;
|
||||
public const uint SayFaceWailingSoul = 9;
|
||||
|
||||
public const uint SayJainaOutro = 0;
|
||||
public const uint SaySylvanasOutro = 0;
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint PhantomBlast = 68982;
|
||||
public const uint MirroredSoulProcAura = 69023;
|
||||
public const uint MirroredSoulDamage = 69034;
|
||||
public const uint MirroredSoulTargetSelector = 69048;
|
||||
public const uint MirroredSoulBuff = 69051;
|
||||
public const uint WellOfSouls = 68820;
|
||||
public const uint UnleashedSouls = 68939;
|
||||
public const uint WailingSoulsStarting = 68912; // Initial Spell Cast At Begining Of Wailing Souls Phase
|
||||
public const uint WailingSoulsBeam = 68875; // The Beam Visual
|
||||
public const uint WailingSouls = 68873; // The Actual Spell
|
||||
// 68871; 68873; 68875; 68876; 68899; 68912; 70324;
|
||||
// 68899 Trigger 68871
|
||||
}
|
||||
|
||||
struct ModelIds
|
||||
{
|
||||
public const uint Anger = 30148;
|
||||
public const uint Sorrow = 30149;
|
||||
public const uint Desire = 30150;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint DataThreeFaced = 1;
|
||||
|
||||
public static outroPosition[] outroPositions =
|
||||
{
|
||||
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5590.47f, 2427.79f, 705.935f, 0.802851f)),
|
||||
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5593.59f, 2428.34f, 705.935f, 0.977384f)),
|
||||
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5600.81f, 2429.31f, 705.935f, 0.890118f)),
|
||||
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5600.81f, 2421.12f, 705.935f, 0.890118f)),
|
||||
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5601.43f, 2426.53f, 705.935f, 0.890118f)),
|
||||
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5601.55f, 2418.36f, 705.935f, 1.15192f)),
|
||||
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5598, 2429.14f, 705.935f, 1.0472f)),
|
||||
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5594.04f, 2424.87f, 705.935f, 1.15192f)),
|
||||
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5597.89f, 2421.54f, 705.935f, 0.610865f)),
|
||||
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5598.57f, 2434.62f, 705.935f, 1.13446f)),
|
||||
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5585.46f, 2417.99f, 705.935f, 1.06465f)),
|
||||
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5605.81f, 2428.42f, 705.935f, 0.820305f)),
|
||||
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5591.61f, 2412.66f, 705.935f, 0.925025f)),
|
||||
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5593.9f, 2410.64f, 705.935f, 0.872665f)),
|
||||
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5586.76f, 2416.73f, 705.935f, 0.942478f)),
|
||||
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion3Horde, new Position(5592.23f, 2419.14f, 705.935f, 0.855211f)),
|
||||
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion3Horde, new Position(5594.61f, 2416.87f, 705.935f, 0.907571f)),
|
||||
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion3Horde, new Position(5589.77f, 2421.03f, 705.935f, 0.855211f)),
|
||||
|
||||
new outroPosition(CreatureIds.Koreln, CreatureIds.Loralen, new Position(5602.58f, 2435.95f, 705.935f, 0.959931f)),
|
||||
new outroPosition(CreatureIds.Elandra, CreatureIds.Kalira, new Position(5606.13f, 2433.16f, 705.935f, 0.785398f)),
|
||||
new outroPosition(CreatureIds.JainaPart2, CreatureIds.SylvanasPart2, new Position(5606.12f, 2436.6f, 705.935f, 0.890118f)),
|
||||
};
|
||||
|
||||
public static Position CrucibleSummonPos = new Position(5672.294f, 2520.686f, 713.4386f, 0.9599311f);
|
||||
}
|
||||
|
||||
struct outroPosition
|
||||
{
|
||||
public outroPosition(uint allianceEntry, uint hordeEntry, Position movePosition)
|
||||
{
|
||||
Entry = new uint[2];
|
||||
Entry[0] = allianceEntry;
|
||||
Entry[1] = hordeEntry;
|
||||
|
||||
MovePosition = movePosition;
|
||||
}
|
||||
|
||||
public uint[] Entry;
|
||||
public Position MovePosition;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_devourer_of_souls : BossAI
|
||||
{
|
||||
public boss_devourer_of_souls(Creature creature) : base(creature, DataType.DevourerOfSouls)
|
||||
{
|
||||
Initialize();
|
||||
beamAngle = 0.0f;
|
||||
beamAngleDiff = 0.0f;
|
||||
wailingSoulTick = 0;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
threeFaced = true;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
me.SetControlled(false, UnitState.Root);
|
||||
me.SetDisplayId(ModelIds.Anger);
|
||||
me.SetReactState(ReactStates.Aggressive);
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(TextIds.SayFaceAggro);
|
||||
|
||||
if (!me.FindNearestCreature(CreatureIds.CrucibleOfSouls, 60)) // Prevent double spawn
|
||||
me.GetMap().SummonCreature(CreatureIds.CrucibleOfSouls, Misc.CrucibleSummonPos);
|
||||
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.PhantomBlast);
|
||||
task.Repeat(TimeSpan.FromSeconds(5));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
DoCastAOE(SpellIds.MirroredSoulTargetSelector);
|
||||
Talk(TextIds.EmoteMirroredSoul);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.WellOfSouls);
|
||||
task.Repeat(TimeSpan.FromSeconds(20));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.UnleashedSouls);
|
||||
me.SetDisplayId(ModelIds.Sorrow);
|
||||
Talk(TextIds.SayFaceUnleashSoul);
|
||||
Talk(TextIds.EmoteUnleashSoul);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
task.Schedule(TimeSpan.FromSeconds(5), () => me.SetDisplayId(ModelIds.Anger));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), task =>
|
||||
{
|
||||
me.SetDisplayId(ModelIds.Desire);
|
||||
Talk(TextIds.SayFaceWailingSoul);
|
||||
Talk(TextIds.EmoteWailingSoul);
|
||||
DoCast(me, SpellIds.WailingSoulsStarting);
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
{
|
||||
me.SetFacingToObject(target);
|
||||
DoCast(me, SpellIds.WailingSoulsBeam);
|
||||
}
|
||||
|
||||
beamAngle = me.GetOrientation();
|
||||
|
||||
beamAngleDiff = (float)Math.PI / 30.0f; // PI/2 in 15 sec = PI/30 per tick
|
||||
if (RandomHelper.RAND(true, false))
|
||||
beamAngleDiff = -beamAngleDiff;
|
||||
|
||||
me.InterruptNonMeleeSpells(false);
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
|
||||
//Remove any target
|
||||
me.SetTarget(ObjectGuid.Empty);
|
||||
|
||||
me.GetMotionMaster().Clear();
|
||||
me.SetControlled(true, UnitState.Root);
|
||||
|
||||
wailingSoulTick = 15;
|
||||
|
||||
_scheduler.DelayAll(TimeSpan.FromSeconds(18)); // no other events during wailing souls
|
||||
|
||||
// first one after 3 secs.
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(3), tickTask =>
|
||||
{
|
||||
beamAngle += beamAngleDiff;
|
||||
me.SetFacingTo(beamAngle, true);
|
||||
me.StopMoving();
|
||||
|
||||
DoCast(me, SpellIds.WailingSouls);
|
||||
|
||||
if (--wailingSoulTick != 0)
|
||||
tickTask.Repeat(TimeSpan.FromSeconds(1));
|
||||
else
|
||||
{
|
||||
me.SetReactState(ReactStates.Aggressive);
|
||||
me.SetDisplayId(ModelIds.Anger);
|
||||
me.SetControlled(false, UnitState.Root);
|
||||
me.GetMotionMaster().MoveChase(me.GetVictim());
|
||||
task.Repeat(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (victim.GetTypeId() != TypeId.Player)
|
||||
return;
|
||||
|
||||
byte textId = 0;
|
||||
switch (me.GetDisplayId())
|
||||
{
|
||||
case ModelIds.Anger:
|
||||
textId = TextIds.SayFaceAngerSlay;
|
||||
break;
|
||||
case ModelIds.Sorrow:
|
||||
textId = TextIds.SayFaceSorrowSlay;
|
||||
break;
|
||||
case ModelIds.Desire:
|
||||
textId = TextIds.SayFaceDesireSlay;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (textId != 0)
|
||||
Talk(textId);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
|
||||
Position spawnPoint = new Position(5618.139f, 2451.873f, 705.854f, 0);
|
||||
|
||||
Talk(TextIds.SayFaceDeath);
|
||||
|
||||
int entryIndex;
|
||||
if (instance.GetData(DataType.TeamInInstance) == (uint)Team.Alliance)
|
||||
entryIndex = 0;
|
||||
else
|
||||
entryIndex = 1;
|
||||
|
||||
for (var i = 0; Misc.outroPositions[i].Entry[entryIndex] != 0; ++i)
|
||||
{
|
||||
Creature summon = me.SummonCreature(Misc.outroPositions[i].Entry[entryIndex], spawnPoint, TempSummonType.DeadDespawn);
|
||||
if (summon)
|
||||
{
|
||||
summon.GetMotionMaster().MovePoint(0, Misc.outroPositions[i].MovePosition);
|
||||
if (summon.GetEntry() == CreatureIds.JainaPart2)
|
||||
summon.GetAI().Talk(TextIds.SayJainaOutro);
|
||||
else if (summon.GetEntry() == CreatureIds.SylvanasPart2)
|
||||
summon.GetAI().Talk(TextIds.SaySylvanasOutro);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void SpellHitTarget(Unit target, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id == SpellIds.PhantomBlast)
|
||||
threeFaced = false;
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
if (type == Misc.DataThreeFaced)
|
||||
return threeFaced ? 1 : 0u;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool threeFaced;
|
||||
|
||||
// wailing soul event
|
||||
float beamAngle;
|
||||
float beamAngleDiff;
|
||||
sbyte wailingSoulTick;
|
||||
}
|
||||
|
||||
[Script] // 69051 - Mirrored Soul
|
||||
class spell_devourer_of_souls_mirrored_soul : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.MirroredSoulProcAura);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
target.CastSpell(GetCaster(), SpellIds.MirroredSoulProcAura, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 69023 - Mirrored Soul (Proc)
|
||||
class spell_devourer_of_souls_mirrored_soul_proc : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.MirroredSoulDamage);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
return GetCaster() && GetCaster().IsAlive();
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
DamageInfo damageInfo = eventInfo.GetDamageInfo();
|
||||
if (damageInfo == null || damageInfo.GetDamage() == 0)
|
||||
return;
|
||||
|
||||
int damage = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), 45);
|
||||
GetTarget().CastCustomSpell(SpellIds.MirroredSoulDamage, SpellValueMod.BasePoint0, damage, GetCaster(), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 69048 - Mirrored Soul (Target Selector)
|
||||
class spell_devourer_of_souls_mirrored_soul_target_selector : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.MirroredSoulBuff);
|
||||
}
|
||||
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
if (targets.Empty())
|
||||
return;
|
||||
|
||||
WorldObject target = targets.SelectRandom();
|
||||
targets.Clear();
|
||||
targets.Add(target);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
GetCaster().CastSpell(target, SpellIds.MirroredSoulBuff, false);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEntry));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_three_faced : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_three_faced() : base("achievement_three_faced") { }
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Creature devourer = target.ToCreature();
|
||||
if (devourer)
|
||||
if (devourer.GetAI().GetData(Misc.DataThreeFaced) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* 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 System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls
|
||||
{
|
||||
struct DataType
|
||||
{
|
||||
// Encounter states and GUIDs
|
||||
public const uint Bronjahm = 0;
|
||||
public const uint DevourerOfSouls = 1;
|
||||
|
||||
// Additional Data
|
||||
public const uint TeamInInstance = 2;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint Bronjahm = 36497;
|
||||
public const uint Devourer = 36502;
|
||||
public const uint CorruptedSoulFragment = 36535;
|
||||
|
||||
public const uint SylvanasPart1 = 37596;
|
||||
public const uint SylvanasPart2 = 38161;
|
||||
public const uint JainaPart1 = 37597;
|
||||
public const uint JainaPart2 = 38160;
|
||||
public const uint Kalira = 37583;
|
||||
public const uint Elandra = 37774;
|
||||
public const uint Loralen = 37779;
|
||||
public const uint Koreln = 37582;
|
||||
public const uint Champion1Horde = 37584;
|
||||
public const uint Champion2Horde = 37587;
|
||||
public const uint Champion3Horde = 37588;
|
||||
public const uint Champion1Alliance = 37496;
|
||||
public const uint Champion2Alliance = 37497;
|
||||
public const uint CrucibleOfSouls = 37094;
|
||||
}
|
||||
|
||||
struct EventIds
|
||||
{
|
||||
public const uint None = 0;
|
||||
|
||||
// Jaina/Sylvanas Intro
|
||||
public const uint Intro1 = 1;
|
||||
public const uint Intro2 = 2;
|
||||
public const uint Intro3 = 3;
|
||||
public const uint Intro4 = 4;
|
||||
public const uint Intro5 = 5;
|
||||
public const uint Intro6 = 6;
|
||||
public const uint Intro7 = 7;
|
||||
public const uint Intro8 = 8;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayJainaIntro1 = 0;
|
||||
public const uint SayJainaIntro2 = 1;
|
||||
public const uint SayJainaIntro3 = 2;
|
||||
public const uint SayJainaIntro4 = 3;
|
||||
public const uint SayJainaIntro5 = 4;
|
||||
public const uint SayJainaIntro6 = 5;
|
||||
public const uint SayJainaIntro7 = 6;
|
||||
public const uint SayJainaIntro8 = 7;
|
||||
|
||||
public const uint SaySylvanasIntro1 = 0;
|
||||
public const uint SaySylvanasIntro2 = 1;
|
||||
public const uint SaySylvanasIntro3 = 2;
|
||||
public const uint SaySylvanasIntro4 = 3;
|
||||
public const uint SaySylvanasIntro5 = 4;
|
||||
public const uint SaySylvanasIntro6 = 5;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint MenuIdJaina = 10943;
|
||||
public const uint MenuIdSylvanas = 10971;
|
||||
public const uint GossipOptionId = 0;
|
||||
}
|
||||
|
||||
enum Phase
|
||||
{
|
||||
Normal,
|
||||
Intro,
|
||||
}
|
||||
|
||||
[Script]
|
||||
class instance_forge_of_souls : InstanceMapScript
|
||||
{
|
||||
public instance_forge_of_souls() : base(nameof(instance_forge_of_souls), 632) { }
|
||||
|
||||
class instance_forge_of_souls_InstanceScript : InstanceScript
|
||||
{
|
||||
public instance_forge_of_souls_InstanceScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("FOS");
|
||||
SetBossNumber(2);
|
||||
|
||||
teamInInstance = 0;
|
||||
}
|
||||
|
||||
public override void OnPlayerEnter(Player player)
|
||||
{
|
||||
if (teamInInstance == 0)
|
||||
teamInInstance = player.GetTeam();
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
if (teamInInstance == 0)
|
||||
{
|
||||
var players = instance.GetPlayers();
|
||||
if (!players.Empty())
|
||||
{
|
||||
Player player = players[0];
|
||||
if (player)
|
||||
teamInInstance = player.GetTeam();
|
||||
}
|
||||
}
|
||||
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case CreatureIds.Bronjahm:
|
||||
bronjahm = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.Devourer:
|
||||
devourerOfSouls = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.SylvanasPart1:
|
||||
if (teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.JainaPart1);
|
||||
break;
|
||||
case CreatureIds.Loralen:
|
||||
if (teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.Elandra);
|
||||
break;
|
||||
case CreatureIds.Kalira:
|
||||
if (teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.Koreln);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataType.TeamInInstance:
|
||||
return (uint)teamInInstance;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataType.Bronjahm:
|
||||
return bronjahm;
|
||||
case DataType.DevourerOfSouls:
|
||||
return devourerOfSouls;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
ObjectGuid bronjahm;
|
||||
ObjectGuid devourerOfSouls;
|
||||
|
||||
Team teamInInstance;
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_forge_of_souls_InstanceScript(map);
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_sylvanas_fos : ScriptedAI
|
||||
{
|
||||
public npc_sylvanas_fos(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
me.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
phase = Phase.Normal;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void sGossipSelect(Player player, uint menuId, uint gossipListId)
|
||||
{
|
||||
if (menuId == Misc.MenuIdSylvanas && gossipListId == Misc.GossipOptionId)
|
||||
{
|
||||
player.CLOSE_GOSSIP_MENU();
|
||||
phase = Phase.Intro;
|
||||
me.RemoveFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EventIds.Intro1, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (phase == Phase.Intro)
|
||||
{
|
||||
_events.Update(diff);
|
||||
switch (_events.ExecuteEvent())
|
||||
{
|
||||
case EventIds.Intro1:
|
||||
Talk(TextIds.SaySylvanasIntro1);
|
||||
_events.ScheduleEvent(EventIds.Intro2, 11500);
|
||||
break;
|
||||
|
||||
case EventIds.Intro2:
|
||||
Talk(TextIds.SaySylvanasIntro2);
|
||||
_events.ScheduleEvent(EventIds.Intro3, 10500);
|
||||
break;
|
||||
|
||||
case EventIds.Intro3:
|
||||
Talk(TextIds.SaySylvanasIntro3);
|
||||
_events.ScheduleEvent(EventIds.Intro4, 9500);
|
||||
break;
|
||||
|
||||
case EventIds.Intro4:
|
||||
Talk(TextIds.SaySylvanasIntro4);
|
||||
_events.ScheduleEvent(EventIds.Intro5, 10500);
|
||||
break;
|
||||
|
||||
case EventIds.Intro5:
|
||||
Talk(TextIds.SaySylvanasIntro5);
|
||||
_events.ScheduleEvent(EventIds.Intro6, 9500);
|
||||
break;
|
||||
|
||||
case EventIds.Intro6:
|
||||
Talk(TextIds.SaySylvanasIntro6);
|
||||
// End of Intro
|
||||
phase = Phase.Normal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
Phase phase;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_jaina_fos : ScriptedAI
|
||||
{
|
||||
public npc_jaina_fos(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
me.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
phase = Phase.Normal;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void sGossipSelect(Player player, uint menuId, uint gossipListId)
|
||||
{
|
||||
if (menuId == Misc.MenuIdJaina && gossipListId == Misc.GossipOptionId)
|
||||
{
|
||||
player.CLOSE_GOSSIP_MENU();
|
||||
phase = Phase.Intro;
|
||||
me.RemoveFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EventIds.Intro1, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (phase == Phase.Intro)
|
||||
{
|
||||
_events.Update(diff);
|
||||
switch (_events.ExecuteEvent())
|
||||
{
|
||||
case EventIds.Intro1:
|
||||
Talk(TextIds.SayJainaIntro1);
|
||||
_events.ScheduleEvent(EventIds.Intro2, 8000);
|
||||
break;
|
||||
|
||||
case EventIds.Intro2:
|
||||
Talk(TextIds.SayJainaIntro2);
|
||||
_events.ScheduleEvent(EventIds.Intro3, 8500);
|
||||
break;
|
||||
|
||||
case EventIds.Intro3:
|
||||
Talk(TextIds.SayJainaIntro3);
|
||||
_events.ScheduleEvent(EventIds.Intro4, 8000);
|
||||
break;
|
||||
|
||||
case EventIds.Intro4:
|
||||
Talk(TextIds.SayJainaIntro4);
|
||||
_events.ScheduleEvent(EventIds.Intro5, 10000);
|
||||
break;
|
||||
|
||||
case EventIds.Intro5:
|
||||
Talk(TextIds.SayJainaIntro5);
|
||||
_events.ScheduleEvent(EventIds.Intro6, 8000);
|
||||
break;
|
||||
|
||||
case EventIds.Intro6:
|
||||
Talk(TextIds.SayJainaIntro6);
|
||||
_events.ScheduleEvent(EventIds.Intro7, 12000);
|
||||
break;
|
||||
|
||||
case EventIds.Intro7:
|
||||
Talk(TextIds.SayJainaIntro7);
|
||||
_events.ScheduleEvent(EventIds.Intro8, 8000);
|
||||
break;
|
||||
|
||||
case EventIds.Intro8:
|
||||
Talk(TextIds.SayJainaIntro8);
|
||||
// End of Intro
|
||||
phase = Phase.Normal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
Phase phase;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Framework.Constants;
|
||||
using Game.Spells;
|
||||
using Game.Scripting;
|
||||
|
||||
namespace Scripts.Northrend.FrozenHalls.PitOfSaron.BossForgemasterGarfrost
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SayPhase2 = 1;
|
||||
public const uint SayPhase3 = 2;
|
||||
public const uint SayDeath = 3;
|
||||
public const uint SaySlay = 4;
|
||||
public const uint SayThrowSaronite = 5;
|
||||
public const uint SayCastDeepFreeze = 6;
|
||||
|
||||
public const uint SayTyrannusDeath = 0;
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Permafrost = 70326;
|
||||
public const uint ThrowSaronite = 68788;
|
||||
public const uint ThunderingStomp = 68771;
|
||||
public const uint ChillingWave = 68778;
|
||||
public const uint DeepFreeze = 70381;
|
||||
public const uint ForgeMace = 68785;
|
||||
public const uint ForgeBlade = 68774;
|
||||
|
||||
public const uint PermafrostAura = 68786;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const byte PhaseOne = 1;
|
||||
public const byte PhaseTwo = 2;
|
||||
public const byte PhaseThree = 3;
|
||||
|
||||
public const int EquipIdSword = 49345;
|
||||
public const int EquipIdMace = 49344;
|
||||
public const uint AchievDoesntGoToEleven = 0;
|
||||
public const uint PointForge = 0;
|
||||
|
||||
public static Position northForgePos = new Position(722.5643f, -234.1615f, 527.182f, 2.16421f);
|
||||
public static Position southForgePos = new Position(639.257f, -210.1198f, 529.015f, 0.523599f);
|
||||
}
|
||||
|
||||
struct Events
|
||||
{
|
||||
public const uint ThrowSaronite = 1;
|
||||
public const uint ChillingWave = 2;
|
||||
public const uint DeepFreeze = 3;
|
||||
public const uint ForgeJump = 4;
|
||||
public const uint ResumeAttack = 5;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_garfrost : BossAI
|
||||
{
|
||||
public boss_garfrost(Creature creature) : base(creature, DataTypes.Garfrost) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
_events.SetPhase(Misc.PhaseOne);
|
||||
SetEquipmentSlots(true);
|
||||
_permafrostStack = 0;
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(TextIds.SayAggro);
|
||||
DoCast(me, SpellIds.Permafrost);
|
||||
me.CallForHelp(70.0f);
|
||||
_events.ScheduleEvent(Events.ThrowSaronite, 7000);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (victim.IsPlayer())
|
||||
Talk(TextIds.SaySlay);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(TextIds.SayDeath);
|
||||
me.RemoveAllGameObjects();
|
||||
|
||||
Creature tyrannus = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Tyrannus));
|
||||
if (tyrannus)
|
||||
tyrannus.GetAI().Talk(TextIds.SayTyrannusDeath);
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (_events.IsInPhase(Misc.PhaseOne) && !HealthAbovePct(66))
|
||||
{
|
||||
_events.SetPhase(Misc.PhaseTwo);
|
||||
Talk(TextIds.SayPhase2);
|
||||
_events.DelayEvents(8000);
|
||||
DoCast(me, SpellIds.ThunderingStomp);
|
||||
_events.ScheduleEvent(Events.ForgeJump, 1500);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_events.IsInPhase(Misc.PhaseTwo) && !HealthAbovePct(33))
|
||||
{
|
||||
_events.SetPhase(Misc.PhaseThree);
|
||||
Talk(TextIds.SayPhase3);
|
||||
_events.DelayEvents(8000);
|
||||
DoCast(me, SpellIds.ThunderingStomp);
|
||||
_events.ScheduleEvent(Events.ForgeJump, 1500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Effect || id != Misc.PointForge)
|
||||
return;
|
||||
|
||||
if (_events.IsInPhase(Misc.PhaseTwo))
|
||||
{
|
||||
DoCast(me, SpellIds.ForgeBlade);
|
||||
SetEquipmentSlots(false, Misc.EquipIdSword);
|
||||
}
|
||||
if (_events.IsInPhase(Misc.PhaseThree))
|
||||
{
|
||||
me.RemoveAurasDueToSpell(SpellIds.ForgeBlade);
|
||||
DoCast(me, SpellIds.ForgeMace);
|
||||
SetEquipmentSlots(false, Misc.EquipIdMace);
|
||||
}
|
||||
_events.ScheduleEvent(Events.ResumeAttack, 5000);
|
||||
}
|
||||
|
||||
public override void SpellHitTarget(Unit target, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id == SpellIds.PermafrostAura)
|
||||
{
|
||||
Aura aura = target.GetAura(SpellIds.PermafrostAura);
|
||||
if (aura != null)
|
||||
_permafrostStack = Math.Max(_permafrostStack, aura.GetStackAmount());
|
||||
}
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
return _permafrostStack;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Events.ThrowSaronite:
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
|
||||
if (target)
|
||||
{
|
||||
Talk(TextIds.SayThrowSaronite, target);
|
||||
DoCast(target, SpellIds.ThrowSaronite);
|
||||
}
|
||||
_events.ScheduleEvent(Events.ThrowSaronite, TimeSpan.FromSeconds(12.5), TimeSpan.FromSeconds(20));
|
||||
}
|
||||
break;
|
||||
case Events.ChillingWave:
|
||||
DoCast(me, SpellIds.ChillingWave);
|
||||
_events.ScheduleEvent(Events.ChillingWave, 40000, 0, Misc.PhaseTwo);
|
||||
break;
|
||||
case Events.DeepFreeze:
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
|
||||
if (target)
|
||||
{
|
||||
Talk(TextIds.SayCastDeepFreeze, target);
|
||||
DoCast(target, SpellIds.DeepFreeze);
|
||||
}
|
||||
_events.ScheduleEvent(Events.DeepFreeze, 35000, 0, Misc.PhaseThree);
|
||||
}
|
||||
break;
|
||||
case Events.ForgeJump:
|
||||
me.AttackStop();
|
||||
if (_events.IsInPhase(Misc.PhaseTwo))
|
||||
me.GetMotionMaster().MoveJump(Misc.northForgePos, 25.0f, 15.0f, Misc.PointForge);
|
||||
else if (_events.IsInPhase(Misc.PhaseThree))
|
||||
me.GetMotionMaster().MoveJump(Misc.southForgePos, 25.0f, 15.0f, Misc.PointForge);
|
||||
break;
|
||||
case Events.ResumeAttack:
|
||||
if (_events.IsInPhase(Misc.PhaseTwo))
|
||||
_events.ScheduleEvent(Events.ChillingWave, 5000, 0, Misc.PhaseTwo);
|
||||
else if (_events.IsInPhase(Misc.PhaseThree))
|
||||
_events.ScheduleEvent(Events.DeepFreeze, 10000, 0, Misc.PhaseThree);
|
||||
AttackStart(me.GetVictim());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
uint _permafrostStack;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_garfrost_permafrost : SpellScript
|
||||
{
|
||||
public spell_garfrost_permafrost()
|
||||
{
|
||||
prevented = false;
|
||||
}
|
||||
|
||||
void PreventHitByLoS(SpellMissInfo missInfo)
|
||||
{
|
||||
if (missInfo != SpellMissInfo.None)
|
||||
return;
|
||||
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
//Temporary Line of Sight Check
|
||||
List<GameObject> blockList = new List<GameObject>();
|
||||
caster.GetGameObjectListWithEntryInGrid(blockList, GameObjectIds.SaroniteRock, 100.0f);
|
||||
if (!blockList.Empty())
|
||||
{
|
||||
foreach (var obj in blockList)
|
||||
{
|
||||
if (!obj.IsInvisibleDueToDespawn())
|
||||
{
|
||||
if (obj.IsInBetween(caster, target, 4.0f))
|
||||
{
|
||||
prevented = true;
|
||||
target.ApplySpellImmune(GetSpellInfo().Id, SpellImmunity.Id, GetSpellInfo().Id, true);
|
||||
PreventHitDefaultEffect(0);
|
||||
PreventHitDefaultEffect(1);
|
||||
PreventHitDefaultEffect(2);
|
||||
PreventHitDamage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreImmunity()
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
{
|
||||
target.ApplySpellImmune(GetSpellInfo().Id, SpellImmunity.Id, GetSpellInfo().Id, false);
|
||||
if (prevented)
|
||||
PreventHitAura();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
BeforeHit.Add(new BeforeHitHandler(PreventHitByLoS));
|
||||
AfterHit.Add(new HitHandler(RestoreImmunity));
|
||||
}
|
||||
|
||||
bool prevented;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_doesnt_go_to_eleven : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_doesnt_go_to_eleven() : base("achievement_doesnt_go_to_eleven") { }
|
||||
|
||||
public override bool OnCheck(Player source, Unit target)
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
Creature garfrost = target.ToCreature();
|
||||
if (garfrost)
|
||||
if (garfrost.GetAI().GetData(Misc.AchievDoesntGoToEleven) <= 10)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,674 @@
|
||||
using System;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.AI;
|
||||
using Framework.Constants;
|
||||
using Game.Maps;
|
||||
using Game.Spells;
|
||||
|
||||
namespace Scripts.Northrend.FrozenHalls.PitOfSaron.BossKrickAndIck
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint MightyKick = 69021; //Ick'S Spell
|
||||
public const uint ShadowBolt = 69028; //Krick'S Spell
|
||||
public const uint ToxicWaste = 69024; //Krick'S Spell
|
||||
public const uint ExplosiveBarrageKrick = 69012; //Special Spell 1
|
||||
public const uint ExplosiveBarrageIck = 69263; //Special Spell 1
|
||||
public const uint PoisonNova = 68989; //Special Spell 2
|
||||
public const uint Pursuit = 68987; //Special Spell 3
|
||||
|
||||
public const uint ExplosiveBarrageSummon = 69015;
|
||||
public const uint ExplodingOrb = 69017; //Visual On Exploding Orb
|
||||
public const uint AutoGrow = 69020; //Grow Effect On Exploding Orb
|
||||
public const uint HastyGrow = 44851; //Need To Check Growing Stacks
|
||||
public const uint ExplosiveBarrageDamage = 69019; //Damage Done By Orb While Exploding
|
||||
|
||||
public const uint Strangulating = 69413; //Krick'S Selfcast In Intro
|
||||
public const uint Suicide = 7;
|
||||
public const uint KrickKillCredit = 71308;
|
||||
public const uint NecromanticPower = 69753;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
// Krick
|
||||
public const uint SayKrickAggro = 0;
|
||||
public const uint SayKrickSlay = 1;
|
||||
public const uint SayKrickBarrage1 = 2;
|
||||
public const uint SayKrickBarrage2 = 3;
|
||||
public const uint SayKrickPoisonNova = 4;
|
||||
public const uint SayKrickChase = 5;
|
||||
public const uint SayKrickOutro1 = 6;
|
||||
public const uint SayKrickOutro3 = 7;
|
||||
public const uint SayKrickOutro5 = 8;
|
||||
public const uint SayKrickOutro8 = 9;
|
||||
|
||||
// Ick
|
||||
public const uint SayIckPoisonNova = 0;
|
||||
public const uint SayIckChase1 = 1;
|
||||
|
||||
// Outro
|
||||
public const uint SayJaynaOutro2 = 0;
|
||||
public const uint SayJaynaOutro4 = 1;
|
||||
public const uint SayJaynaOutro10 = 2;
|
||||
public const uint SaySylvanasOutro2 = 0;
|
||||
public const uint SaySylvanasOutro4 = 1;
|
||||
public const uint SaySylvanasOutro10 = 2;
|
||||
public const uint SayTyrannusOutro7 = 1;
|
||||
public const uint SayTyrannusOutro9 = 2;
|
||||
}
|
||||
|
||||
struct Events
|
||||
{
|
||||
public const uint MightyKick = 1;
|
||||
public const uint ShadowBolt = 2;
|
||||
public const uint ToxicWaste = 3;
|
||||
public const uint Special = 4; //Special Spell Selection (One Of Event 5; 6 Or 7)
|
||||
public const uint Pursuit = 5;
|
||||
public const uint PoisonNova = 6;
|
||||
public const uint ExplosiveBarrage = 7;
|
||||
|
||||
// Krick Outro
|
||||
public const uint Outro1 = 8;
|
||||
public const uint Outro2 = 9;
|
||||
public const uint Outro3 = 10;
|
||||
public const uint Outro4 = 11;
|
||||
public const uint Outro5 = 12;
|
||||
public const uint Outro6 = 13;
|
||||
public const uint Outro7 = 14;
|
||||
public const uint Outro8 = 15;
|
||||
public const uint Outro9 = 16;
|
||||
public const uint Outro10 = 17;
|
||||
public const uint Outro11 = 18;
|
||||
public const uint Outro12 = 19;
|
||||
public const uint Outro13 = 20;
|
||||
public const uint OutroEnd = 21;
|
||||
}
|
||||
|
||||
enum KrickPhase
|
||||
{
|
||||
Combat = 1,
|
||||
Outro = 2
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const int ActionOutro = 1;
|
||||
|
||||
public const uint PointKrickIntro = 364770;
|
||||
public const uint PointKrickDeath = 364771;
|
||||
|
||||
public static Position[] outroPos =
|
||||
{
|
||||
new Position(828.9342f, 118.6247f, 509.5190f, 0.0000000f), // Krick's Outro Position
|
||||
new Position( 841.0100f, 196.2450f, 573.9640f, 0.2046099f), // Scourgelord Tyrannus Outro Position (Tele to...)
|
||||
new Position( 777.2274f, 119.5521f, 510.0363f, 6.0562930f), // Sylvanas / Jaine Outro Spawn Position (NPC_SYLVANAS_PART1)
|
||||
new Position(823.3984f, 114.4907f, 509.4899f, 0.0000000f), // Sylvanas / Jaine Outro Move Position (1)
|
||||
new Position( 835.5887f, 139.4345f, 530.9526f, 0.0000000f), // Tyrannus fly down Position (not sniffed)
|
||||
new Position( 828.9342f, 118.6247f, 514.5190f, 0.0000000f), // Krick's Choke Position
|
||||
new Position(828.9342f, 118.6247f, 509.4958f, 0.0000000f), // Kirck's Death Position
|
||||
new Position(914.4820f, 143.1602f, 633.3624f, 0.0000000f) // Tyrannus fly up (not sniffed)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[Script]
|
||||
class boss_ick : BossAI
|
||||
{
|
||||
public boss_ick(Creature creature) : base(creature, DataTypes.Ick)
|
||||
{
|
||||
_tempThreat = 0;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.Reset();
|
||||
instance.SetBossState(DataTypes.Ick, EncounterState.NotStarted);
|
||||
}
|
||||
|
||||
Creature GetKrick()
|
||||
{
|
||||
return ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Krick));
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
Creature krick = GetKrick();
|
||||
if (krick)
|
||||
krick.GetAI().Talk(TextIds.SayKrickAggro);
|
||||
|
||||
_events.ScheduleEvent(Events.MightyKick, 20000);
|
||||
_events.ScheduleEvent(Events.ToxicWaste, 5000);
|
||||
_events.ScheduleEvent(Events.ShadowBolt, 10000);
|
||||
_events.ScheduleEvent(Events.Special, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35));
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
me.GetMotionMaster().Clear();
|
||||
base.EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Creature krick = GetKrick();
|
||||
if (krick)
|
||||
{
|
||||
Vehicle vehicle = me.GetVehicleKit();
|
||||
if (vehicle)
|
||||
vehicle.RemoveAllPassengers();
|
||||
if (krick.IsAIEnabled)
|
||||
krick.GetAI().DoAction(Misc.ActionOutro);
|
||||
}
|
||||
|
||||
instance.SetBossState(DataTypes.Ick, EncounterState.Done);
|
||||
}
|
||||
|
||||
public void SetTempThreat(float threat)
|
||||
{
|
||||
_tempThreat = threat;
|
||||
}
|
||||
|
||||
public void _ResetThreat(Unit target)
|
||||
{
|
||||
DoModifyThreatPercent(target, -100);
|
||||
me.AddThreat(target, _tempThreat);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!me.IsInCombat())
|
||||
return;
|
||||
|
||||
if (!me.GetVictim() && me.GetThreatManager().isThreatListEmpty())
|
||||
{
|
||||
EnterEvadeMode(EvadeReason.NoHostiles);
|
||||
return;
|
||||
}
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Events.ToxicWaste:
|
||||
{
|
||||
Creature krick = GetKrick();
|
||||
if (krick)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
krick.CastSpell(target, SpellIds.ToxicWaste);
|
||||
_events.ScheduleEvent(Events.ToxicWaste, TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(10));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Events.ShadowBolt:
|
||||
{
|
||||
Creature krick = GetKrick();
|
||||
if (krick)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 1);
|
||||
if (target)
|
||||
krick.CastSpell(target, SpellIds.ShadowBolt);
|
||||
_events.ScheduleEvent(Events.ShadowBolt, 15000);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case Events.MightyKick:
|
||||
DoCastVictim(SpellIds.MightyKick);
|
||||
_events.ScheduleEvent(Events.MightyKick, 25000);
|
||||
return;
|
||||
case Events.Special:
|
||||
//select one of these three special _events
|
||||
_events.ScheduleEvent(RandomHelper.RAND(Events.ExplosiveBarrage, Events.PoisonNova, Events.Pursuit), 1000);
|
||||
_events.ScheduleEvent(Events.Special, TimeSpan.FromSeconds(23), TimeSpan.FromSeconds(28));
|
||||
break;
|
||||
case Events.ExplosiveBarrage:
|
||||
{
|
||||
Creature krick = GetKrick();
|
||||
if (krick)
|
||||
{
|
||||
krick.GetAI().Talk(TextIds.SayKrickBarrage1);
|
||||
krick.GetAI().Talk(TextIds.SayKrickBarrage2);
|
||||
krick.CastSpell(krick, SpellIds.ExplosiveBarrageKrick, true);
|
||||
DoCast(me, SpellIds.ExplosiveBarrageIck);
|
||||
}
|
||||
_events.DelayEvents(20000);
|
||||
}
|
||||
break;
|
||||
case Events.PoisonNova:
|
||||
{
|
||||
Creature krick = GetKrick();
|
||||
if (krick)
|
||||
krick.GetAI().Talk(TextIds.SayKrickPoisonNova);
|
||||
|
||||
Talk(TextIds.SayIckPoisonNova);
|
||||
DoCast(me, SpellIds.PoisonNova);
|
||||
}
|
||||
break;
|
||||
case Events.Pursuit:
|
||||
{
|
||||
Creature krick = GetKrick();
|
||||
if (krick)
|
||||
krick.GetAI().Talk(TextIds.SayKrickChase);
|
||||
DoCast(me, SpellIds.Pursuit);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
float _tempThreat;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_krick : ScriptedAI
|
||||
{
|
||||
public boss_krick(Creature creature) : base(creature)
|
||||
{
|
||||
_instanceScript = creature.GetInstanceScript();
|
||||
_summons = new SummonList(creature);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_phase = KrickPhase.Combat;
|
||||
_outroNpcGUID.Clear();
|
||||
_tyrannusGUID.Clear();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.Reset();
|
||||
Initialize();
|
||||
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
}
|
||||
|
||||
Creature GetIck()
|
||||
{
|
||||
return ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.Ick));
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (victim.IsPlayer())
|
||||
Talk(TextIds.SayKrickSlay);
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
_summons.Summon(summon);
|
||||
if (summon.GetEntry() == CreatureIds.ExplodingOrb)
|
||||
{
|
||||
summon.CastSpell(summon, SpellIds.ExplodingOrb, true);
|
||||
summon.CastSpell(summon, SpellIds.AutoGrow, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void DoAction(int actionId)
|
||||
{
|
||||
if (actionId == Misc.ActionOutro)
|
||||
{
|
||||
Creature tyrannusPtr = ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.TyrannusEvent));
|
||||
if (tyrannusPtr)
|
||||
tyrannusPtr.NearTeleportTo(Misc.outroPos[1].GetPositionX(), Misc.outroPos[1].GetPositionY(), Misc.outroPos[1].GetPositionZ(), Misc.outroPos[1].GetOrientation());
|
||||
else
|
||||
tyrannusPtr = me.SummonCreature(CreatureIds.TyrannusEvents, Misc.outroPos[1], TempSummonType.ManualDespawn);
|
||||
|
||||
tyrannusPtr.SetCanFly(true);
|
||||
me.GetMotionMaster().MovePoint(Misc.PointKrickIntro, Misc.outroPos[0].GetPositionX(), Misc.outroPos[0].GetPositionY(), Misc.outroPos[0].GetPositionZ());
|
||||
tyrannusPtr.SetFacingToObject(me);
|
||||
}
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Point || id != Misc.PointKrickIntro)
|
||||
return;
|
||||
|
||||
Talk(TextIds.SayKrickOutro1);
|
||||
_phase = KrickPhase.Outro;
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(Events.Outro1, 1000);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (_phase != KrickPhase.Outro)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Events.Outro1:
|
||||
{
|
||||
Creature temp = ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.JainaSylvanas1));
|
||||
if (temp)
|
||||
temp.DespawnOrUnsummon();
|
||||
|
||||
Creature jainaOrSylvanas = null;
|
||||
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
|
||||
jainaOrSylvanas = me.SummonCreature(CreatureIds.JainaPart1, Misc.outroPos[2], TempSummonType.ManualDespawn);
|
||||
else
|
||||
jainaOrSylvanas = me.SummonCreature(CreatureIds.SylvanasPart1, Misc.outroPos[2], TempSummonType.ManualDespawn);
|
||||
|
||||
if (jainaOrSylvanas)
|
||||
{
|
||||
jainaOrSylvanas.GetMotionMaster().MovePoint(0, Misc.outroPos[3]);
|
||||
_outroNpcGUID = jainaOrSylvanas.GetGUID();
|
||||
}
|
||||
_events.ScheduleEvent(Events.Outro2, 6000);
|
||||
break;
|
||||
}
|
||||
case Events.Outro2:
|
||||
{
|
||||
Creature jainaOrSylvanas = ObjectAccessor.GetCreature(me, _outroNpcGUID);
|
||||
if (jainaOrSylvanas)
|
||||
{
|
||||
jainaOrSylvanas.SetFacingToObject(me);
|
||||
me.SetFacingToObject(jainaOrSylvanas);
|
||||
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
|
||||
jainaOrSylvanas.GetAI().Talk(TextIds.SayJaynaOutro2);
|
||||
else
|
||||
jainaOrSylvanas.GetAI().Talk(TextIds.SaySylvanasOutro2);
|
||||
}
|
||||
_events.ScheduleEvent(Events.Outro3, 5000);
|
||||
}
|
||||
break;
|
||||
case Events.Outro3:
|
||||
Talk(TextIds.SayKrickOutro3);
|
||||
_events.ScheduleEvent(Events.Outro4, 18000);
|
||||
break;
|
||||
case Events.Outro4:
|
||||
{
|
||||
Creature jainaOrSylvanas = ObjectAccessor.GetCreature(me, _outroNpcGUID);
|
||||
if (jainaOrSylvanas)
|
||||
{
|
||||
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
|
||||
jainaOrSylvanas.GetAI().Talk(TextIds.SayJaynaOutro4);
|
||||
else
|
||||
jainaOrSylvanas.GetAI().Talk(TextIds.SaySylvanasOutro4);
|
||||
}
|
||||
_events.ScheduleEvent(Events.Outro5, 5000);
|
||||
}
|
||||
break;
|
||||
case Events.Outro5:
|
||||
Talk(TextIds.SayKrickOutro5);
|
||||
_events.ScheduleEvent(Events.Outro6, 1000);
|
||||
break;
|
||||
case Events.Outro6:
|
||||
{
|
||||
Creature tyrannus = ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.TyrannusEvent));
|
||||
if (tyrannus)
|
||||
{
|
||||
tyrannus.SetSpeedRate(UnitMoveType.Flight, 3.5f);
|
||||
tyrannus.GetMotionMaster().MovePoint(1, Misc.outroPos[4]);
|
||||
_tyrannusGUID = tyrannus.GetGUID();
|
||||
}
|
||||
_events.ScheduleEvent(Events.Outro7, 5000);
|
||||
}
|
||||
break;
|
||||
case Events.Outro7:
|
||||
{
|
||||
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
|
||||
if (tyrannus)
|
||||
tyrannus.GetAI().Talk(TextIds.SayTyrannusOutro7);
|
||||
_events.ScheduleEvent(Events.Outro8, 5000);
|
||||
}
|
||||
break;
|
||||
case Events.Outro8:
|
||||
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
|
||||
me.AddUnitMovementFlag(MovementFlag.Flying);
|
||||
me.GetMotionMaster().MovePoint(0, Misc.outroPos[5]);
|
||||
DoCast(me, SpellIds.Strangulating);
|
||||
_events.ScheduleEvent(Events.Outro9, 2000);
|
||||
break;
|
||||
case Events.Outro9:
|
||||
{
|
||||
Talk(TextIds.SayKrickOutro8);
|
||||
/// @todo Tyrannus starts killing Krick.
|
||||
// there shall be some visual spell effect
|
||||
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
|
||||
if (tyrannus)
|
||||
tyrannus.CastSpell(me, SpellIds.NecromanticPower, true); //not sure if it's the right spell :/
|
||||
_events.ScheduleEvent(Events.Outro10, 1000);
|
||||
}
|
||||
break;
|
||||
case Events.Outro10:
|
||||
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
|
||||
me.RemoveUnitMovementFlag(MovementFlag.Flying);
|
||||
me.AddUnitMovementFlag(MovementFlag.FallingFar);
|
||||
me.GetMotionMaster().MovePoint(0, Misc.outroPos[6]);
|
||||
_events.ScheduleEvent(Events.Outro11, 2000);
|
||||
break;
|
||||
case Events.Outro11:
|
||||
DoCast(me, SpellIds.KrickKillCredit); // don't really know if we need it
|
||||
me.SetStandState(UnitStandStateType.Dead);
|
||||
me.SetHealth(0);
|
||||
_events.ScheduleEvent(Events.Outro12, 3000);
|
||||
break;
|
||||
case Events.Outro12:
|
||||
{
|
||||
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
|
||||
if (tyrannus)
|
||||
tyrannus.GetAI().Talk(TextIds.SayTyrannusOutro9);
|
||||
_events.ScheduleEvent(Events.Outro13, 2000);
|
||||
}
|
||||
break;
|
||||
case Events.Outro13:
|
||||
{
|
||||
Creature jainaOrSylvanas = ObjectAccessor.GetCreature(me, _outroNpcGUID);
|
||||
if (jainaOrSylvanas)
|
||||
{
|
||||
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
|
||||
jainaOrSylvanas.GetAI().Talk(TextIds.SayJaynaOutro10);
|
||||
else
|
||||
jainaOrSylvanas.GetAI().Talk(TextIds.SaySylvanasOutro10);
|
||||
}
|
||||
// End of OUTRO. for now...
|
||||
_events.ScheduleEvent(Events.OutroEnd, 3000);
|
||||
|
||||
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
|
||||
if (tyrannus)
|
||||
tyrannus.GetMotionMaster().MovePoint(0, Misc.outroPos[7]);
|
||||
}
|
||||
break;
|
||||
case Events.OutroEnd:
|
||||
{
|
||||
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
|
||||
if (tyrannus)
|
||||
tyrannus.DespawnOrUnsummon();
|
||||
|
||||
me.DisappearAndDie();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
InstanceScript _instanceScript;
|
||||
SummonList _summons;
|
||||
|
||||
KrickPhase _phase;
|
||||
ObjectGuid _outroNpcGUID;
|
||||
ObjectGuid _tyrannusGUID;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_krick_explosive_barrage : AuraScript
|
||||
{
|
||||
void HandlePeriodicTick(AuraEffect aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
{
|
||||
if (caster.IsCreature())
|
||||
{
|
||||
var players = caster.GetMap().GetPlayers();
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player)
|
||||
if (player.IsWithinDist(caster, 60.0f)) // don't know correct range
|
||||
caster.CastSpell(player, SpellIds.ExplosiveBarrageSummon, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodicTick, 0, AuraType.PeriodicTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_ick_explosive_barrage : AuraScript
|
||||
{
|
||||
void HandleEffectApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
if (caster.IsCreature())
|
||||
caster.GetMotionMaster().MoveIdle();
|
||||
}
|
||||
|
||||
void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
{
|
||||
if (caster.IsCreature())
|
||||
{
|
||||
caster.GetMotionMaster().Clear();
|
||||
caster.GetMotionMaster().MoveChase(caster.GetVictim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(HandleEffectApply, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_exploding_orb_hasty_grow : AuraScript
|
||||
{
|
||||
void OnStackChange(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
if (GetStackAmount() == 15)
|
||||
{
|
||||
Unit target = GetTarget(); // store target because aura gets removed
|
||||
target.CastSpell(target, SpellIds.ExplosiveBarrageDamage, false);
|
||||
target.RemoveAurasDueToSpell(SpellIds.HastyGrow);
|
||||
target.RemoveAurasDueToSpell(SpellIds.AutoGrow);
|
||||
target.RemoveAurasDueToSpell(SpellIds.ExplodingOrb);
|
||||
|
||||
Creature creature = target.ToCreature();
|
||||
if (creature)
|
||||
creature.DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(OnStackChange, 0, AuraType.ModScale, AuraEffectHandleModes.Reapply));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_krick_pursuit : SpellScript
|
||||
{
|
||||
void HandleScriptEffect(uint effIndex)
|
||||
{
|
||||
if (GetCaster())
|
||||
{
|
||||
Creature ick = GetCaster().ToCreature();
|
||||
if (ick)
|
||||
{
|
||||
Unit target = ick.GetAI().SelectTarget(SelectAggroTarget.Random, 0, 200.0f, true);
|
||||
if (target)
|
||||
{
|
||||
ick.GetAI().Talk(TextIds.SayIckChase1, target);
|
||||
ick.AddAura(GetSpellInfo().Id, target);
|
||||
ick.GetAI<boss_ick>().SetTempThreat(ick.GetThreatManager().getThreat(target));
|
||||
ick.AddThreat(target, GetEffectValue());
|
||||
target.AddThreat(ick, GetEffectValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 1, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_krick_pursuit_AuraScript : AuraScript
|
||||
{
|
||||
void HandleExtraEffect(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
{
|
||||
Creature creCaster = caster.ToCreature();
|
||||
if (creCaster)
|
||||
creCaster.GetAI<boss_ick>()._ResetThreat(GetTarget());
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(HandleExtraEffect, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_krick_pursuit_confusion : AuraScript
|
||||
{
|
||||
void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().ApplySpellImmune(0, SpellImmunity.State, AuraType.ModTaunt, true);
|
||||
GetTarget().ApplySpellImmune(0, SpellImmunity.Effect, SpellEffectName.AttackMe, true);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().ApplySpellImmune(0, SpellImmunity.State, AuraType.ModTaunt, false);
|
||||
GetTarget().ApplySpellImmune(0, SpellImmunity.Effect, SpellEffectName.AttackMe, false);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectApply.Add(new EffectApplyHandler(OnApply, 2, AuraType.Linked, AuraEffectHandleModes.Real));
|
||||
OnEffectRemove.Add(new EffectApplyHandler(OnRemove, 2, AuraType.Linked, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
using System.Collections.Generic;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.Maps;
|
||||
using Framework.Constants;
|
||||
using Framework.Dynamic;
|
||||
|
||||
namespace Scripts.Northrend.FrozenHalls.PitOfSaron
|
||||
{
|
||||
struct Misc
|
||||
{
|
||||
// positions for Martin Victus (37591) and Gorkun Ironskull (37592)
|
||||
public static Position SlaveLeaderPos = new Position(689.7158f, -104.8736f, 513.7360f, 0.0f);
|
||||
// position for Jaina and Sylvanas
|
||||
public static Position EventLeaderPos2 = new Position(1054.368f, 107.14620f, 628.4467f, 0.0f);
|
||||
|
||||
public static DoorData[] Doors =
|
||||
{
|
||||
new DoorData(GameObjectIds.IceWall, DataTypes.Garfrost, DoorType.Passage),
|
||||
new DoorData(GameObjectIds.IceWall, DataTypes.Ick, DoorType.Passage),
|
||||
new DoorData(GameObjectIds.HallsOfReflectionPortcullis, DataTypes.Tyrannus, DoorType.Passage),
|
||||
};
|
||||
}
|
||||
|
||||
class instance_pit_of_saron : InstanceMapScript
|
||||
{
|
||||
public instance_pit_of_saron() : base(nameof(instance_pit_of_saron), 658) { }
|
||||
|
||||
class instance_pit_of_saron_InstanceScript : InstanceScript
|
||||
{
|
||||
public instance_pit_of_saron_InstanceScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("POS");
|
||||
SetBossNumber(3);
|
||||
LoadDoorData(Misc.Doors);
|
||||
_teamInInstance = 0;
|
||||
_cavernActive = 0;
|
||||
_shardsHit = 0;
|
||||
}
|
||||
|
||||
public override void OnPlayerEnter(Player player)
|
||||
{
|
||||
if (_teamInInstance == 0)
|
||||
_teamInInstance = player.GetTeam();
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
if (_teamInInstance == 0)
|
||||
{
|
||||
var players = instance.GetPlayers();
|
||||
if (!players.Empty())
|
||||
{
|
||||
Player player = players[0];
|
||||
if (player)
|
||||
_teamInInstance = player.GetTeam();
|
||||
}
|
||||
}
|
||||
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case CreatureIds.Garfrost:
|
||||
_garfrostGUID = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.Krick:
|
||||
_krickGUID = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.Ick:
|
||||
_ickGUID = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.Tyrannus:
|
||||
_tyrannusGUID = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.Rimefang:
|
||||
_rimefangGUID = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.TyrannusEvents:
|
||||
_tyrannusEventGUID = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.SylvanasPart1:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.JainaPart1);
|
||||
_jainaOrSylvanas1GUID = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.SylvanasPart2:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.JainaPart2);
|
||||
_jainaOrSylvanas2GUID = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.Kilara:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.Elandra);
|
||||
break;
|
||||
case CreatureIds.Koralen:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.Korlaen);
|
||||
break;
|
||||
case CreatureIds.Champion1Horde:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.Champion1Alliance);
|
||||
break;
|
||||
case CreatureIds.Champion2Horde:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.Champion2Alliance);
|
||||
break;
|
||||
case CreatureIds.Champion3Horde: // No 3rd set for Alliance?
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.Champion2Alliance);
|
||||
break;
|
||||
case CreatureIds.HordeSlave1:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.AllianceSlave1);
|
||||
break;
|
||||
case CreatureIds.HordeSlave2:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.AllianceSlave2);
|
||||
break;
|
||||
case CreatureIds.HordeSlave3:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.AllianceSlave3);
|
||||
break;
|
||||
case CreatureIds.HordeSlave4:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.AllianceSlave4);
|
||||
break;
|
||||
case CreatureIds.FreedSlave1Horde:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.FreedSlave1Alliance);
|
||||
break;
|
||||
case CreatureIds.FreedSlave2Horde:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.FreedSlave2Alliance);
|
||||
break;
|
||||
case CreatureIds.FreedSlave3Horde:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.FreedSlave3Alliance);
|
||||
break;
|
||||
case CreatureIds.RescuedSlaveHorde:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.RescuedSlaveAlliance);
|
||||
break;
|
||||
case CreatureIds.MartinVictus1:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.MartinVictus1);
|
||||
break;
|
||||
case CreatureIds.MartinVictus2:
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.MartinVictus2);
|
||||
break;
|
||||
case CreatureIds.CavernEventTrigger:
|
||||
_cavernstriggersVector.Add(creature.GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GameObjectIds.IceWall:
|
||||
case GameObjectIds.HallsOfReflectionPortcullis:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectRemove(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GameObjectIds.IceWall:
|
||||
case GameObjectIds.HallsOfReflectionPortcullis:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SetBossState(uint type, EncounterState state)
|
||||
{
|
||||
if (!base.SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.Garfrost:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
Creature summoner = instance.GetCreature(_garfrostGUID);
|
||||
if (summoner)
|
||||
{
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
summoner.SummonCreature(CreatureIds.MartinVictus1, Misc.SlaveLeaderPos, TempSummonType.ManualDespawn);
|
||||
else
|
||||
summoner.SummonCreature(CreatureIds.GorkunIronskull2, Misc.SlaveLeaderPos, TempSummonType.ManualDespawn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DataTypes.Tyrannus:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
Creature summoner = instance.GetCreature(_tyrannusGUID);
|
||||
if (summoner)
|
||||
{
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
summoner.SummonCreature(CreatureIds.JainaPart2, Misc.EventLeaderPos2, TempSummonType.ManualDespawn);
|
||||
else
|
||||
summoner.SummonCreature(CreatureIds.SylvanasPart2, Misc.EventLeaderPos2, TempSummonType.ManualDespawn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.TeamInInstance:
|
||||
return (uint)_teamInInstance;
|
||||
case DataTypes.IceShardsHit:
|
||||
return _shardsHit;
|
||||
case DataTypes.CavernActive:
|
||||
return _cavernActive;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void SetData(uint type, uint data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.IceShardsHit:
|
||||
_shardsHit = (byte)data;
|
||||
break;
|
||||
case DataTypes.CavernActive:
|
||||
if (data != 0)
|
||||
{
|
||||
_cavernActive = (byte)data;
|
||||
HandleCavernEventTrigger(true);
|
||||
}
|
||||
else
|
||||
HandleCavernEventTrigger(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.Garfrost:
|
||||
return _garfrostGUID;
|
||||
case DataTypes.Krick:
|
||||
return _krickGUID;
|
||||
case DataTypes.Ick:
|
||||
return _ickGUID;
|
||||
case DataTypes.Tyrannus:
|
||||
return _tyrannusGUID;
|
||||
case DataTypes.Rimefang:
|
||||
return _rimefangGUID;
|
||||
case DataTypes.TyrannusEvent:
|
||||
return _tyrannusEventGUID;
|
||||
case DataTypes.JainaSylvanas1:
|
||||
return _jainaOrSylvanas1GUID;
|
||||
case DataTypes.JainaSylvanas2:
|
||||
return _jainaOrSylvanas2GUID;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
void HandleCavernEventTrigger(bool activate)
|
||||
{
|
||||
foreach (ObjectGuid guid in _cavernstriggersVector)
|
||||
{
|
||||
Creature trigger = instance.GetCreature(guid);
|
||||
if (trigger)
|
||||
{
|
||||
if (activate)
|
||||
trigger.m_Events.AddEvent(new ScheduledIcicleSummons(trigger), trigger.m_Events.CalculateTime(1000));
|
||||
else
|
||||
trigger.m_Events.KillAllEvents(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid _garfrostGUID;
|
||||
ObjectGuid _krickGUID;
|
||||
ObjectGuid _ickGUID;
|
||||
ObjectGuid _tyrannusGUID;
|
||||
ObjectGuid _rimefangGUID;
|
||||
|
||||
ObjectGuid _tyrannusEventGUID;
|
||||
ObjectGuid _jainaOrSylvanas1GUID;
|
||||
ObjectGuid _jainaOrSylvanas2GUID;
|
||||
List<ObjectGuid> _cavernstriggersVector = new List<ObjectGuid>();
|
||||
|
||||
Team _teamInInstance;
|
||||
byte _shardsHit;
|
||||
byte _cavernActive;
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_pit_of_saron_InstanceScript(map);
|
||||
}
|
||||
}
|
||||
|
||||
class ScheduledIcicleSummons : BasicEvent
|
||||
{
|
||||
public ScheduledIcicleSummons(Creature trigger)
|
||||
{
|
||||
_trigger = trigger;
|
||||
}
|
||||
|
||||
public override bool Execute(ulong time, uint diff)
|
||||
{
|
||||
if (RandomHelper.randChance(12))
|
||||
{
|
||||
_trigger.CastSpell(_trigger, SpellIds.IcicleSummon, true);
|
||||
_trigger.m_Events.AddEvent(new ScheduledIcicleSummons(_trigger), _trigger.m_Events.CalculateTime(RandomHelper.URand(20000, 35000)));
|
||||
}
|
||||
else
|
||||
_trigger.m_Events.AddEvent(new ScheduledIcicleSummons(_trigger), _trigger.m_Events.CalculateTime(RandomHelper.URand(1000, 20000)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Creature _trigger;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
using System;
|
||||
using Game.Entities;
|
||||
using Game.AI;
|
||||
using Game.Spells;
|
||||
using Game.DataStorage;
|
||||
using Game.Scripting;
|
||||
using Framework.Constants;
|
||||
using Game.Maps;
|
||||
|
||||
namespace Scripts.Northrend.FrozenHalls.PitOfSaron
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayTyrannusCavernEntrance = 3;
|
||||
}
|
||||
|
||||
struct DataTypes
|
||||
{
|
||||
// Encounter States And Guids
|
||||
public const uint Garfrost = 0;
|
||||
public const uint Ick = 1;
|
||||
public const uint Tyrannus = 2;
|
||||
|
||||
// Guids
|
||||
public const uint Rimefang = 3;
|
||||
public const uint Krick = 4;
|
||||
public const uint JainaSylvanas1 = 5; // Guid Of Either Jaina Or Sylvanas Part 1; Depending On Team; As It'S The Same Spawn.
|
||||
public const uint JainaSylvanas2 = 6; // Guid Of Either Jaina Or Sylvanas Part 2; Depending On Team; As It'S The Same Spawn.
|
||||
public const uint TyrannusEvent = 7;
|
||||
public const uint TeamInInstance = 8;
|
||||
public const uint IceShardsHit = 9;
|
||||
public const uint CavernActive = 10;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint Garfrost = 36494;
|
||||
public const uint Krick = 36477;
|
||||
public const uint Ick = 36476;
|
||||
public const uint Tyrannus = 36658;
|
||||
public const uint Rimefang = 36661;
|
||||
|
||||
public const uint TyrannusEvents = 36794;
|
||||
public const uint SylvanasPart1 = 36990;
|
||||
public const uint SylvanasPart2 = 38189;
|
||||
public const uint JainaPart1 = 36993;
|
||||
public const uint JainaPart2 = 38188;
|
||||
public const uint Kilara = 37583;
|
||||
public const uint Elandra = 37774;
|
||||
public const uint Koralen = 37779;
|
||||
public const uint Korlaen = 37582;
|
||||
public const uint Champion1Horde = 37584;
|
||||
public const uint Champion2Horde = 37587;
|
||||
public const uint Champion3Horde = 37588;
|
||||
public const uint Champion1Alliance = 37496;
|
||||
public const uint Champion2Alliance = 37497;
|
||||
|
||||
public const uint HordeSlave1 = 36770;
|
||||
public const uint HordeSlave2 = 36771;
|
||||
public const uint HordeSlave3 = 36772;
|
||||
public const uint HordeSlave4 = 36773;
|
||||
public const uint AllianceSlave1 = 36764;
|
||||
public const uint AllianceSlave2 = 36765;
|
||||
public const uint AllianceSlave3 = 36766;
|
||||
public const uint AllianceSlave4 = 36767;
|
||||
public const uint FreedSlave1Alliance = 37575;
|
||||
public const uint FreedSlave2Alliance = 37572;
|
||||
public const uint FreedSlave3Alliance = 37576;
|
||||
public const uint FreedSlave1Horde = 37579;
|
||||
public const uint FreedSlave2Horde = 37578;
|
||||
public const uint FreedSlave3Horde = 37577;
|
||||
public const uint RescuedSlaveAlliance = 36888;
|
||||
public const uint RescuedSlaveHorde = 36889;
|
||||
public const uint MartinVictus1 = 37591;
|
||||
public const uint MartinVictus2 = 37580;
|
||||
public const uint GorkunIronskull1 = 37581;
|
||||
public const uint GorkunIronskull2 = 37592;
|
||||
|
||||
public const uint ForgemasterStalker = 36495;
|
||||
public const uint ExplodingOrb = 36610;
|
||||
public const uint YmirjarDeathbringer = 36892;
|
||||
public const uint IcyBlast = 36731;
|
||||
public const uint CavernEventTrigger = 32780;
|
||||
}
|
||||
|
||||
struct GameObjectIds
|
||||
{
|
||||
public const uint SaroniteRock = 196485;
|
||||
public const uint IceWall = 201885;
|
||||
public const uint HallsOfReflectionPortcullis = 201848;
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint IcicleSummon = 69424;
|
||||
public const uint IcicleFallTrigger = 69426;
|
||||
public const uint IcicleFallVisual = 69428;
|
||||
public const uint AchievDontLookUpCredit = 72845;
|
||||
|
||||
public const uint Fireball = 69583; //Ymirjar Flamebearer
|
||||
public const uint Hellfire = 69586;
|
||||
public const uint TacticalBlink = 69584;
|
||||
public const uint FrostBreath = 69527; //Iceborn Proto-Drake
|
||||
public const uint LeapingFaceMaul = 69504; // Geist Ambusher
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_ymirjar_flamebearer : ScriptedAI
|
||||
{
|
||||
public npc_ymirjar_flamebearer(Creature creature) : base(creature)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Fireball);
|
||||
task.Repeat(TimeSpan.FromSeconds(5));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.TacticalBlink);
|
||||
DoCast(me, SpellIds.Hellfire);
|
||||
task.Repeat(TimeSpan.FromSeconds(12));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_iceborn_protodrake : ScriptedAI
|
||||
{
|
||||
public npc_iceborn_protodrake(Creature creature) : base(creature) { }
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
Vehicle vehicle = me.GetVehicleKit();
|
||||
if (vehicle)
|
||||
vehicle.RemoveAllPassengers();
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.FrostBreath);
|
||||
task.Repeat(TimeSpan.FromSeconds(10));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_geist_ambusher : ScriptedAI
|
||||
{
|
||||
public npc_geist_ambusher(Creature creature) : base(creature) { }
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
if (who.GetTypeId() != TypeId.Player)
|
||||
return;
|
||||
|
||||
// the max range is determined by aggro range
|
||||
if (me.GetDistance(who) > 5.0f)
|
||||
DoCast(who, SpellIds.LeapingFaceMaul);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(9), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 5.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.LeapingFaceMaul);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(9), TimeSpan.FromSeconds(14));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_trash_npc_glacial_strike : AuraScript
|
||||
{
|
||||
void PeriodicTick(AuraEffect aurEff)
|
||||
{
|
||||
if (GetTarget().IsFullHealth())
|
||||
{
|
||||
GetTarget().RemoveAura(GetId(), ObjectGuid.Empty, 0, AuraRemoveMode.EnemySpell);
|
||||
PreventDefaultAction();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(PeriodicTick, 2, AuraType.PeriodicDamagePercent));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_pit_of_saron_icicle : PassiveAI
|
||||
{
|
||||
public npc_pit_of_saron_icicle(Creature creature) : base(creature)
|
||||
{
|
||||
me.SetDisplayId(me.GetCreatureTemplate().ModelId1);
|
||||
}
|
||||
|
||||
public override void IsSummonedBy(Unit summoner)
|
||||
{
|
||||
_summonerGUID = summoner.GetGUID();
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromMilliseconds(3650), task =>
|
||||
{
|
||||
DoCastSelf(SpellIds.IcicleFallTrigger, true);
|
||||
DoCastSelf(SpellIds.IcicleFallVisual);
|
||||
|
||||
Unit caster = Global.ObjAccessor.GetUnit(me, _summonerGUID);
|
||||
if (caster)
|
||||
caster.RemoveDynObject(SpellIds.IcicleSummon);
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
ObjectGuid _summonerGUID;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_pos_ice_shards : SpellScript
|
||||
{
|
||||
void HandleScriptEffect(uint effIndex)
|
||||
{
|
||||
if (GetHitPlayer())
|
||||
GetCaster().GetInstanceScript().SetData(DataTypes.CavernActive, 1);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.SchoolDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class at_pit_cavern_entrance : AreaTriggerScript
|
||||
{
|
||||
public at_pit_cavern_entrance() : base("at_pit_cavern_entrance") { }
|
||||
|
||||
public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger, bool entered)
|
||||
{
|
||||
if (!entered)
|
||||
return true;
|
||||
|
||||
InstanceScript instance = player.GetInstanceScript();
|
||||
if (instance != null)
|
||||
{
|
||||
if (instance.GetData(DataTypes.CavernActive) != 0)
|
||||
return true;
|
||||
|
||||
instance.SetData(DataTypes.CavernActive, 1);
|
||||
|
||||
Creature tyrannus = ObjectAccessor.GetCreature(player, instance.GetGuidData(DataTypes.TyrannusEvent));
|
||||
if (tyrannus)
|
||||
tyrannus.GetAI().Talk(TextIds.SayTyrannusCavernEntrance);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class at_pit_cavern_end : AreaTriggerScript
|
||||
{
|
||||
public at_pit_cavern_end() : base("at_pit_cavern_end") { }
|
||||
|
||||
public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger, bool entered)
|
||||
{
|
||||
if (!entered)
|
||||
return true;
|
||||
|
||||
InstanceScript instance = player.GetInstanceScript();
|
||||
if (instance != null)
|
||||
{
|
||||
instance.SetData(DataTypes.CavernActive, 0);
|
||||
|
||||
if (instance.GetData(DataTypes.IceShardsHit) == 0)
|
||||
instance.DoUpdateCriteria(CriteriaTypes.BeSpellTarget, SpellIds.AchievDontLookUpCredit, 0, player);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace Scripts.Northrend.Gundrak.DrakkariColossus
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
// Drakkari Elemental
|
||||
public const uint EmoteMojo = 0;
|
||||
public const uint EmoteActivateAltar = 1;
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Emerge = 54850;
|
||||
public const uint ElementalSpawnEffect = 54888;
|
||||
public const uint MojoVolley = 54849;
|
||||
public const uint SurgeVisual = 54827;
|
||||
public const uint Merge = 54878;
|
||||
public const uint MightyBlow = 54719;
|
||||
public const uint Surge = 54801;
|
||||
public const uint FreezeAnim = 16245;
|
||||
public const uint MojoPuddle = 55627;
|
||||
public const uint MojoWave = 55626;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint EventMightyBlow = 1;
|
||||
public const uint EventSurge = 1;
|
||||
|
||||
public const int ActionSummonElemental = 1;
|
||||
public const int ActionFreezeColossus = 2;
|
||||
public const int ActionUnfreezeColossus = 3;
|
||||
public const int ActionReturnToColossus = 1;
|
||||
|
||||
public const byte ColossusPhaseNormal = 1;
|
||||
public const byte ColossusPhaseFirstElementalSummon = 2;
|
||||
public const byte ColossusPhaseSecondElementalSummon = 3;
|
||||
|
||||
public const uint DataColossusPhase = 1;
|
||||
public const uint DataIntroDone = 2;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_drakkari_colossus : BossAI
|
||||
{
|
||||
public boss_drakkari_colossus(Creature creature) : base(creature, GDDataTypes.DrakkariColossus)
|
||||
{
|
||||
Initialize();
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
introDone = false;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
phase = Misc.ColossusPhaseNormal;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
|
||||
if (GetData(Misc.DataIntroDone) != 0)
|
||||
{
|
||||
me.SetReactState(ReactStates.Aggressive);
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
|
||||
me.RemoveAura(SpellIds.FreezeAnim);
|
||||
}
|
||||
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.MightyBlow);
|
||||
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
me.RemoveAura(SpellIds.FreezeAnim);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case Misc.ActionSummonElemental:
|
||||
DoCast(SpellIds.Emerge);
|
||||
break;
|
||||
case Misc.ActionFreezeColossus:
|
||||
me.GetMotionMaster().Clear();
|
||||
me.GetMotionMaster().MoveIdle();
|
||||
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
|
||||
DoCast(me, SpellIds.FreezeAnim);
|
||||
break;
|
||||
case Misc.ActionUnfreezeColossus:
|
||||
if (me.GetReactState() == ReactStates.Aggressive)
|
||||
return;
|
||||
|
||||
me.SetReactState(ReactStates.Aggressive);
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
|
||||
me.RemoveAura(SpellIds.FreezeAnim);
|
||||
|
||||
me.SetInCombatWithZone();
|
||||
|
||||
if (me.GetVictim())
|
||||
me.GetMotionMaster().MoveChase(me.GetVictim(), 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (me.HasFlag(UnitFields.Flags, UnitFlags.ImmuneToPc))
|
||||
damage = 0;
|
||||
|
||||
if (phase == Misc.ColossusPhaseNormal ||
|
||||
phase == Misc.ColossusPhaseFirstElementalSummon)
|
||||
{
|
||||
if (HealthBelowPct(phase == Misc.ColossusPhaseNormal ? 50 : 5))
|
||||
{
|
||||
damage = 0;
|
||||
phase = (phase == Misc.ColossusPhaseNormal ? Misc.ColossusPhaseFirstElementalSummon : Misc.ColossusPhaseSecondElementalSummon);
|
||||
DoAction(Misc.ActionFreezeColossus);
|
||||
DoAction(Misc.ActionSummonElemental);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override uint GetData(uint data)
|
||||
{
|
||||
if (data == Misc.DataColossusPhase)
|
||||
return phase;
|
||||
else if (data == Misc.DataIntroDone)
|
||||
return introDone ? 1 : 0u;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void SetData(uint type, uint data)
|
||||
{
|
||||
if (type == Misc.DataIntroDone)
|
||||
introDone = data != 0;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
if (me.GetReactState() == ReactStates.Aggressive)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon)
|
||||
{
|
||||
summon.SetInCombatWithZone();
|
||||
|
||||
if (phase == Misc.ColossusPhaseSecondElementalSummon)
|
||||
summon.SetHealth(summon.GetMaxHealth() / 2);
|
||||
}
|
||||
|
||||
byte phase;
|
||||
bool introDone;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_drakkari_elemental : ScriptedAI
|
||||
{
|
||||
public boss_drakkari_elemental(Creature creature) : base(creature)
|
||||
{
|
||||
DoCast(me, SpellIds.ElementalSpawnEffect);
|
||||
instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCast(SpellIds.SurgeVisual);
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 0.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Surge);
|
||||
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
|
||||
me.AddAura(SpellIds.MojoVolley, me);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(TextIds.EmoteActivateAltar);
|
||||
|
||||
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
|
||||
if (colossus)
|
||||
killer.Kill(colossus);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case Misc.ActionReturnToColossus:
|
||||
Talk(TextIds.EmoteMojo);
|
||||
DoCast(SpellIds.SurgeVisual);
|
||||
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
|
||||
if (colossus)
|
||||
// what if the elemental is more than 80 yards from drakkari colossus ?
|
||||
DoCast(colossus, SpellIds.Merge, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (HealthBelowPct(50))
|
||||
{
|
||||
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
|
||||
if (colossus)
|
||||
{
|
||||
if (colossus.GetAI().GetData(Misc.DataColossusPhase) == Misc.ColossusPhaseFirstElementalSummon)
|
||||
{
|
||||
damage = 0;
|
||||
|
||||
// to prevent spell spaming
|
||||
if (me.HasUnitState(UnitState.Charging))
|
||||
return;
|
||||
|
||||
// not sure about this, the idea of this code is to prevent bug the elemental
|
||||
// if it is not in a acceptable distance to cast the charge spell.
|
||||
if (me.GetDistance(colossus) > 80.0f)
|
||||
{
|
||||
if (me.GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Point)
|
||||
return;
|
||||
|
||||
me.GetMotionMaster().MovePoint(0, colossus.GetPositionX(), colossus.GetPositionY(), colossus.GetPositionZ());
|
||||
return;
|
||||
}
|
||||
DoAction(Misc.ActionReturnToColossus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
public override void SpellHitTarget(Unit target, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id == SpellIds.Merge)
|
||||
{
|
||||
Creature colossus = target.ToCreature();
|
||||
if (colossus)
|
||||
{
|
||||
colossus.GetAI().DoAction(Misc.ActionUnfreezeColossus);
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_living_mojo : ScriptedAI
|
||||
{
|
||||
public npc_living_mojo(Creature creature) : base(creature)
|
||||
{
|
||||
instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(2), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.MojoWave);
|
||||
task.Repeat(TimeSpan.FromSeconds(15));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.MojoPuddle);
|
||||
task.Repeat(TimeSpan.FromSeconds(18));
|
||||
});
|
||||
}
|
||||
|
||||
void MoveMojos(Creature boss)
|
||||
{
|
||||
List<Creature> mojosList = new List<Creature>();
|
||||
boss.GetCreatureListWithEntryInGrid(mojosList, me.GetEntry(), 12.0f);
|
||||
if (!mojosList.Empty())
|
||||
{
|
||||
foreach (var mojo in mojosList)
|
||||
{
|
||||
if (mojo)
|
||||
mojo.GetMotionMaster().MovePoint(1, boss.GetHomePosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Point)
|
||||
return;
|
||||
|
||||
if (id == 1)
|
||||
{
|
||||
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
|
||||
if (colossus)
|
||||
{
|
||||
colossus.GetAI().DoAction(Misc.ActionUnfreezeColossus);
|
||||
if (colossus.GetAI().GetData(Misc.DataIntroDone) == 0)
|
||||
colossus.GetAI().SetData(Misc.DataIntroDone, 1);
|
||||
colossus.SetInCombatWithZone();
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void AttackStart(Unit attacker)
|
||||
{
|
||||
if (me.GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Point)
|
||||
return;
|
||||
|
||||
// we do this checks to see if the creature is one of the creatures that sorround the boss
|
||||
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
|
||||
if (colossus)
|
||||
{
|
||||
Position homePosition = me.GetHomePosition();
|
||||
|
||||
float distance = homePosition.GetExactDist(colossus.GetHomePosition());
|
||||
|
||||
if (distance < 12.0f)
|
||||
{
|
||||
MoveMojos(colossus);
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
}
|
||||
else
|
||||
base.AttackStart(attacker);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.Northrend.Gundrak.EckTheFerocious
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
public const uint EmoteSpawn = 0;
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Berserk = 55816; // Eck goes berserk, increasing his attack speed by 150% and all damage he deals by 500%.
|
||||
public const uint Bite = 55813; // Eck bites down hard, inflicting 150% of his normal damage to an enemy.
|
||||
public const uint Spit = 55814; // Eck spits toxic bile at enemies in a cone in front of him, inflicting 2970 Nature damage and draining 220 mana every 1 sec for 3 sec.
|
||||
public const uint Spring1 = 55815; // Eck leaps at a distant target. --> Drops aggro and charges a random player. Tank can simply taunt him back.
|
||||
public const uint Spring2 = 55837; // Eck leaps at a distant target.
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_eck : BossAI
|
||||
{
|
||||
public boss_eck(Creature creature) : base(creature, GDDataTypes.EckTheFerocious)
|
||||
{
|
||||
Initialize();
|
||||
Talk(TextIds.EmoteSpawn);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_berserk = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Bite);
|
||||
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Spit);
|
||||
task.Repeat(TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(14));
|
||||
});
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 35.0f, true);
|
||||
if (target)
|
||||
DoCast(target, RandomHelper.RAND(SpellIds.Spring1, SpellIds.Spring2));
|
||||
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10));
|
||||
});
|
||||
|
||||
// 60-90 secs according to wowwiki
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(90), 1, task =>
|
||||
{
|
||||
DoCast(me, SpellIds.Berserk);
|
||||
_berserk = true;
|
||||
});
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (!_berserk && me.HealthBelowPctDamaged(20, damage))
|
||||
{
|
||||
_scheduler.RescheduleGroup(1, TimeSpan.FromSeconds(1));
|
||||
_berserk = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool _berserk;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* 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 Framework.IO;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Scripts.Northrend.Gundrak
|
||||
{
|
||||
struct GDInstanceMisc
|
||||
{
|
||||
public const uint TimerStatueActivation = 3500;
|
||||
|
||||
public static DoorData[] doorData =
|
||||
{
|
||||
new DoorData(GDGameObjectIds.GalDarahDoor1, GDDataTypes.GalDarah, DoorType.Passage),
|
||||
new DoorData(GDGameObjectIds.GalDarahDoor2, GDDataTypes.GalDarah, DoorType.Passage),
|
||||
new DoorData(GDGameObjectIds.GalDarahDoor3, GDDataTypes.GalDarah, DoorType.Room),
|
||||
new DoorData(GDGameObjectIds.EckTheFerociousDoor, GDDataTypes.Moorabi, DoorType.Passage),
|
||||
new DoorData(GDGameObjectIds.EckTheFerociousDoorBehind, GDDataTypes.EckTheFerocious, DoorType.Passage),
|
||||
};
|
||||
|
||||
public static ObjectData[] creatureData =
|
||||
{
|
||||
new ObjectData(GDCreatureIds.DrakkariColossus, GDDataTypes.DrakkariColossus),
|
||||
};
|
||||
|
||||
public static ObjectData[] gameObjectData =
|
||||
{
|
||||
new ObjectData(GDGameObjectIds.SladRanAltar, GDDataTypes.SladRanAltar),
|
||||
new ObjectData(GDGameObjectIds.MoorabiAltar, GDDataTypes.MoorabiAltar),
|
||||
new ObjectData(GDGameObjectIds.DrakkariColossusAltar, GDDataTypes.DrakkariColossusAltar),
|
||||
new ObjectData(GDGameObjectIds.SladRanStatue, GDDataTypes.SladRanStatue),
|
||||
new ObjectData(GDGameObjectIds.MoorabiStatue, GDDataTypes.MoorabiStatue),
|
||||
new ObjectData(GDGameObjectIds.DrakkariColossusStatue, GDDataTypes.DrakkariColossusStatue),
|
||||
new ObjectData(GDGameObjectIds.GalDarahStatue, GDDataTypes.GalDarahStatue),
|
||||
new ObjectData(GDGameObjectIds.Trapdoor, GDDataTypes.Trapdoor),
|
||||
new ObjectData(GDGameObjectIds.Collision, GDDataTypes.Collision)
|
||||
};
|
||||
|
||||
public static Position EckSpawnPoint = new Position(1643.877930f, 936.278015f, 107.204948f, 0.668432f);
|
||||
}
|
||||
|
||||
struct GDDataTypes
|
||||
{
|
||||
// Encounter Ids // Encounter States // Boss Guids
|
||||
public const uint SladRan = 0;
|
||||
public const uint DrakkariColossus = 1;
|
||||
public const uint Moorabi = 2;
|
||||
public const uint GalDarah = 3;
|
||||
public const uint EckTheFerocious = 4;
|
||||
|
||||
// Additional Objects
|
||||
public const uint SladRanAltar = 5;
|
||||
public const uint DrakkariColossusAltar = 6;
|
||||
public const uint MoorabiAltar = 7;
|
||||
|
||||
public const uint SladRanStatue = 8;
|
||||
public const uint DrakkariColossusStatue = 9;
|
||||
public const uint MoorabiStatue = 10;
|
||||
public const uint GalDarahStatue = 11;
|
||||
|
||||
public const uint Trapdoor = 12;
|
||||
public const uint Collision = 13;
|
||||
public const uint Bridge = 14;
|
||||
|
||||
public const uint StatueActivate = 15;
|
||||
}
|
||||
|
||||
struct GDCreatureIds
|
||||
{
|
||||
public const uint SladRan = 29304;
|
||||
public const uint Moorabi = 29305;
|
||||
public const uint GalDarah = 29306;
|
||||
public const uint DrakkariColossus = 29307;
|
||||
public const uint RuinDweller = 29920;
|
||||
public const uint EckTheFerocious = 29932;
|
||||
public const uint AltarTrigger = 30298;
|
||||
}
|
||||
|
||||
struct GDGameObjectIds
|
||||
{
|
||||
public const uint SladRanAltar = 192518;
|
||||
public const uint MoorabiAltar = 192519;
|
||||
public const uint DrakkariColossusAltar = 192520;
|
||||
public const uint SladRanStatue = 192564;
|
||||
public const uint MoorabiStatue = 192565;
|
||||
public const uint GalDarahStatue = 192566;
|
||||
public const uint DrakkariColossusStatue = 192567;
|
||||
public const uint EckTheFerociousDoor = 192632;
|
||||
public const uint EckTheFerociousDoorBehind = 192569;
|
||||
public const uint GalDarahDoor1 = 193208;
|
||||
public const uint GalDarahDoor2 = 193209;
|
||||
public const uint GalDarahDoor3 = 192568;
|
||||
public const uint Trapdoor = 193188;
|
||||
public const uint Collision = 192633;
|
||||
}
|
||||
|
||||
struct GDSpellIds
|
||||
{
|
||||
public const uint FireBeamMammoth = 57068;
|
||||
public const uint FireBeamSnake = 57071;
|
||||
public const uint FireBeamElemental = 57072;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class instance_gundrak : InstanceMapScript
|
||||
{
|
||||
public instance_gundrak() : base(nameof(instance_gundrak), 604) { }
|
||||
|
||||
class instance_gundrak_InstanceMapScript : InstanceScript
|
||||
{
|
||||
public instance_gundrak_InstanceMapScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("GD");
|
||||
SetBossNumber(5);
|
||||
LoadDoorData(GDInstanceMisc.doorData);
|
||||
LoadObjectData(GDInstanceMisc.creatureData, GDInstanceMisc.gameObjectData);
|
||||
|
||||
SladRanStatueState = GameObjectState.Active;
|
||||
DrakkariColossusStatueState = GameObjectState.Active;
|
||||
MoorabiStatueState = GameObjectState.Active;
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case GDCreatureIds.RuinDweller:
|
||||
if (creature.IsAlive())
|
||||
DwellerGUIDs.Add(creature.GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
base.OnCreatureCreate(creature);
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GDGameObjectIds.SladRanAltar:
|
||||
if (GetBossState(GDDataTypes.SladRan) == EncounterState.Done)
|
||||
{
|
||||
if (SladRanStatueState == GameObjectState.Active)
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
else
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
}
|
||||
break;
|
||||
case GDGameObjectIds.MoorabiAltar:
|
||||
if (GetBossState(GDDataTypes.Moorabi) == EncounterState.Done)
|
||||
{
|
||||
if (MoorabiStatueState == GameObjectState.Active)
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
else
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
}
|
||||
break;
|
||||
case GDGameObjectIds.DrakkariColossusAltar:
|
||||
if (GetBossState(GDDataTypes.DrakkariColossus) == EncounterState.Done)
|
||||
{
|
||||
if (DrakkariColossusStatueState == GameObjectState.Active)
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
else
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
}
|
||||
break;
|
||||
case GDGameObjectIds.SladRanStatue:
|
||||
go.SetGoState(SladRanStatueState);
|
||||
break;
|
||||
case GDGameObjectIds.MoorabiStatue:
|
||||
go.SetGoState(MoorabiStatueState);
|
||||
break;
|
||||
case GDGameObjectIds.GalDarahStatue:
|
||||
go.SetGoState(CheckRequiredBosses(GDDataTypes.GalDarah) ? GameObjectState.ActiveAlternative : GameObjectState.Ready);
|
||||
break;
|
||||
case GDGameObjectIds.DrakkariColossusStatue:
|
||||
go.SetGoState(DrakkariColossusStatueState);
|
||||
break;
|
||||
case GDGameObjectIds.EckTheFerociousDoor:
|
||||
// Don't store door on non-heroic
|
||||
if (!instance.IsHeroic())
|
||||
return;
|
||||
break;
|
||||
case GDGameObjectIds.Trapdoor:
|
||||
go.SetGoState(CheckRequiredBosses(GDDataTypes.GalDarah) ? GameObjectState.Ready : GameObjectState.Active);
|
||||
break;
|
||||
case GDGameObjectIds.Collision:
|
||||
go.SetGoState(CheckRequiredBosses(GDDataTypes.GalDarah) ? GameObjectState.Active : GameObjectState.Ready);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
base.OnGameObjectCreate(go);
|
||||
}
|
||||
|
||||
public override void OnUnitDeath(Unit unit)
|
||||
{
|
||||
if (unit.GetEntry() == GDCreatureIds.RuinDweller)
|
||||
{
|
||||
DwellerGUIDs.Remove(unit.GetGUID());
|
||||
|
||||
if (DwellerGUIDs.Empty())
|
||||
unit.SummonCreature(GDCreatureIds.EckTheFerocious, GDInstanceMisc.EckSpawnPoint, TempSummonType.CorpseTimedDespawn, 300 * Time.InMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SetBossState(uint type, EncounterState state)
|
||||
{
|
||||
if (!base.SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GDDataTypes.SladRan:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
GameObject go = GetGameObject(GDDataTypes.SladRanAltar);
|
||||
if (go)
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
}
|
||||
break;
|
||||
case GDDataTypes.DrakkariColossus:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
GameObject go = GetGameObject(GDDataTypes.DrakkariColossusAltar);
|
||||
if (go)
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
}
|
||||
break;
|
||||
case GDDataTypes.Moorabi:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
GameObject go = GetGameObject(GDDataTypes.MoorabiAltar);
|
||||
if (go)
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CheckRequiredBosses(uint bossId, Player player = null)
|
||||
{
|
||||
if (_SkipCheckRequiredBosses(player))
|
||||
return true;
|
||||
|
||||
switch (bossId)
|
||||
{
|
||||
case GDDataTypes.EckTheFerocious:
|
||||
if (!instance.IsHeroic() || GetBossState(GDDataTypes.Moorabi) != EncounterState.Done)
|
||||
return false;
|
||||
break;
|
||||
case GDDataTypes.GalDarah:
|
||||
if (SladRanStatueState != GameObjectState.ActiveAlternative
|
||||
|| DrakkariColossusStatueState != GameObjectState.ActiveAlternative
|
||||
|| MoorabiStatueState != GameObjectState.ActiveAlternative)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsBridgeReady()
|
||||
{
|
||||
return SladRanStatueState == GameObjectState.Ready && DrakkariColossusStatueState == GameObjectState.Ready && MoorabiStatueState == GameObjectState.Ready;
|
||||
}
|
||||
|
||||
public override void SetData(uint type, uint data)
|
||||
{
|
||||
if (type == GDDataTypes.StatueActivate)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case GDGameObjectIds.SladRanAltar:
|
||||
_events.ScheduleEvent(GDDataTypes.SladRanStatue, GDInstanceMisc.TimerStatueActivation);
|
||||
break;
|
||||
case GDGameObjectIds.DrakkariColossusAltar:
|
||||
_events.ScheduleEvent(GDDataTypes.DrakkariColossusStatue, GDInstanceMisc.TimerStatueActivation);
|
||||
break;
|
||||
case GDGameObjectIds.MoorabiAltar:
|
||||
_events.ScheduleEvent(GDDataTypes.MoorabiStatue, GDInstanceMisc.TimerStatueActivation);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteSaveDataMore(StringBuilder data)
|
||||
{
|
||||
data.AppendFormat("{0} {1} {2} ", (uint)SladRanStatueState, (uint)DrakkariColossusStatueState, (uint)MoorabiStatueState);
|
||||
}
|
||||
|
||||
public override void ReadSaveDataMore(StringArguments data)
|
||||
{
|
||||
SladRanStatueState = (GameObjectState)data.NextUInt32();
|
||||
DrakkariColossusStatueState = (GameObjectState)data.NextUInt32();
|
||||
MoorabiStatueState = (GameObjectState)data.NextUInt32();
|
||||
|
||||
if (IsBridgeReady())
|
||||
_events.ScheduleEvent(GDDataTypes.Bridge, GDInstanceMisc.TimerStatueActivation);
|
||||
}
|
||||
|
||||
void ToggleGameObject(uint type, GameObjectState state)
|
||||
{
|
||||
GameObject go = GetGameObject(type);
|
||||
if (go)
|
||||
go.SetGoState(state);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GDDataTypes.SladRanStatue:
|
||||
SladRanStatueState = state;
|
||||
break;
|
||||
case GDDataTypes.DrakkariColossusStatue:
|
||||
DrakkariColossusStatueState = state;
|
||||
break;
|
||||
case GDDataTypes.MoorabiStatue:
|
||||
MoorabiStatueState = state;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(uint diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
uint spellId = 0;
|
||||
uint altarId = 0;
|
||||
switch (eventId)
|
||||
{
|
||||
case GDDataTypes.SladRanStatue:
|
||||
spellId = GDSpellIds.FireBeamSnake;
|
||||
altarId = GDDataTypes.SladRanAltar;
|
||||
break;
|
||||
case GDDataTypes.DrakkariColossusStatue:
|
||||
spellId = GDSpellIds.FireBeamElemental;
|
||||
altarId = GDDataTypes.DrakkariColossusAltar;
|
||||
break;
|
||||
case GDDataTypes.MoorabiStatue:
|
||||
spellId = GDSpellIds.FireBeamMammoth;
|
||||
altarId = GDDataTypes.MoorabiAltar;
|
||||
break;
|
||||
case GDDataTypes.Bridge:
|
||||
for (uint type = GDDataTypes.SladRanStatue; type <= GDDataTypes.GalDarahStatue; ++type)
|
||||
ToggleGameObject(type, GameObjectState.ActiveAlternative);
|
||||
ToggleGameObject(GDDataTypes.Trapdoor, GameObjectState.Ready);
|
||||
ToggleGameObject(GDDataTypes.Collision, GameObjectState.Active);
|
||||
SaveToDB();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject altar = GetGameObject(altarId);
|
||||
if (altar)
|
||||
{
|
||||
Creature trigger = altar.FindNearestCreature(GDCreatureIds.AltarTrigger, 10.0f);
|
||||
if (trigger)
|
||||
trigger.CastSpell((Unit)null, spellId, true);
|
||||
}
|
||||
|
||||
// eventId equals statueId
|
||||
ToggleGameObject(eventId, GameObjectState.Ready);
|
||||
|
||||
if (IsBridgeReady())
|
||||
_events.ScheduleEvent(GDDataTypes.Bridge, GDInstanceMisc.TimerStatueActivation);
|
||||
|
||||
SaveToDB();
|
||||
});
|
||||
}
|
||||
|
||||
List<ObjectGuid> DwellerGUIDs = new List<ObjectGuid>();
|
||||
|
||||
GameObjectState SladRanStatueState;
|
||||
GameObjectState DrakkariColossusStatueState;
|
||||
GameObjectState MoorabiStatueState;
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_gundrak_InstanceMapScript(map);
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class go_gundrak_altar : GameObjectScript
|
||||
{
|
||||
public go_gundrak_altar() : base("go_gundrak_altar") { }
|
||||
|
||||
public override bool OnGossipHello(Player player, GameObject go)
|
||||
{
|
||||
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
|
||||
InstanceScript instance = go.GetInstanceScript();
|
||||
if (instance != null)
|
||||
{
|
||||
instance.SetData(GDDataTypes.StatueActivate, go.GetEntry());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,733 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
namespace Scripts.Northrend.IcecrownCitadel
|
||||
{
|
||||
struct IccConst
|
||||
{
|
||||
public const uint WeeklyNPCs = 9;
|
||||
}
|
||||
|
||||
struct Bosses
|
||||
{
|
||||
public const uint LordMarrowgar = 0;
|
||||
public const uint LadyDeathwhisper = 1;
|
||||
public const uint GunshipBattle = 2;
|
||||
public const uint DeathbringerSaurfang = 3;
|
||||
public const uint Festergut = 4;
|
||||
public const uint Rotface = 5;
|
||||
public const uint ProfessorPutricide = 6;
|
||||
public const uint BloodPrinceCouncil = 7;
|
||||
public const uint BloodQueenLanaThel = 8;
|
||||
public const uint SisterSvalna = 9;
|
||||
public const uint ValithriaDreamwalker = 10;
|
||||
public const uint Sindragosa = 11;
|
||||
public const uint TheLichKing = 12;
|
||||
|
||||
public const uint MaxEncounters = 13;
|
||||
}
|
||||
|
||||
struct Texts
|
||||
{
|
||||
// Highlord Tirion Fordring (At Light'S Hammer)
|
||||
public const uint SayTirionIntro1 = 0;
|
||||
public const uint SayTirionIntro2 = 1;
|
||||
public const uint SayTirionIntro3 = 2;
|
||||
public const uint SayTirionIntro4 = 3;
|
||||
public const uint SayTirionIntroH5 = 4;
|
||||
public const uint SayTirionIntroA5 = 5;
|
||||
|
||||
// The Lich King (At Light'S Hammer)
|
||||
public const uint SayLkIntro1 = 0;
|
||||
public const uint SayLkIntro2 = 1;
|
||||
public const uint SayLkIntro3 = 2;
|
||||
public const uint SayLkIntro4 = 3;
|
||||
public const uint SayLkIntro5 = 4;
|
||||
|
||||
// Highlord Bolvar Fordragon (At Light'S Hammer)
|
||||
public const uint SayBolvarIntro1 = 0;
|
||||
|
||||
// High Overlord Saurfang (At Light'S Hammer)
|
||||
public const uint SaySaurfangIntro1 = 15;
|
||||
public const uint SaySaurfangIntro2 = 16;
|
||||
public const uint SaySaurfangIntro3 = 17;
|
||||
public const uint SaySaurfangIntro4 = 18;
|
||||
|
||||
// Muradin Bronzebeard (At Light'S Hammer)
|
||||
public const uint SayMuradinIntro1 = 13;
|
||||
public const uint SayMuradinIntro2 = 14;
|
||||
public const uint SayMuradinIntro3 = 15;
|
||||
|
||||
// Deathbound Ward
|
||||
public const uint SayTrapActivate = 0;
|
||||
|
||||
// Rotting Frost Giant
|
||||
public const uint EmoteDeathPlagueWarning = 0;
|
||||
|
||||
// Sister Svalna
|
||||
public const uint SaySvalnaKillCaptain = 1; // Happens When She Kills A Captain
|
||||
public const uint SaySvalnaKill = 4;
|
||||
public const uint SaySvalnaCaptainDeath = 5; // Happens When A Captain Resurrected By Her Dies
|
||||
public const uint SaySvalnaDeath = 6;
|
||||
public const uint EmoteSvalnaImpale = 7;
|
||||
public const uint EmoteSvalnaBrokenShield = 8;
|
||||
|
||||
public const uint SayCrokIntro1 = 0; // Ready Your Arms; My Argent Brothers. The Vrykul Will Protect The Frost Queen With Their Lives.
|
||||
public const uint SayArnathIntro2 = 5; // Even Dying Here Beats Spending Another Day Collecting Reagents For That Madman; Finklestein.
|
||||
public const uint SayCrokIntro3 = 1; // Enough Idle Banter! Our Champions Have Arrived - Support Them As We Push Our Way Through The Hall!
|
||||
public const uint SaySvalnaEventStart = 0; // You May Have Once Fought Beside Me; Crok; But Now You Are Nothing More Than A Traitor. Come; Your Second Death Approaches!
|
||||
public const uint SayCrokCombatWp0 = 2; // Draw Them Back To Us; And We'Ll Assist You.
|
||||
public const uint SayCrokCombatWp1 = 3; // Quickly; Push On!
|
||||
public const uint SayCrokFinalWp = 4; // Her Reinforcements Will Arrive Shortly; We Must Bring Her Down Quickly!
|
||||
public const uint SaySvalnaResurrectCaptains = 2; // Foolish Crok. You Brought My Reinforcements With You. Arise; Argent Champions; And Serve The Lich King In Death!
|
||||
public const uint SayCrokCombatSvalna = 5; // I'Ll Draw Her Attacks. Return Our Brothers To Their Graves; Then Help Me Bring Her Down!
|
||||
public const uint SaySvalnaAggro = 3; // Come; Scourgebane. I'Ll Show The Master Which Of Us Is Truly Worthy Of The Title Of "Champion"!
|
||||
public const uint SayCaptainDeath = 0;
|
||||
public const uint SayCaptainResurrected = 1;
|
||||
public const uint SayCaptainKill = 2;
|
||||
public const uint SayCaptainSecondDeath = 3;
|
||||
public const uint SayCaptainSurviveTalk = 4;
|
||||
public const uint SayCrokWeakeningGauntlet = 6;
|
||||
public const uint SayCrokWeakeningSvalna = 7;
|
||||
public const uint SayCrokDeath = 8;
|
||||
}
|
||||
|
||||
struct InstanceSpells
|
||||
{
|
||||
// Rotting Frost Giant
|
||||
public const uint DeathPlague = 72879;
|
||||
public const uint DeathPlagueAura = 72865;
|
||||
public const uint RecentlyInfected = 72884;
|
||||
public const uint DeathPlagueKill = 72867;
|
||||
public const uint Stomp = 64652;
|
||||
public const uint ArcticBreath = 72848;
|
||||
|
||||
// Frost Freeze Trap
|
||||
public const uint ColdflameJets = 70460;
|
||||
|
||||
// Alchemist Adrianna
|
||||
public const uint HarvestBlightSpecimen = 72155;
|
||||
public const uint HarvestBlightSpecimen25 = 72162;
|
||||
|
||||
// Crok Scourgebane
|
||||
public const uint IceboundArmor = 70714;
|
||||
public const uint ScourgeStrike = 71488;
|
||||
public const uint DeathStrike = 71489;
|
||||
|
||||
// Sister Svalna
|
||||
public const uint CaressOfDeath = 70078;
|
||||
public const uint ImpalingSpearKill = 70196;
|
||||
public const uint ReviveChampion = 70053;
|
||||
public const uint Undeath = 70089;
|
||||
public const uint ImpalingSpear = 71443;
|
||||
public const uint AetherShield = 71463;
|
||||
public const uint HurlSpear = 71466;
|
||||
|
||||
// Captain Arnath
|
||||
public const uint DominateMind = 14515;
|
||||
public const uint FlashHealNormal = 71595;
|
||||
public const uint PowerWordShieldNormal = 71548;
|
||||
public const uint SmiteNormal = 71546;
|
||||
public const uint FlashHealUndead = 71782;
|
||||
public const uint PowerWordShieldUndead = 71780;
|
||||
public const uint SmiteUndead = 71778;
|
||||
public static uint SpellFlashHeal(bool isUndead) { return isUndead ? InstanceSpells.FlashHealUndead : InstanceSpells.FlashHealNormal; }
|
||||
public static uint SpellPowerWordShield(bool isUndead) { return isUndead ? InstanceSpells.PowerWordShieldUndead : InstanceSpells.PowerWordShieldNormal; }
|
||||
public static uint SpellSmite(bool isUndead) { return isUndead ? InstanceSpells.SmiteUndead : InstanceSpells.SmiteNormal; }
|
||||
|
||||
// Captain Brandon
|
||||
public const uint CrusaderStrike = 71549;
|
||||
public const uint DivineShield = 71550;
|
||||
public const uint JudgementOfCommand = 71551;
|
||||
public const uint HammerOfBetrayal = 71784;
|
||||
|
||||
// Captain Grondel
|
||||
public const uint Charge = 71553;
|
||||
public const uint MortalStrike = 71552;
|
||||
public const uint SunderArmor = 71554;
|
||||
public const uint Conflagration = 71785;
|
||||
|
||||
// Captain Rupert
|
||||
public const uint FelIronBombNormal = 71592;
|
||||
public const uint MachineGunNormal = 71594;
|
||||
public const uint RocketLaunchNormal = 71590;
|
||||
public const uint FelIronBombUndead = 71787;
|
||||
public const uint MachineGunUndead = 71788;
|
||||
public const uint RocketLaunchUndead = 71786;
|
||||
public static uint SpellFelIronBomb(bool isUndead) { return isUndead ? InstanceSpells.FelIronBombUndead : InstanceSpells.FelIronBombNormal; }
|
||||
public static uint SpellMachineGun(bool isUndead) { return isUndead ? InstanceSpells.MachineGunUndead : InstanceSpells.MachineGunNormal; }
|
||||
public static uint SpellRocketLaunch(bool isUndead) { return isUndead ? InstanceSpells.RocketLaunchUndead : InstanceSpells.RocketLaunchNormal; }
|
||||
|
||||
// Invisible Stalker (Float; Uninteractible; Largeaoi)
|
||||
public const uint SoulMissile = 72585;
|
||||
|
||||
public const uint Berserk = 26662;
|
||||
public const uint Berserk2 = 47008;
|
||||
|
||||
// Deathbound Ward
|
||||
public const uint StoneForm = 70733;
|
||||
|
||||
// Residue Rendezvous
|
||||
public const uint OrangeBlightResidue = 72144;
|
||||
public const uint GreenBlightResidue = 72145;
|
||||
|
||||
// The Lich King
|
||||
public const uint ArthasTeleporterCeremony = 72915;
|
||||
public const uint FrostmourneTeleportVisual = 73078;
|
||||
|
||||
// Shadowmourne questline
|
||||
public const uint UnsatedCraving = 71168;
|
||||
public const uint ShadowsFate = 71169;
|
||||
}
|
||||
|
||||
struct EventTypes
|
||||
{
|
||||
// Highlord Tirion Fordring (At Light'S Hammer)
|
||||
// The Lich King (At Light'S Hammer)
|
||||
// Highlord Bolvar Fordragon (At Light'S Hammer)
|
||||
// High Overlord Saurfang (At Light'S Hammer)
|
||||
// Muradin Bronzebeard (At Light'S Hammer)
|
||||
public const uint TirionIntro2 = 1;
|
||||
public const uint TirionIntro3 = 2;
|
||||
public const uint TirionIntro4 = 3;
|
||||
public const uint TirionIntro5 = 4;
|
||||
public const uint LkIntro1 = 5;
|
||||
public const uint TirionIntro6 = 6;
|
||||
public const uint LkIntro2 = 7;
|
||||
public const uint LkIntro3 = 8;
|
||||
public const uint LkIntro4 = 9;
|
||||
public const uint BolvarIntro1 = 10;
|
||||
public const uint LkIntro5 = 11;
|
||||
public const uint SaurfangIntro1 = 12;
|
||||
public const uint TirionIntroH7 = 13;
|
||||
public const uint SaurfangIntro2 = 14;
|
||||
public const uint SaurfangIntro3 = 15;
|
||||
public const uint SaurfangIntro4 = 16;
|
||||
public const uint SaurfangRun = 17;
|
||||
public const uint MuradinIntro1 = 18;
|
||||
public const uint MuradinIntro2 = 19;
|
||||
public const uint MuradinIntro3 = 20;
|
||||
public const uint TirionIntroA7 = 21;
|
||||
public const uint MuradinIntro4 = 22;
|
||||
public const uint MuradinIntro5 = 23;
|
||||
public const uint MuradinRun = 24;
|
||||
|
||||
// Rotting Frost Giant
|
||||
public const uint DeathPlague = 25;
|
||||
public const uint Stomp = 26;
|
||||
public const uint ArcticBreath = 27;
|
||||
|
||||
// Frost Freeze Trap
|
||||
public const uint ActivateTrap = 28;
|
||||
|
||||
// Crok Scourgebane
|
||||
public const uint ScourgeStrike = 29;
|
||||
public const uint DeathStrike = 30;
|
||||
public const uint HealthCheck = 31;
|
||||
public const uint CrokIntro3 = 32;
|
||||
public const uint StartPathing = 33;
|
||||
|
||||
// Sister Svalna
|
||||
public const uint ArnathIntro2 = 34;
|
||||
public const uint SvalnaStart = 35;
|
||||
public const uint SvalnaResurrect = 36;
|
||||
public const uint SvalnaCombat = 37;
|
||||
public const uint ImpalingSpear = 38;
|
||||
public const uint AetherShield = 39;
|
||||
|
||||
// Captain Arnath
|
||||
public const uint ArnathFlashHeal = 40;
|
||||
public const uint ArnathPwShield = 41;
|
||||
public const uint ArnathSmite = 42;
|
||||
public const uint ArnathDominateMind = 43;
|
||||
|
||||
// Captain Brandon
|
||||
public const uint BrandonCrusaderStrike = 44;
|
||||
public const uint BrandonDivineShield = 45;
|
||||
public const uint BrandonJudgementOfCommand = 46;
|
||||
public const uint BrandonHammerOfBetrayal = 47;
|
||||
|
||||
// Captain Grondel
|
||||
public const uint GrondelChargeCheck = 48;
|
||||
public const uint GrondelMortalStrike = 49;
|
||||
public const uint GrondelSunderArmor = 50;
|
||||
public const uint GrondelConflagration = 51;
|
||||
|
||||
// Captain Rupert
|
||||
public const uint RupertFelIronBomb = 52;
|
||||
public const uint RupertMachineGun = 53;
|
||||
public const uint RupertRocketLaunch = 54;
|
||||
|
||||
// Invisible Stalker (Float; Uninteractible; Largeaoi)
|
||||
public const uint SoulMissile = 55;
|
||||
}
|
||||
|
||||
struct DataTypes
|
||||
{
|
||||
// Additional Data
|
||||
public const uint SaurfangEventNpc = 13;
|
||||
public const uint BonedAchievement = 14;
|
||||
public const uint OozeDanceAchievement = 15;
|
||||
public const uint PutricideTable = 16;
|
||||
public const uint NauseaAchievement = 17;
|
||||
public const uint OrbWhispererAchievement = 18;
|
||||
public const uint PrinceKelesethGuid = 19;
|
||||
public const uint PrinceTaldaramGuid = 20;
|
||||
public const uint PrinceValanarGuid = 21;
|
||||
public const uint BloodPrincesControl = 22;
|
||||
public const uint SindragosaFrostwyrms = 23;
|
||||
public const uint Spinestalker = 24;
|
||||
public const uint Rimefang = 25;
|
||||
public const uint ColdflameJets = 26;
|
||||
public const uint TeamInInstance = 27;
|
||||
public const uint BloodQuickeningState = 28;
|
||||
public const uint HeroicAttempts = 29;
|
||||
public const uint CrokScourgebane = 30;
|
||||
public const uint CaptainArnath = 31;
|
||||
public const uint CaptainBrandon = 32;
|
||||
public const uint CaptainGrondel = 33;
|
||||
public const uint CaptainRupert = 34;
|
||||
public const uint ValithriaTrigger = 35;
|
||||
public const uint ValithriaLichKing = 36;
|
||||
public const uint HighlordTirionFordring = 37;
|
||||
public const uint ArthasPlatform = 38;
|
||||
public const uint TerenasMenethil = 39;
|
||||
public const uint EnemyGunship = 40;
|
||||
public const uint UpperSpireTeleAct = 41;
|
||||
}
|
||||
|
||||
struct WorldStates
|
||||
{
|
||||
public const uint ShowTimer = 4903;
|
||||
public const uint ExecutionTime = 4904;
|
||||
public const uint ShowAttempts = 4940;
|
||||
public const uint AttemptsRemaining = 4941;
|
||||
public const uint AttemptsMax = 4942;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
// At Light'S Hammer
|
||||
public const uint HighlordTirionFordringLh = 37119;
|
||||
public const uint TheLichKingLh = 37181;
|
||||
public const uint HighlordBolvarFordragonLh = 37183;
|
||||
public const uint KorKronGeneral = 37189;
|
||||
public const uint AllianceCommander = 37190;
|
||||
public const uint Tortunok = 37992; // Druid Armor H
|
||||
public const uint AlanaMoonstrike = 37999; // Druid Armor A
|
||||
public const uint GerardoTheSuave = 37993; // Hunter Armor H
|
||||
public const uint TalanMoonstrike = 37998; // Hunter Armor A
|
||||
public const uint UvlusBanefire = 38284; // Mage Armor H
|
||||
public const uint MalfusGrimfrost = 38283; // Mage Armor A
|
||||
public const uint IkfirusTheVile = 37991; // Rogue Armor H
|
||||
public const uint Yili = 37997; // Rogue Armor A
|
||||
public const uint VolGuk = 38841; // Shaman Armor H
|
||||
public const uint Jedebia = 38840; // Shaman Armor A
|
||||
public const uint HaraggTheUnseen = 38181; // Warlock Armor H
|
||||
public const uint NibyTheAlmighty = 38182; // Warlock Armor N
|
||||
public const uint GarroshHellscream = 39372;
|
||||
public const uint KingVarianWrynn = 39371;
|
||||
public const uint DeathboundWard = 37007;
|
||||
public const uint LadyJainaProudmooreQuest = 38606;
|
||||
public const uint MuradinBronzaBeardQuest = 38607;
|
||||
public const uint UtherTheLightBringerQuest = 38608;
|
||||
public const uint LadySylvanasWindrunnerQuest = 38609;
|
||||
|
||||
// Weekly Quests
|
||||
public const uint InfiltratorMinchar = 38471;
|
||||
public const uint KorKronLieutenant = 38491;
|
||||
public const uint SkybreakerLieutenant = 38492;
|
||||
public const uint RottingFrostGiant10 = 38490;
|
||||
public const uint RottingFrostGiant25 = 38494;
|
||||
public const uint AlchemistAdrianna = 38501;
|
||||
public const uint AlrinTheAgile = 38551;
|
||||
public const uint InfiltratorMincharBq = 38558;
|
||||
public const uint MincharBeamStalker = 38557;
|
||||
public const uint ValithriaDreamwalkerQuest = 38589;
|
||||
|
||||
// Lord Marrowgar
|
||||
public const uint LordMarrowgar = 36612;
|
||||
public const uint Coldflame = 36672;
|
||||
public const uint BoneSpike = 36619;
|
||||
|
||||
// Lady Deathwhisper
|
||||
public const uint LadyDeathwhisper = 36855;
|
||||
public const uint CultFanatic = 37890;
|
||||
public const uint DeformedFanatic = 38135;
|
||||
public const uint ReanimatedFanatic = 38009;
|
||||
public const uint CultAdherent = 37949;
|
||||
public const uint EmpoweredAdherent = 38136;
|
||||
public const uint ReanimatedAdherent = 38010;
|
||||
public const uint VengefulShade = 38222;
|
||||
|
||||
// Icecrown Gunship Battle
|
||||
public const uint MartyrStalkerIGBSaurfang = 38569;
|
||||
public const uint AllianceGunshipCannon = 36838;
|
||||
public const uint HordeGunshipCannon = 36839;
|
||||
public const uint SkybreakerDeckhand = 36970;
|
||||
public const uint OrgrimsHammerCrew = 36971;
|
||||
public const uint IGBHighOverlordSaurfang = 36939;
|
||||
public const uint IGBMuradinBrozebeard = 36948;
|
||||
public const uint TheSkybreaker = 37540;
|
||||
public const uint OrgrimsHammer = 37215;
|
||||
public const uint GunshipHull = 37547;
|
||||
public const uint TeleportPortal = 37227;
|
||||
public const uint TeleportExit = 37488;
|
||||
public const uint SkybreakerSorcerer = 37116;
|
||||
public const uint SkybreakerRifleman = 36969;
|
||||
public const uint SkybreakerMortarSoldier = 36978;
|
||||
public const uint SkybreakerMarine = 36950;
|
||||
public const uint SkybreakerSergeant = 36961;
|
||||
public const uint KorKronBattleMage = 37117;
|
||||
public const uint KorKronAxeThrower = 36968;
|
||||
public const uint KorKronRocketeer = 36982;
|
||||
public const uint KorKronReaver = 36957;
|
||||
public const uint KorKronSergeant = 36960;
|
||||
public const uint ZafodBoombox = 37184;
|
||||
public const uint HighCaptainJustinBartlett = 37182;
|
||||
public const uint SkyReaverKormBlackscar = 37833;
|
||||
|
||||
// Deathbringer Saurfang
|
||||
public const uint DeathbringerSaurfang = 37813;
|
||||
public const uint BloodBeast = 38508;
|
||||
public const uint SeJainaProudmoore = 37188; // Se Means Saurfang Event
|
||||
public const uint SeMuradinBronzebeard = 37200;
|
||||
public const uint SeKingVarianWrynn = 37879;
|
||||
public const uint SeHighOverlordSaurfang = 37187;
|
||||
public const uint SeKorKronReaver = 37920;
|
||||
public const uint SeSkybreakerMarine = 37830;
|
||||
public const uint FrostFreezeTrap = 37744;
|
||||
|
||||
// Festergut
|
||||
public const uint Festergut = 36626;
|
||||
public const uint GasDummy = 36659;
|
||||
public const uint MalleableOozeStalker = 38556;
|
||||
|
||||
// Rotface
|
||||
public const uint Rotface = 36627;
|
||||
public const uint OozeSprayStalker = 37986;
|
||||
public const uint PuddleStalker = 37013;
|
||||
public const uint UnstableExplosionStalker = 38107;
|
||||
public const uint VileGasStalker = 38548;
|
||||
|
||||
// Professor Putricide
|
||||
public const uint ProfessorPutricide = 36678;
|
||||
public const uint AbominationWingMadScientistStalker = 37824;
|
||||
public const uint GrowingOozePuddle = 37690;
|
||||
public const uint GasCloud = 37562;
|
||||
public const uint VolatileOoze = 37697;
|
||||
public const uint ChokingGasBomb = 38159;
|
||||
public const uint TearGasTargetStalker = 38317;
|
||||
public const uint MutatedAbomination10 = 37672;
|
||||
public const uint MutatedAbomination25 = 38285;
|
||||
|
||||
// Blood Prince Council
|
||||
public const uint PrinceKeleseth = 37972;
|
||||
public const uint PrinceTaldaram = 37973;
|
||||
public const uint PrinceValanar = 37970;
|
||||
public const uint BloodOrbController = 38008;
|
||||
public const uint FloatingTrigger = 30298;
|
||||
public const uint DarkNucleus = 38369;
|
||||
public const uint BallOfFlame = 38332;
|
||||
public const uint BallOfInfernoFlame = 38451;
|
||||
public const uint KineticBombTarget = 38458;
|
||||
public const uint KineticBomb = 38454;
|
||||
public const uint ShockVortex = 38422;
|
||||
|
||||
// Blood-Queen Lana'Thel
|
||||
public const uint BloodQueenLanaThel = 37955;
|
||||
|
||||
// Frostwing Halls Gauntlet Event
|
||||
public const uint CrokScourgebane = 37129;
|
||||
public const uint CaptainArnath = 37122;
|
||||
public const uint CaptainBrandon = 37123;
|
||||
public const uint CaptainGrondel = 37124;
|
||||
public const uint CaptainRupert = 37125;
|
||||
public const uint CaptainArnathUndead = 37491;
|
||||
public const uint CaptainBrandonUndead = 37493;
|
||||
public const uint CaptainGrondelUndead = 37494;
|
||||
public const uint CaptainRupertUndead = 37495;
|
||||
public const uint YmirjarBattleMaiden = 37132;
|
||||
public const uint YmirjarDeathbringer = 38125;
|
||||
public const uint YmirjarFrostbinder = 37127;
|
||||
public const uint YmirjarHuntress = 37134;
|
||||
public const uint YmirjarWarlord = 37133;
|
||||
public const uint SisterSvalna = 37126;
|
||||
public const uint ImpalingSpear = 38248;
|
||||
|
||||
// Valithria Dreamwalker
|
||||
public const uint ValithriaDreamwalker = 36789;
|
||||
public const uint GreenDragonCombatTrigger = 38752;
|
||||
public const uint RisenArchmage = 37868;
|
||||
public const uint BlazingSkeleton = 36791;
|
||||
public const uint Suppresser = 37863;
|
||||
public const uint BlisteringZombie = 37934;
|
||||
public const uint GluttonousAbomination = 37886;
|
||||
public const uint ManaVoid = 38068;
|
||||
public const uint ColumnOfFrost = 37918;
|
||||
public const uint RotWorm = 37907;
|
||||
public const uint TheLichKingValithria = 16980;
|
||||
public const uint DreamPortalPreEffect = 38186;
|
||||
public const uint NightmarePortalPreEffect = 38429;
|
||||
public const uint DreamPortal = 37945;
|
||||
public const uint NightmarePortal = 38430;
|
||||
|
||||
// Sindragosa
|
||||
public const uint Sindragosa = 36853;
|
||||
public const uint Spinestalker = 37534;
|
||||
public const uint Rimefang = 37533;
|
||||
public const uint FrostwardenHandler = 37531;
|
||||
public const uint FrostwingWhelp = 37532;
|
||||
public const uint IcyBlast = 38223;
|
||||
public const uint FrostBomb = 37186;
|
||||
public const uint IceTomb = 36980;
|
||||
|
||||
// The Lich King
|
||||
public const uint TheLichKing = 36597;
|
||||
public const uint HighlordTirionFordringLk = 38995;
|
||||
public const uint TerenasMenethilFrostmourne = 36823;
|
||||
public const uint SpiritWarden = 36824;
|
||||
public const uint TerenasMenethilFrostmourneH = 39217;
|
||||
public const uint ShamblingHorror = 37698;
|
||||
public const uint DrudgeGhoul = 37695;
|
||||
public const uint IceSphere = 36633;
|
||||
public const uint RagingSpirit = 36701;
|
||||
public const uint Defile = 38757;
|
||||
public const uint ValkyrShadowguard = 36609;
|
||||
public const uint VileSpirit = 37799;
|
||||
public const uint WickedSpirit = 39190;
|
||||
public const uint StrangulateVehicle = 36598;
|
||||
public const uint WorldTrigger = 22515;
|
||||
public const uint WorldTriggerInfiniteAoi = 36171;
|
||||
public const uint SpiritBomb = 39189;
|
||||
public const uint FrostmourneTrigger = 38584;
|
||||
|
||||
// Generic
|
||||
public const uint InvisibleStalker = 30298;
|
||||
}
|
||||
|
||||
struct GameObjectIds
|
||||
{
|
||||
// ICC Teleporters
|
||||
public const uint TransporterLichKing = 202223;
|
||||
public const uint TransporterUpperSpire = 202235;
|
||||
public const uint TransporterLightsHammer = 202242;
|
||||
public const uint TransporterRampart = 202243;
|
||||
public const uint TransporterDeathBringer = 202244;
|
||||
public const uint TransporterOratory = 202245;
|
||||
public const uint TransporterSindragosa = 202246;
|
||||
|
||||
// Lower Spire Trash
|
||||
public const uint SpiritAlarm1 = 201814;
|
||||
public const uint SpiritAlarm2 = 201815;
|
||||
public const uint SpiritAlarm3 = 201816;
|
||||
public const uint SpiritAlarm4 = 201817;
|
||||
|
||||
// Lord Marrogar
|
||||
public const uint DoodadIcecrownIcewall02 = 201910;
|
||||
public const uint LordMarrowgarIcewall = 201911;
|
||||
public const uint LordMarrowgarSEntrance = 201857;
|
||||
|
||||
// Lady Deathwhisper
|
||||
public const uint OratoryOfTheDamnedEntrance = 201563;
|
||||
public const uint LadyDeathwhisperElevator = 202220;
|
||||
|
||||
// Icecrown Gunship Battle - Horde raid
|
||||
public const uint OrgrimsHammer_H = 201812;
|
||||
public const uint TheSkybreaker_H = 201811;
|
||||
public const uint GunshipArmory_H_10N = 202178;
|
||||
public const uint GunshipArmory_H_25N = 202180;
|
||||
public const uint GunshipArmory_H_10H = 202177;
|
||||
public const uint GunshipArmory_H_25H = 202179;
|
||||
|
||||
// Icecrown Gunship Battle - Alliance raid
|
||||
public const uint OrgrimsHammer_A = 201581;
|
||||
public const uint TheSkybreaker_A = 201580;
|
||||
public const uint GunshipArmory_A_10N = 201873;
|
||||
public const uint GunshipArmory_A_25N = 201874;
|
||||
public const uint GunshipArmory_A_10H = 201872;
|
||||
public const uint GunshipArmory_A_25H = 201875;
|
||||
|
||||
// Deathbringer Saurfang
|
||||
public const uint SaurfangSDoor = 201825;
|
||||
public const uint DeathbringerSCache10n = 202239;
|
||||
public const uint DeathbringerSCache25n = 202240;
|
||||
public const uint DeathbringerSCache10h = 202238;
|
||||
public const uint DeathbringerSCache25h = 202241;
|
||||
|
||||
// Professor Putricide
|
||||
public const uint OrangePlagueMonsterEntrance = 201371;
|
||||
public const uint GreenPlagueMonsterEntrance = 201370;
|
||||
public const uint ScientistAirlockDoorCollision = 201612;
|
||||
public const uint ScientistAirlockDoorOrange = 201613;
|
||||
public const uint ScientistAirlockDoorGreen = 201614;
|
||||
public const uint DoodadIcecrownOrangetubes02 = 201617;
|
||||
public const uint DoodadIcecrownGreentubes02 = 201618;
|
||||
public const uint ScientistEntrance = 201372;
|
||||
public const uint DrinkMe = 201584;
|
||||
public const uint PlagueSigil = 202182;
|
||||
|
||||
// Blood Prince Council
|
||||
public const uint CrimsonHallDoor = 201376;
|
||||
public const uint BloodElfCouncilDoor = 201378;
|
||||
public const uint BloodElfCouncilDoorRight = 201377;
|
||||
|
||||
// Blood-Queen Lana'Thel
|
||||
public const uint DoodadIcecrownBloodprinceDoor01 = 201746;
|
||||
public const uint DoodadIcecrownGrate01 = 201755;
|
||||
public const uint BloodwingSigil = 202183;
|
||||
|
||||
// Valithria Dreamwalker
|
||||
public const uint GreenDragonBossEntrance = 201375;
|
||||
public const uint GreenDragonBossExit = 201374;
|
||||
public const uint DoodadIcecrownRoostportcullis01 = 201380;
|
||||
public const uint DoodadIcecrownRoostportcullis02 = 201381;
|
||||
public const uint DoodadIcecrownRoostportcullis03 = 201382;
|
||||
public const uint DoodadIcecrownRoostportcullis04 = 201383;
|
||||
public const uint CacheOfTheDreamwalker10n = 201959;
|
||||
public const uint CacheOfTheDreamwalker25n = 202339;
|
||||
public const uint CacheOfTheDreamwalker10h = 202338;
|
||||
public const uint CacheOfTheDreamwalker25h = 202340;
|
||||
|
||||
// Sindragosa
|
||||
public const uint SindragosaEntranceDoor = 201373;
|
||||
public const uint SindragosaShortcutEntranceDoor = 201369;
|
||||
public const uint SindragosaShortcutExitDoor = 201379;
|
||||
public const uint IceWall = 202396;
|
||||
public const uint IceBlock = 201722;
|
||||
public const uint SigilOfTheFrostwing = 202181;
|
||||
|
||||
// The Lich King
|
||||
public const uint ArthasPlatform = 202161;
|
||||
public const uint ArthasPrecipice = 202078;
|
||||
public const uint DoodadIcecrownThronefrostywind01 = 202188;
|
||||
public const uint DoodadIcecrownThronefrostyedge01 = 202189;
|
||||
public const uint DoodadIceshardStanding02 = 202141;
|
||||
public const uint DoodadIceshardStanding01 = 202142;
|
||||
public const uint DoodadIceshardStanding03 = 202143;
|
||||
public const uint DoodadIceshardStanding04 = 202144;
|
||||
public const uint DoodadIcecrownSnowedgewarning01 = 202190;
|
||||
public const uint FrozenLavaman = 202436;
|
||||
public const uint LavamanPillarsChained = 202437;
|
||||
public const uint LavamanPillarsUnchained = 202438;
|
||||
}
|
||||
|
||||
struct AchievementCriteriaIds
|
||||
{
|
||||
// Lord Marrowgar
|
||||
public const uint Boned10n = 12775;
|
||||
public const uint Boned25n = 12962;
|
||||
public const uint Boned10h = 13393;
|
||||
public const uint Boned25h = 13394;
|
||||
|
||||
// Rotface
|
||||
public const uint DancesWithOozes10 = 12984;
|
||||
public const uint DancesWithOozes25 = 12966;
|
||||
public const uint DancesWithOozes10H = 12985;
|
||||
public const uint DancesWithOozes25H = 12983;
|
||||
|
||||
// Professor Putricide
|
||||
public const uint Nausea10 = 12987;
|
||||
public const uint Nausea25 = 12968;
|
||||
public const uint Nausea10H = 12988;
|
||||
public const uint Nausea25H = 12981;
|
||||
|
||||
// Blood Prince Council
|
||||
public const uint OrbWhisperer10 = 13033;
|
||||
public const uint OrbWhisperer25 = 12969;
|
||||
public const uint OrbWhisperer10H = 13034;
|
||||
public const uint OrbWhisperer25H = 13032;
|
||||
|
||||
// Blood-Queen Lana'Thel
|
||||
public const uint KillLanaThel10m = 13340;
|
||||
public const uint KillLanaThel25m = 13360;
|
||||
public const uint OnceBittenTwiceShy10 = 12780;
|
||||
public const uint OnceBittenTwiceShy25 = 13012;
|
||||
public const uint OnceBittenTwiceShy10V = 13011;
|
||||
public const uint OnceBittenTwiceShy25V = 13013;
|
||||
}
|
||||
|
||||
struct WeeklyQuestIds
|
||||
{
|
||||
public const uint Deprogramming10 = 24869;
|
||||
public const uint Deprogramming25 = 24875;
|
||||
public const uint SecuringTheRamparts10 = 24870;
|
||||
public const uint SecuringTheRamparts25 = 24877;
|
||||
public const uint ResidueRendezvous10 = 24873;
|
||||
public const uint ResidueRendezvous25 = 24878;
|
||||
public const uint BloodQuickening10 = 24874;
|
||||
public const uint BloodQuickening25 = 24879;
|
||||
public const uint RespiteForATornmentedSoul10 = 24872;
|
||||
public const uint RespiteForATornmentedSoul25 = 24880;
|
||||
}
|
||||
|
||||
struct Actions
|
||||
{
|
||||
// Icecrown Gunship Battle
|
||||
public const int EnemyGunshipTalk = -369390;
|
||||
public const int ExitShip = -369391;
|
||||
|
||||
// Festergut
|
||||
public const int FestergutCombat = -366260;
|
||||
public const int FestergutGas = -366261;
|
||||
public const int FestergutDeath = -366262;
|
||||
|
||||
// Rotface
|
||||
public const int RotfaceCombat = -366270;
|
||||
public const int RotfaceOoze = -366271;
|
||||
public const int RotfaceDeath = -366272;
|
||||
public const int ChangePhase = -366780;
|
||||
|
||||
// Blood-Queen Lana'Thel
|
||||
public const int KillMinchar = -379550;
|
||||
|
||||
// Frostwing Halls Gauntlet Event
|
||||
public const int VrykulDeath = 37129;
|
||||
|
||||
// Sindragosa
|
||||
public const int StartFrostwyrm = -368530;
|
||||
public const int TriggerAsphyxiation = -368531;
|
||||
|
||||
// The Lich King
|
||||
public const int RestoreLight = -72262;
|
||||
public const int FrostmourneIntro = -36823;
|
||||
|
||||
// Sister Svalna
|
||||
public const int KillCaptain = 1;
|
||||
public const int StartGauntlet = 2;
|
||||
public const int ResurrectCaptains = 3;
|
||||
public const int CaptainDies = 4;
|
||||
public const int ResetEvent = 5;
|
||||
}
|
||||
|
||||
struct TeleporterSpells
|
||||
{
|
||||
public const uint LIGHT_S_HAMMER_TELEPORT = 70781;
|
||||
public const uint ORATORY_OF_THE_DAMNED_TELEPORT = 70856;
|
||||
public const uint RAMPART_OF_SKULLS_TELEPORT = 70857;
|
||||
public const uint DEATHBRINGER_S_RISE_TELEPORT = 7085;
|
||||
public const uint UPPER_SPIRE_TELEPORT = 70859;
|
||||
public const uint FROZEN_THRONE_TELEPORT = 70860;
|
||||
public const uint SINDRAGOSA_S_LAIR_TELEPORT = 70861;
|
||||
}
|
||||
|
||||
struct AreaIds
|
||||
{
|
||||
public const uint IcecrownCitadel = 4812;
|
||||
public const uint TheFrozenThrone = 4859;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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.DataStorage;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
|
||||
namespace Scripts.Northrend.IcecrownCitadel
|
||||
{
|
||||
[Script]
|
||||
class icecrown_citadel_teleport : GameObjectScript
|
||||
{
|
||||
public icecrown_citadel_teleport() : base("icecrown_citadel_teleport") { }
|
||||
|
||||
public class icecrown_citadel_teleportAI : GameObjectAI
|
||||
{
|
||||
public icecrown_citadel_teleportAI(GameObject go) : base(go) { }
|
||||
|
||||
public override bool GossipSelect(Player player, uint menuId, uint gossipListId)
|
||||
{
|
||||
if (gossipListId >= TeleportSpells.Length)
|
||||
return false;
|
||||
|
||||
player.PlayerTalkClass.ClearMenus();
|
||||
player.CLOSE_GOSSIP_MENU();
|
||||
SpellInfo spell = Global.SpellMgr.GetSpellInfo(TeleportSpells[gossipListId]);
|
||||
if (spell == null)
|
||||
return false;
|
||||
|
||||
if (player.IsInCombat())
|
||||
{
|
||||
ObjectGuid castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, player.GetMapId(), spell.Id, player.GetMap().GenerateLowGuid(HighGuid.Cast));
|
||||
Spell.SendCastResult(player, spell, 0, castId, SpellCastResult.AffectingCombat);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override GameObjectAI GetAI(GameObject go)
|
||||
{
|
||||
return GetInstanceAI<icecrown_citadel_teleportAI>(go, "instance_icecrown_citadel");
|
||||
}
|
||||
|
||||
public const uint GOSSIP_SENDER_ICC_PORT = 631;
|
||||
|
||||
static uint[] TeleportSpells =
|
||||
{
|
||||
TeleporterSpells.LIGHT_S_HAMMER_TELEPORT, // 0
|
||||
TeleporterSpells.ORATORY_OF_THE_DAMNED_TELEPORT, // 1
|
||||
0, // 2
|
||||
TeleporterSpells.RAMPART_OF_SKULLS_TELEPORT, // 3
|
||||
TeleporterSpells.DEATHBRINGER_S_RISE_TELEPORT, // 4
|
||||
TeleporterSpells.UPPER_SPIRE_TELEPORT, // 5
|
||||
TeleporterSpells.SINDRAGOSA_S_LAIR_TELEPORT // 6
|
||||
};
|
||||
}
|
||||
|
||||
[Script]
|
||||
class at_frozen_throne_teleport : AreaTriggerScript
|
||||
{
|
||||
public at_frozen_throne_teleport() : base("at_frozen_throne_teleport") { }
|
||||
|
||||
public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger, bool entered)
|
||||
{
|
||||
if (player.IsInCombat())
|
||||
{
|
||||
SpellInfo spell = Global.SpellMgr.GetSpellInfo(TeleporterSpells.FROZEN_THRONE_TELEPORT);
|
||||
if (spell != null)
|
||||
{
|
||||
ObjectGuid castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, player.GetMapId(), spell.Id, player.GetMap().GenerateLowGuid(HighGuid.Cast));
|
||||
Spell.SendCastResult(player, spell, 0, castId, SpellCastResult.AffectingCombat);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
InstanceScript instance = player.GetInstanceScript();
|
||||
if (instance != null)
|
||||
if (instance.GetBossState(Bosses.ProfessorPutricide) == EncounterState.Done &&
|
||||
instance.GetBossState(Bosses.BloodQueenLanaThel) == EncounterState.Done &&
|
||||
instance.GetBossState(Bosses.Sindragosa) == EncounterState.Done &&
|
||||
instance.GetBossState(Bosses.TheLichKing) != EncounterState.InProgress)
|
||||
player.CastSpell(player, TeleporterSpells.FROZEN_THRONE_TELEPORT, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,645 @@
|
||||
/*
|
||||
* 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.Movement;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
namespace Scripts.Northrend.IcecrownCitadel
|
||||
{
|
||||
namespace Marrorgar
|
||||
{
|
||||
struct Texts
|
||||
{
|
||||
public const int SayEnterZone = 0;
|
||||
public const int SayAggro = 1;
|
||||
public const int SayBoneStorm = 2;
|
||||
public const int SayBonespike = 3;
|
||||
public const int SayKill = 4;
|
||||
public const int SayDeath = 5;
|
||||
public const int SayBerserk = 6;
|
||||
public const int EmoteBoneStorm = 7;
|
||||
}
|
||||
|
||||
struct Spells
|
||||
{
|
||||
// Lord Marrowgar
|
||||
public const uint BoneSlice = 69055;
|
||||
public const uint BoneStorm = 69076;
|
||||
public const uint BoneSpikeGraveyard = 69057;
|
||||
public const uint ColdflameNormal = 69140;
|
||||
public const uint ColdflameBoneStorm = 72705;
|
||||
|
||||
// Bone Spike
|
||||
public const uint Impaled = 69065;
|
||||
public const uint RideVehicle = 46598;
|
||||
|
||||
// Coldflame
|
||||
public const uint ColdflamePassive = 69145;
|
||||
public const uint ColdflameSummon = 69147;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public static uint[] BoneSpikeSummonId = { 69062, 72669, 72670 };
|
||||
|
||||
public const uint EventBoneSpikeGraveyard = 1;
|
||||
public const uint EventColdflame = 2;
|
||||
public const uint EventBoneStormBegin = 3;
|
||||
public const uint EventBoneStormMove = 4;
|
||||
public const uint EventBoneStormEnd = 5;
|
||||
public const uint EventEnableBoneSlice = 6;
|
||||
public const uint EventEnrage = 7;
|
||||
public const uint EventWarnBoneStorm = 8;
|
||||
|
||||
public const uint EventColdflameTrigger = 9;
|
||||
public const uint EventFailBoned = 10;
|
||||
|
||||
public const uint EventGroupSpecial = 1;
|
||||
|
||||
public const uint PointTargetBonestormPlayer = 36612631;
|
||||
public const uint PointTargetColdflame = 36672631;
|
||||
|
||||
public const int DataColdflameGuid = 0;
|
||||
|
||||
// Manual Marking For Targets Hit By Bone Slice As No Aura Exists For This Purpose
|
||||
// These Units Are The Tanks In This Encounter
|
||||
// And Should Be Immune To Bone Spike Graveyard
|
||||
public const int DataSpikeImmune = 1;
|
||||
//DataSpikeImmune1; = 2; // Reserved & Used
|
||||
//DataSpikeImmune2; = 3; // Reserved & Used
|
||||
|
||||
public const int ActionClearSpikeImmunities = 1;
|
||||
|
||||
public const uint MaxBoneSpikeImmune = 3;
|
||||
}
|
||||
|
||||
class BoneSpikeTargetSelector : ISelector
|
||||
{
|
||||
public BoneSpikeTargetSelector(UnitAI ai)
|
||||
{
|
||||
_ai = ai;
|
||||
}
|
||||
|
||||
public bool Check(Unit unit)
|
||||
{
|
||||
if (!unit.IsTypeId(TypeId.Player))
|
||||
return false;
|
||||
|
||||
if (unit.HasAura(Spells.Impaled))
|
||||
return false;
|
||||
|
||||
// Check if it is one of the tanks soaking Bone Slice
|
||||
for (int i = 0; i < Misc.MaxBoneSpikeImmune; ++i)
|
||||
if (unit.GetGUID() == _ai.GetGUID(Misc.DataSpikeImmune + i))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UnitAI _ai;
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class boss_lord_marrowgar : BossAI
|
||||
{
|
||||
public boss_lord_marrowgar(Creature creature) : base(creature, Bosses.LordMarrowgar)
|
||||
{
|
||||
_boneStormDuration = RaidMode<uint>(20000, 30000, 20000, 30000);
|
||||
_baseSpeed = creature.GetSpeedRate(UnitMoveType.Run);
|
||||
_coldflameLastPos.Relocate(creature);
|
||||
_introDone = false;
|
||||
_boneSlice = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
me.SetSpeedRate(UnitMoveType.Run, _baseSpeed);
|
||||
me.RemoveAurasDueToSpell(Spells.BoneStorm);
|
||||
me.RemoveAurasDueToSpell(InstanceSpells.Berserk);
|
||||
|
||||
_events.ScheduleEvent(Misc.EventEnableBoneSlice, 10000);
|
||||
_events.ScheduleEvent(Misc.EventBoneSpikeGraveyard, 15000, Misc.EventGroupSpecial);
|
||||
_events.ScheduleEvent(Misc.EventColdflame, 5000, Misc.EventGroupSpecial);
|
||||
_events.ScheduleEvent(Misc.EventWarnBoneStorm, RandomHelper.URand(45000, 50000));
|
||||
_events.ScheduleEvent(Misc.EventEnrage, 600000);
|
||||
_boneSlice = false;
|
||||
_boneSpikeImmune.Clear();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
Talk(Texts.SayAggro);
|
||||
|
||||
me.setActive(true);
|
||||
DoZoneInCombat();
|
||||
instance.SetBossState(Bosses.LordMarrowgar, EncounterState.InProgress);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(Texts.SayDeath);
|
||||
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
public override void JustReachedHome()
|
||||
{
|
||||
_JustReachedHome();
|
||||
instance.SetBossState(Bosses.LordMarrowgar, EncounterState.Fail);
|
||||
instance.SetData(DataTypes.BonedAchievement, 1); // reset
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (victim.IsTypeId(TypeId.Player))
|
||||
Talk(Texts.SayKill);
|
||||
}
|
||||
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
if (!_introDone && me.IsWithinDistInMap(who, 70.0f))
|
||||
{
|
||||
Talk(Texts.SayEnterZone);
|
||||
_introDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case Misc.EventBoneSpikeGraveyard:
|
||||
if (IsHeroic() || !me.HasAura(Spells.BoneStorm))
|
||||
DoCast(me, Spells.BoneSpikeGraveyard);
|
||||
_events.ScheduleEvent(Misc.EventBoneSpikeGraveyard, RandomHelper.URand(15000, 20000), Misc.EventGroupSpecial);
|
||||
break;
|
||||
case Misc.EventColdflame:
|
||||
_coldflameLastPos.Relocate(me);
|
||||
_coldflameTarget.Clear();
|
||||
if (!me.HasAura(Spells.BoneStorm))
|
||||
DoCastAOE(Spells.ColdflameNormal);
|
||||
else
|
||||
DoCast(me, Spells.ColdflameBoneStorm);
|
||||
_events.ScheduleEvent(Misc.EventColdflame, 5000, Misc.EventGroupSpecial);
|
||||
break;
|
||||
case Misc.EventWarnBoneStorm:
|
||||
_boneSlice = false;
|
||||
Talk(Texts.SayBoneStorm);
|
||||
me.FinishSpell(CurrentSpellTypes.Melee, false);
|
||||
DoCast(me, Spells.BoneStorm);
|
||||
_events.DelayEvents(3000, Misc.EventGroupSpecial);
|
||||
_events.ScheduleEvent(Misc.EventBoneStormBegin, 3050);
|
||||
_events.ScheduleEvent(Misc.EventWarnBoneStorm, RandomHelper.URand(90000, 95000));
|
||||
break;
|
||||
case Misc.EventBoneStormBegin:
|
||||
Aura pStorm = me.GetAura(Spells.BoneStorm);
|
||||
if (pStorm != null)
|
||||
pStorm.SetDuration((int)_boneStormDuration);
|
||||
me.SetSpeedRate(UnitMoveType.Run, _baseSpeed * 3.0f);
|
||||
Talk(Texts.SayBoneStorm);
|
||||
_events.ScheduleEvent(Misc.EventBoneStormEnd, _boneStormDuration + 1);
|
||||
goto case Misc.EventBoneStormMove;
|
||||
// no break here
|
||||
case Misc.EventBoneStormMove:
|
||||
{
|
||||
_events.ScheduleEvent(Misc.EventBoneStormMove, _boneStormDuration / 3);
|
||||
Unit unit = SelectTarget(SelectAggroTarget.Random, 0, new NonTankTargetSelector(me));
|
||||
if (!unit)
|
||||
unit = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
|
||||
if (unit)
|
||||
me.GetMotionMaster().MovePoint(Misc.PointTargetBonestormPlayer, unit);
|
||||
break;
|
||||
}
|
||||
case Misc.EventBoneStormEnd:
|
||||
if (me.GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Point)
|
||||
me.GetMotionMaster().MovementExpired();
|
||||
me.GetMotionMaster().MoveChase(me.GetVictim());
|
||||
me.SetSpeedRate(UnitMoveType.Run, _baseSpeed);
|
||||
_events.CancelEvent(Misc.EventBoneStormMove);
|
||||
_events.ScheduleEvent(Misc.EventEnableBoneSlice, 10000);
|
||||
if (!IsHeroic())
|
||||
_events.RescheduleEvent(Misc.EventBoneSpikeGraveyard, 15000, Misc.EventGroupSpecial);
|
||||
break;
|
||||
case Misc.EventEnableBoneSlice:
|
||||
_boneSlice = true;
|
||||
break;
|
||||
case Misc.EventEnrage:
|
||||
DoCast(me, Texts.SayBerserk, true);
|
||||
Talk(Texts.SayBerserk);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// We should not melee attack when storming
|
||||
if (me.HasAura(Spells.BoneStorm))
|
||||
return;
|
||||
|
||||
// 10 seconds since encounter start Bone Slice replaces melee attacks
|
||||
if (_boneSlice && !me.GetCurrentSpell(CurrentSpellTypes.Melee))
|
||||
DoCastVictim(Spells.BoneSlice);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Point || id != Misc.PointTargetBonestormPlayer)
|
||||
return;
|
||||
|
||||
// lock movement
|
||||
me.GetMotionMaster().MoveIdle();
|
||||
}
|
||||
|
||||
public Position GetLastColdflamePosition()
|
||||
{
|
||||
return _coldflameLastPos;
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGUID(int type = 0)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Misc.DataColdflameGuid:
|
||||
return _coldflameTarget;
|
||||
case Misc.DataSpikeImmune + 0:
|
||||
case Misc.DataSpikeImmune + 1:
|
||||
case Misc.DataSpikeImmune + 2:
|
||||
{
|
||||
int index = type - Misc.DataSpikeImmune;
|
||||
if (index < _boneSpikeImmune.Count)
|
||||
return _boneSpikeImmune[index];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
public override void SetGUID(ObjectGuid guid, int type = 0)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Misc.DataColdflameGuid:
|
||||
_coldflameTarget = guid;
|
||||
break;
|
||||
case Misc.DataSpikeImmune:
|
||||
_boneSpikeImmune.Add(guid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
if (action != Misc.ActionClearSpikeImmunities)
|
||||
return;
|
||||
|
||||
_boneSpikeImmune.Clear();
|
||||
}
|
||||
|
||||
Position _coldflameLastPos = new Position();
|
||||
List<ObjectGuid> _boneSpikeImmune = new List<ObjectGuid>();
|
||||
ObjectGuid _coldflameTarget;
|
||||
uint _boneStormDuration;
|
||||
float _baseSpeed;
|
||||
bool _introDone;
|
||||
bool _boneSlice;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_coldflame : ScriptedAI
|
||||
{
|
||||
public npc_coldflame(Creature creature) : base(creature) { }
|
||||
|
||||
public override void IsSummonedBy(Unit owner)
|
||||
{
|
||||
if (!owner.IsTypeId(TypeId.Player))
|
||||
return;
|
||||
|
||||
Position pos = new Position();
|
||||
var marrowgarAI = (boss_lord_marrowgar)owner.GetAI();
|
||||
if (marrowgarAI != null)
|
||||
pos.Relocate(marrowgarAI.GetLastColdflamePosition());
|
||||
else
|
||||
pos.Relocate(owner);
|
||||
|
||||
if (owner.HasAura(Spells.BoneStorm))
|
||||
{
|
||||
float ang = Position.NormalizeOrientation(pos.GetAngle(me));
|
||||
me.SetOrientation(ang);
|
||||
owner.GetNearPoint2D(out pos.posX, out pos.posY, 5.0f - owner.GetObjectSize(), ang);
|
||||
}
|
||||
else
|
||||
{
|
||||
Player target = Global.ObjAccessor.GetPlayer(owner, owner.GetAI().GetGUID(Misc.DataColdflameGuid));
|
||||
if (!target)
|
||||
{
|
||||
me.DespawnOrUnsummon();
|
||||
return;
|
||||
}
|
||||
|
||||
float ang = Position.NormalizeOrientation(pos.GetAngle(target));
|
||||
me.SetOrientation(ang);
|
||||
owner.GetNearPoint2D(out pos.posX, out pos.posY, 15.0f - owner.GetObjectSize(), ang);
|
||||
}
|
||||
|
||||
me.NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me.GetPositionZ(), me.GetOrientation());
|
||||
DoCast(Spells.ColdflameSummon);
|
||||
_events.ScheduleEvent(Misc.EventColdflameTrigger, 500);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
if (_events.ExecuteEvent() == Misc.EventColdflameTrigger)
|
||||
{
|
||||
Position newPos = me.GetNearPosition(5.0f, 0.0f);
|
||||
me.NearTeleportTo(newPos.GetPositionX(), newPos.GetPositionY(), me.GetPositionZ(), me.GetOrientation());
|
||||
DoCast(Spells.ColdflameSummon);
|
||||
_events.ScheduleEvent(Misc.EventColdflameTrigger, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_bone_spike : ScriptedAI
|
||||
{
|
||||
public npc_bone_spike(Creature creature)
|
||||
: base(creature)
|
||||
{
|
||||
_hasTrappedUnit = false;
|
||||
Contract.Assert(creature.GetVehicleKit());
|
||||
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
TempSummon summ = me.ToTempSummon();
|
||||
if (summ)
|
||||
{
|
||||
Unit trapped = summ.GetSummoner();
|
||||
if (trapped)
|
||||
trapped.RemoveAurasDueToSpell(Spells.Impaled);
|
||||
}
|
||||
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
me.DespawnOrUnsummon();
|
||||
victim.RemoveAurasDueToSpell(Spells.Impaled);
|
||||
}
|
||||
|
||||
public override void IsSummonedBy(Unit summoner)
|
||||
{
|
||||
DoCast(summoner, Spells.Impaled);
|
||||
summoner.CastSpell(me, Spells.RideVehicle, true);
|
||||
_events.ScheduleEvent(Misc.EventFailBoned, 8000);
|
||||
_hasTrappedUnit = true;
|
||||
}
|
||||
|
||||
public override void PassengerBoarded(Unit passenger, sbyte seat, bool apply)
|
||||
{
|
||||
if (!apply)
|
||||
return;
|
||||
|
||||
// @HACK - Change passenger offset to the one taken directly from sniffs
|
||||
// Remove this when proper calculations are implemented.
|
||||
// This fixes healing spiked people
|
||||
MoveSplineInit init = new MoveSplineInit(passenger);
|
||||
init.DisableTransportPathTransformations();
|
||||
init.MoveTo(-0.02206125f, -0.02132235f, 5.514783f, false);
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!_hasTrappedUnit)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (_events.ExecuteEvent() == Misc.EventFailBoned)
|
||||
{
|
||||
InstanceScript instance = me.GetInstanceScript();
|
||||
if (instance != null)
|
||||
instance.SetData(DataTypes.BonedAchievement, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool _hasTrappedUnit;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_marrowgar_coldflame : SpellScript
|
||||
{
|
||||
void SelectTarget(List<WorldObject> targets)
|
||||
{
|
||||
targets.Clear();
|
||||
// select any unit but not the tank (by owners threatlist)
|
||||
Unit target = GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 1, -GetCaster().GetObjectSize(), true, -(int)Spells.Impaled);
|
||||
if (!target)
|
||||
target = GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true); // or the tank if its solo
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
GetCaster().GetAI().SetGUID(target.GetGUID(), Misc.DataColdflameGuid);
|
||||
|
||||
targets.Add(target);
|
||||
}
|
||||
|
||||
void HandleScriptEffect(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
GetCaster().CastSpell(GetHitUnit(), (uint)GetEffectValue(), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(SelectTarget, 0, Targets.UnitDestAreaEnemy));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_marrowgar_coldflame_bonestorm : SpellScript
|
||||
{
|
||||
void HandleScriptEffect(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
GetCaster().CastSpell(GetHitUnit(), (uint)(GetEffectValue() + i), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_marrowgar_coldflame_damage : AuraScript
|
||||
{
|
||||
bool CanBeAppliedOn(Unit target)
|
||||
{
|
||||
if (target.HasAura(Spells.Impaled))
|
||||
return false;
|
||||
|
||||
if (target.GetExactDist2d(GetOwner()) > GetSpellInfo().GetEffect(target.GetMap().GetDifficultyID(), 0).CalcRadius())
|
||||
return false;
|
||||
|
||||
Aura aur = target.GetAura(GetId());
|
||||
if (aur != null)
|
||||
if (aur.GetOwner() != GetOwner())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckAreaTarget.Add(new CheckAreaTargetHandler(CanBeAppliedOn));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_marrowgar_bone_spike_graveyard : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(Misc.BoneSpikeSummonId);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Unit) && GetCaster().IsAIEnabled;
|
||||
}
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
return GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 0, new BoneSpikeTargetSelector(GetCaster().GetAI())) ? SpellCastResult.SpellCastOk : SpellCastResult.NoValidTargets;
|
||||
}
|
||||
|
||||
void HandleSpikes(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
Creature marrowgar = GetCaster().ToCreature();
|
||||
if (marrowgar)
|
||||
{
|
||||
CreatureAI marrowgarAI = marrowgar.GetAI();
|
||||
byte boneSpikeCount = (byte)(Convert.ToBoolean((int)GetCaster().GetMap().GetSpawnMode() & 1) ? 3 : 1);
|
||||
|
||||
List<Unit> targets = marrowgarAI.SelectTargetList(new BoneSpikeTargetSelector(marrowgarAI), boneSpikeCount, SelectAggroTarget.Random);
|
||||
if (targets.Empty())
|
||||
return;
|
||||
|
||||
uint i = 0;
|
||||
foreach (var target in targets)
|
||||
{
|
||||
target.CastSpell(target, Misc.BoneSpikeSummonId[i], true);
|
||||
i++;
|
||||
}
|
||||
|
||||
marrowgarAI.Talk(Texts.SayBonespike);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleSpikes, 1, SpellEffectName.ApplyAura));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_marrowgar_bone_storm : SpellScript
|
||||
{
|
||||
void RecalculateDamage()
|
||||
{
|
||||
SetHitDamage((int)(GetHitDamage() / Math.Max(Math.Sqrt(GetHitUnit().GetExactDist2d(GetCaster())), 1.0f)));
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnHit.Add(new HitHandler(RecalculateDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_marrowgar_bone_slice : SpellScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
_targetCount = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClearSpikeImmunities()
|
||||
{
|
||||
GetCaster().GetAI().DoAction(Misc.ActionClearSpikeImmunities);
|
||||
}
|
||||
|
||||
void CountTargets(List<WorldObject> targets)
|
||||
{
|
||||
_targetCount = (uint)Math.Min(targets.Count, GetSpellInfo().MaxAffectedTargets);
|
||||
}
|
||||
|
||||
void SplitDamage()
|
||||
{
|
||||
// Mark the unit as hit, even if the spell missed or was dodged/parried
|
||||
GetCaster().GetAI().SetGUID(GetHitUnit().GetGUID(), Misc.DataSpikeImmune);
|
||||
|
||||
if (_targetCount == 0)
|
||||
return; // This spell can miss all targets
|
||||
|
||||
SetHitDamage((int)(GetHitDamage() / _targetCount));
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
BeforeCast.Add(new CastHandler(ClearSpikeImmunities));
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(CountTargets, 0, Targets.UnitDestAreaEnemy));
|
||||
OnHit.Add(new HitHandler(SplitDamage));
|
||||
}
|
||||
|
||||
uint _targetCount;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 Game.Entities;
|
||||
|
||||
namespace Scripts.Northrend.IcecrownCitadel
|
||||
{
|
||||
public class Sindragosa
|
||||
{
|
||||
Position RimefangFlyPos = new Position(4413.309f, 2456.421f, 233.3795f, 2.890186f);
|
||||
Position RimefangLandPos = new Position(4413.309f, 2456.421f, 203.3848f, 2.890186f);
|
||||
Position SpinestalkerFlyPos = new Position(4418.895f, 2514.233f, 230.4864f, 3.396045f);
|
||||
Position SpinestalkerLandPos = new Position(4418.895f, 2514.233f, 203.3848f, 3.396045f);
|
||||
public static Position SindragosaSpawnPos = new Position(4818.700f, 2483.710f, 287.0650f, 3.089233f);
|
||||
Position SindragosaFlyPos = new Position(4475.190f, 2484.570f, 234.8510f, 3.141593f);
|
||||
Position SindragosaLandPos = new Position(4419.190f, 2484.570f, 203.3848f, 3.141593f);
|
||||
Position SindragosaAirPos = new Position(4475.990f, 2484.430f, 247.9340f, 3.141593f);
|
||||
Position SindragosaAirPosFar = new Position(4525.600f, 2485.150f, 245.0820f, 3.141593f);
|
||||
Position SindragosaFlyInPos = new Position(4419.190f, 2484.360f, 232.5150f, 3.141593f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 Game.Entities;
|
||||
|
||||
namespace Scripts.Northrend.IcecrownCitadel
|
||||
{
|
||||
public class TheLichKing
|
||||
{
|
||||
Position CenterPosition = new Position(503.6282f, -2124.655f, 840.8569f, 0.0f);
|
||||
Position TirionIntro = new Position(489.2970f, -2124.840f, 840.8569f, 0.0f);
|
||||
Position TirionCharge = new Position(482.9019f, -2124.479f, 840.8570f, 0.0f);
|
||||
Position[] LichKingIntro =
|
||||
{
|
||||
new Position(432.0851f, -2123.673f, 864.6582f, 0.0f),
|
||||
new Position(457.8351f, -2123.423f, 841.1582f, 0.0f),
|
||||
new Position(465.0730f, -2123.470f, 840.8569f, 0.0f),
|
||||
};
|
||||
Position OutroPosition1 = new Position(493.6286f, -2124.569f, 840.8569f, 0.0f);
|
||||
Position OutroFlying = new Position(508.9897f, -2124.561f, 845.3565f, 0.0f);
|
||||
public static Position TerenasSpawn = new Position(495.5542f, -2517.012f, 1050.000f, 4.6993f);
|
||||
Position TerenasSpawnHeroic = new Position(495.7080f, -2523.760f, 1050.000f, 0.0f);
|
||||
public static Position SpiritWardenSpawn = new Position(495.3406f, -2529.983f, 1050.000f, 1.5592f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 Game.Entities;
|
||||
|
||||
namespace Scripts.Northrend.IcecrownCitadel
|
||||
{
|
||||
public class ValithriaDreamwalker
|
||||
{
|
||||
public static Position ValithriaSpawnPos = new Position(4210.813f, 2484.443f, 364.9558f, 0.01745329f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Scripts.Northrend.Naxxramas
|
||||
{
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SayGreet = 1;
|
||||
public const uint SaySlay = 2;
|
||||
|
||||
public const uint EmoteLocust = 3;
|
||||
|
||||
public const uint EmoteFrenzy = 0;
|
||||
public const uint EmoteSpawn = 1;
|
||||
public const uint EmoteScarab = 2;
|
||||
}
|
||||
|
||||
struct EventIds
|
||||
{
|
||||
public const uint Impale = 1; // Cast Impale On A Random Target
|
||||
public const uint Locust = 2; // Begin Channeling Locust Swarm
|
||||
public const uint LocustEnds = 3; // Locust Swarm Dissipates
|
||||
public const uint SpawnGuard = 4; // 10-Man Only - Crypt Guard Has Delayed Spawn; Also Used For The Locust Swarm Crypt Guard In Both Modes
|
||||
public const uint Scarabs = 5; // Spawn Corpse Scarabs
|
||||
public const uint Berserk = 6; // Berserk
|
||||
}
|
||||
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Impale = 28783; // 25-Man: 56090
|
||||
public const uint LocustSwarm = 28785; // 25-Man: 54021
|
||||
public const uint SummonCorpseScarabsPlr = 29105; // This Spawns 5 Corpse Scarabs On Top Of Player
|
||||
public const uint SummonCorpseScarabsMob = 28864; // This Spawns 10 Corpse Scarabs On Top Of Dead Guards
|
||||
public const uint Berserk = 27680;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint achievTimedStartEvent = 9891;
|
||||
|
||||
public const uint PhaseNormal = 1;
|
||||
public const uint PhaseSwarm = 2;
|
||||
|
||||
public const uint SpawnGroupsInitial25M = 1;
|
||||
public const uint SpawnGroupsSingleSpawn = 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Scripts.Northrend.Nexus.EyeOfEternity
|
||||
{
|
||||
class BossMalygos
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* 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 Framework.GameMath;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Scripts.Northrend.Nexus.EyeOfEternity
|
||||
{
|
||||
struct EyeOfEternityConst
|
||||
{
|
||||
public const uint MaxEncounter = 1;
|
||||
public const uint EventFocusingIris = 20711;
|
||||
}
|
||||
|
||||
struct InstanceData
|
||||
{
|
||||
public const uint MalygosEvent = 1;
|
||||
public const uint VortexHandling = 2;
|
||||
public const uint PowerSparksHandling = 3;
|
||||
public const uint RespawnIris = 4;
|
||||
}
|
||||
|
||||
struct InstanceData64
|
||||
{
|
||||
public const uint Trigger = 0;
|
||||
public const uint Malygos = 1;
|
||||
public const uint Platform = 2;
|
||||
public const uint AlexstraszaBunnyGUID = 3;
|
||||
public const uint HeartOfMagicGUID = 4;
|
||||
public const uint FocusingIrisGUID = 5;
|
||||
public const uint GiftBoxBunnyGUID = 6;
|
||||
}
|
||||
|
||||
struct InstanceNpcs
|
||||
{
|
||||
public const uint Malygos = 28859;
|
||||
public const uint VortexTrigger = 30090;
|
||||
public const uint PortalTrigger = 30118;
|
||||
public const uint PowerSpark = 30084;
|
||||
public const uint HoverDiskMelee = 30234;
|
||||
public const uint HoverDiskCaster = 30248;
|
||||
public const uint ArcaneOverload = 30282;
|
||||
public const uint WyrmrestSkytalon = 30161;
|
||||
public const uint Alexstrasza = 32295;
|
||||
public const uint AlexstraszaBunny = 31253;
|
||||
public const uint AlexstraszasGift = 32448;
|
||||
public const uint SurgeOfPower = 30334;
|
||||
}
|
||||
|
||||
struct InstanceGameObjects
|
||||
{
|
||||
public const uint NexusRaidPlatform = 193070;
|
||||
public const uint ExitPortal = 193908;
|
||||
public const uint FocusingIris10 = 193958;
|
||||
public const uint FocusingIris25 = 193960;
|
||||
public const uint AlexstraszaSGift10 = 193905;
|
||||
public const uint AlexstraszaSGift25 = 193967;
|
||||
public const uint HeartOfMagic10 = 194158;
|
||||
public const uint HeartOfMagic25 = 194159;
|
||||
}
|
||||
|
||||
struct InstanceSpells
|
||||
{
|
||||
public const uint Vortex4 = 55853; // Damage | Used To Enter To The Vehicle
|
||||
public const uint Vortex5 = 56263; // Damage | Used To Enter To The Vehicle
|
||||
public const uint PortalOpened = 61236;
|
||||
public const uint RideRedDragonTriggered = 56072;
|
||||
public const uint IrisOpened = 61012; // Visual When Starting Encounter
|
||||
public const uint SummomRedDragonBuddy = 56070;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class instance_eye_of_eternity : InstanceMapScript
|
||||
{
|
||||
public instance_eye_of_eternity() : base("instance_eye_of_eternity", 616) { }
|
||||
|
||||
class instance_eye_of_eternity_InstanceMapScript : InstanceScript
|
||||
{
|
||||
public instance_eye_of_eternity_InstanceMapScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("EOE");
|
||||
SetBossNumber(EyeOfEternityConst.MaxEncounter);
|
||||
}
|
||||
|
||||
public override void OnPlayerEnter(Player player)
|
||||
{
|
||||
if (GetBossState(0) == EncounterState.Done)
|
||||
player.CastSpell(player, InstanceSpells.SummomRedDragonBuddy, true);
|
||||
}
|
||||
|
||||
public override bool SetBossState(uint type, EncounterState state)
|
||||
{
|
||||
if (!base.SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
if (type == InstanceData.MalygosEvent)
|
||||
{
|
||||
if (state == EncounterState.Fail)
|
||||
{
|
||||
foreach (var triggerGuid in portalTriggers)
|
||||
{
|
||||
Creature trigger = instance.GetCreature(triggerGuid);
|
||||
if (trigger)
|
||||
{
|
||||
// just in case
|
||||
trigger.RemoveAllAuras();
|
||||
trigger.GetAI().Reset();
|
||||
}
|
||||
}
|
||||
|
||||
SpawnGameObject(InstanceGameObjects.ExitPortal, exitPortalPosition);
|
||||
|
||||
GameObject platform = instance.GetGameObject(platformGUID);
|
||||
if (platform)
|
||||
platform.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.Destroyed);
|
||||
}
|
||||
else if (state == EncounterState.Done)
|
||||
SpawnGameObject(InstanceGameObjects.ExitPortal, exitPortalPosition);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @todo this should be handled in map, maybe add a summon function in map
|
||||
// There is no other way afaik...
|
||||
void SpawnGameObject(uint entry, Position pos)
|
||||
{
|
||||
GameObject go = new GameObject();
|
||||
if (go.Create(entry, instance, PhaseMasks.Normal, pos, Quaternion.WAxis, 255, GameObjectState.Ready))
|
||||
instance.AddToMap(go);
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case InstanceGameObjects.NexusRaidPlatform:
|
||||
platformGUID = go.GetGUID();
|
||||
break;
|
||||
case InstanceGameObjects.FocusingIris10:
|
||||
case InstanceGameObjects.FocusingIris25:
|
||||
irisGUID = go.GetGUID();
|
||||
focusingIrisPosition = go.GetPosition();
|
||||
break;
|
||||
case InstanceGameObjects.ExitPortal:
|
||||
exitPortalGUID = go.GetGUID();
|
||||
exitPortalPosition = go.GetPosition();
|
||||
break;
|
||||
case InstanceGameObjects.HeartOfMagic10:
|
||||
case InstanceGameObjects.HeartOfMagic25:
|
||||
heartOfMagicGUID = go.GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case InstanceNpcs.VortexTrigger:
|
||||
vortexTriggers.Add(creature.GetGUID());
|
||||
break;
|
||||
case InstanceNpcs.Malygos:
|
||||
malygosGUID = creature.GetGUID();
|
||||
break;
|
||||
case InstanceNpcs.PortalTrigger:
|
||||
portalTriggers.Add(creature.GetGUID());
|
||||
break;
|
||||
case InstanceNpcs.AlexstraszaBunny:
|
||||
alexstraszaBunnyGUID = creature.GetGUID();
|
||||
break;
|
||||
case InstanceNpcs.AlexstraszasGift:
|
||||
giftBoxBunnyGUID = creature.GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnUnitDeath(Unit unit)
|
||||
{
|
||||
if (!unit.IsTypeId(TypeId.Player))
|
||||
return;
|
||||
|
||||
// Player continues to be moving after death no matter if spline will be cleared along with all movements,
|
||||
// so on next world tick was all about delay if box will pop or not (when new movement will be registered)
|
||||
// since in EoE you never stop falling. However root at this precise* moment works,
|
||||
// it will get cleared on release. If by any chance some lag happen "Reload()" and "RepopMe()" works,
|
||||
// last test I made now gave me 50/0 of this bug so I can't do more about it.
|
||||
unit.SetControlled(true, UnitState.Root);
|
||||
}
|
||||
|
||||
public override void ProcessEvent(WorldObject obj, uint eventId)
|
||||
{
|
||||
if (eventId == EyeOfEternityConst.EventFocusingIris)
|
||||
{
|
||||
Creature alexstraszaBunny = instance.GetCreature(alexstraszaBunnyGUID);
|
||||
if (alexstraszaBunny)
|
||||
alexstraszaBunny.CastSpell(alexstraszaBunny, InstanceSpells.IrisOpened);
|
||||
|
||||
GameObject iris = instance.GetGameObject(irisGUID);
|
||||
if (iris)
|
||||
iris.SetFlag(GameObjectFields.Flags, GameObjectFlags.InUse);
|
||||
|
||||
Creature malygos = instance.GetCreature(malygosGUID);
|
||||
if (malygos)
|
||||
malygos.GetAI().DoAction(0); // ACTION_LAND_ENCOUNTER_START
|
||||
|
||||
GameObject exitPortal = instance.GetGameObject(exitPortalGUID);
|
||||
if (exitPortal)
|
||||
exitPortal.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
void VortexHandling()
|
||||
{
|
||||
Creature malygos = instance.GetCreature(malygosGUID);
|
||||
if (malygos)
|
||||
{
|
||||
var threatList = malygos.GetThreatManager().getThreatList();
|
||||
foreach (var guid in vortexTriggers)
|
||||
{
|
||||
if (threatList.Empty())
|
||||
return;
|
||||
|
||||
byte counter = 0;
|
||||
Creature trigger = instance.GetCreature(guid);
|
||||
if (trigger)
|
||||
{
|
||||
// each trigger have to cast the spell to 5 players.
|
||||
foreach (var refe in threatList)
|
||||
{
|
||||
if (counter >= 5)
|
||||
break;
|
||||
|
||||
Unit target = refe.getTarget();
|
||||
if (target)
|
||||
{
|
||||
Player player = target.ToPlayer();
|
||||
|
||||
if (!player || player.IsGameMaster() || player.HasAura(InstanceSpells.Vortex4))
|
||||
continue;
|
||||
|
||||
player.CastSpell(trigger, InstanceSpells.Vortex4, true);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PowerSparksHandling()
|
||||
{
|
||||
bool next = (lastPortalGUID == portalTriggers.Last() || !lastPortalGUID.IsEmpty() ? true : false);
|
||||
|
||||
foreach (var guid in portalTriggers)
|
||||
{
|
||||
if (next)
|
||||
{
|
||||
Creature trigger = instance.GetCreature(guid);
|
||||
if (trigger)
|
||||
{
|
||||
lastPortalGUID = trigger.GetGUID();
|
||||
trigger.CastSpell(trigger, InstanceSpells.PortalOpened, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (guid == lastPortalGUID)
|
||||
next = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetData(uint data, uint value)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case InstanceData.VortexHandling:
|
||||
VortexHandling();
|
||||
break;
|
||||
case InstanceData.PowerSparksHandling:
|
||||
PowerSparksHandling();
|
||||
break;
|
||||
case InstanceData.RespawnIris:
|
||||
SpawnGameObject(instance.GetDifficultyID() == Difficulty.Raid10N ? InstanceGameObjects.FocusingIris10 : InstanceGameObjects.FocusingIris25, focusingIrisPosition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case InstanceData64.Trigger:
|
||||
return vortexTriggers.First();
|
||||
case InstanceData64.Malygos:
|
||||
return malygosGUID;
|
||||
case InstanceData64.Platform:
|
||||
return platformGUID;
|
||||
case InstanceData64.AlexstraszaBunnyGUID:
|
||||
return alexstraszaBunnyGUID;
|
||||
case InstanceData64.HeartOfMagicGUID:
|
||||
return heartOfMagicGUID;
|
||||
case InstanceData64.FocusingIrisGUID:
|
||||
return irisGUID;
|
||||
case InstanceData64.GiftBoxBunnyGUID:
|
||||
return giftBoxBunnyGUID;
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
List<ObjectGuid> vortexTriggers = new List<ObjectGuid>();
|
||||
List<ObjectGuid> portalTriggers = new List<ObjectGuid>();
|
||||
ObjectGuid malygosGUID;
|
||||
ObjectGuid irisGUID;
|
||||
ObjectGuid lastPortalGUID;
|
||||
ObjectGuid platformGUID;
|
||||
ObjectGuid exitPortalGUID;
|
||||
ObjectGuid heartOfMagicGUID;
|
||||
ObjectGuid alexstraszaBunnyGUID;
|
||||
ObjectGuid giftBoxBunnyGUID;
|
||||
Position focusingIrisPosition;
|
||||
Position exitPortalPosition;
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_eye_of_eternity_InstanceMapScript(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* 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 System;
|
||||
|
||||
namespace Scripts.Northrend.Nexus.Nexus
|
||||
{
|
||||
struct AnomalusConst
|
||||
{
|
||||
//Spells
|
||||
public const uint SpellSpark = 47751;
|
||||
public const uint SpellSparkHeroic = 57062;
|
||||
public const uint SpellRiftShield = 47748;
|
||||
public const uint SpellChargeRift = 47747; // Works Wrong (Affect Players; Not Rifts)
|
||||
public const uint SpellCreateRift = 47743; // Don'T Work; Using Wa
|
||||
public const uint SpellArcaneAttraction = 57063; // No Idea; When It'S Used
|
||||
|
||||
public const uint SpellChaoticEnergyBurst = 47688;
|
||||
public const uint SpellChargedChaoticEnergyBurst = 47737;
|
||||
public const uint SpellArcaneform = 48019; // Chaotic Rift Visual
|
||||
|
||||
//Texts
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SayDeath = 1;
|
||||
public const uint SayRift = 2;
|
||||
public const uint SayShield = 3;
|
||||
public const uint SayRiftEmote = 4; // Needs To Be Added To Script
|
||||
public const uint SayShieldEmote = 5; // Needs To Be Added To Script
|
||||
|
||||
//Misc
|
||||
public const uint NpcCrazedManaWraith = 26746;
|
||||
public const uint NpcChaoticRift = 26918;
|
||||
|
||||
public const uint DataChaosTheory = 1;
|
||||
|
||||
public static Position[] RiftLocation =
|
||||
{
|
||||
new Position(652.64f, -273.70f, -8.75f, 0.0f),
|
||||
new Position(634.45f, -265.94f, -8.44f, 0.0f),
|
||||
new Position(620.73f, -281.17f, -9.02f, 0.0f),
|
||||
new Position(626.10f, -304.67f, -9.44f, 0.0f),
|
||||
new Position(639.87f, -314.11f, -9.49f, 0.0f),
|
||||
new Position(651.72f, -297.44f, -9.37f, 0.0f)
|
||||
};
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_anomalus : ScriptedAI
|
||||
{
|
||||
public boss_anomalus(Creature creature) : base(creature)
|
||||
{
|
||||
instance = me.GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, AnomalusConst.SpellSpark);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(5));
|
||||
});
|
||||
|
||||
Phase = 0;
|
||||
uiChaoticRiftGUID.Clear();
|
||||
chaosTheory = true;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
instance.SetBossState(DataTypes.Anomalus, EncounterState.NotStarted);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
Talk(AnomalusConst.SayAggro);
|
||||
|
||||
instance.SetBossState(DataTypes.Anomalus, EncounterState.InProgress);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(AnomalusConst.SayDeath);
|
||||
|
||||
instance.SetBossState(DataTypes.Anomalus, EncounterState.Done);
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
if (type == AnomalusConst.DataChaosTheory)
|
||||
return chaosTheory ? 1 : 0u;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void SummonedCreatureDies(Creature summoned, Unit who)
|
||||
{
|
||||
if (summoned.GetEntry() == AnomalusConst.NpcChaoticRift)
|
||||
chaosTheory = false;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me.GetDistance(me.GetHomePosition()) > 60.0f)
|
||||
{
|
||||
// Not blizzlike, hack to avoid an exploit
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (me.HasAura(AnomalusConst.SpellRiftShield))
|
||||
{
|
||||
if (!uiChaoticRiftGUID.IsEmpty())
|
||||
{
|
||||
Creature Rift = ObjectAccessor.GetCreature(me, uiChaoticRiftGUID);
|
||||
if (Rift && Rift.IsDead())
|
||||
{
|
||||
me.RemoveAurasDueToSpell(AnomalusConst.SpellRiftShield);
|
||||
uiChaoticRiftGUID.Clear();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
uiChaoticRiftGUID.Clear();
|
||||
|
||||
if ((Phase == 0) && HealthBelowPct(50))
|
||||
{
|
||||
Phase = 1;
|
||||
Talk(AnomalusConst.SayShield);
|
||||
DoCast(me, AnomalusConst.SpellRiftShield);
|
||||
Creature Rift = me.SummonCreature(AnomalusConst.NpcChaoticRift, AnomalusConst.RiftLocation[RandomHelper.IRand(0, 5)], TempSummonType.TimedDespawnOOC, 1000);
|
||||
if (Rift)
|
||||
{
|
||||
//DoCast(Rift, SPELL_CHARGE_RIFT);
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
Rift.GetAI().AttackStart(target);
|
||||
uiChaoticRiftGUID = Rift.GetGUID();
|
||||
Talk(AnomalusConst.SayRift);
|
||||
}
|
||||
}
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
byte Phase;
|
||||
ObjectGuid uiChaoticRiftGUID;
|
||||
bool chaosTheory;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_chaotic_rift : ScriptedAI
|
||||
{
|
||||
public npc_chaotic_rift(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = me.GetInstanceScript();
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiChaoticEnergyBurstTimer = 1000;
|
||||
uiSummonCrazedManaWraithTimer = 5000;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
me.SetDisplayId(me.GetCreatureTemplate().ModelId2);
|
||||
DoCast(me, AnomalusConst.SpellArcaneform, false);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiChaoticEnergyBurstTimer <= diff)
|
||||
{
|
||||
Creature Anomalus = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Anomalus));
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
{
|
||||
if (Anomalus && Anomalus.HasAura(AnomalusConst.SpellRiftShield))
|
||||
DoCast(target, AnomalusConst.SpellChargedChaoticEnergyBurst);
|
||||
else
|
||||
DoCast(target, AnomalusConst.SpellChaoticEnergyBurst);
|
||||
}
|
||||
uiChaoticEnergyBurstTimer = 1000;
|
||||
}
|
||||
else
|
||||
uiChaoticEnergyBurstTimer -= diff;
|
||||
|
||||
if (uiSummonCrazedManaWraithTimer <= diff)
|
||||
{
|
||||
Creature Wraith = me.SummonCreature(AnomalusConst.NpcCrazedManaWraith, me.GetPositionX() + 1, me.GetPositionY() + 1, me.GetPositionZ(), 0, TempSummonType.TimedDespawnOOC, 1000);
|
||||
if (Wraith)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
Wraith.GetAI().AttackStart(target);
|
||||
}
|
||||
Creature Anomalus = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Anomalus));
|
||||
if (Anomalus && Anomalus.HasAura(AnomalusConst.SpellRiftShield))
|
||||
uiSummonCrazedManaWraithTimer = 5000;
|
||||
else
|
||||
uiSummonCrazedManaWraithTimer = 10000;
|
||||
}
|
||||
else
|
||||
uiSummonCrazedManaWraithTimer -= diff;
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
uint uiChaoticEnergyBurstTimer;
|
||||
uint uiSummonCrazedManaWraithTimer;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_chaos_theory : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_chaos_theory() : base("achievement_chaos_theory")
|
||||
{
|
||||
}
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Creature Anomalus = target.ToCreature();
|
||||
if (Anomalus)
|
||||
if (Anomalus.GetAI().GetData(AnomalusConst.DataChaosTheory) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace Scripts.Northrend.Nexus.Nexus
|
||||
{
|
||||
struct KeristraszaConst
|
||||
{
|
||||
//Spells
|
||||
public const uint SpellFrozenPrison = 47854;
|
||||
public const uint SpellTailSweep = 50155;
|
||||
public const uint SpellCrystalChains = 50997;
|
||||
public const uint SpellEnrage = 8599;
|
||||
public const uint SpellCrystalFireBreath = 48096;
|
||||
public const uint SpellCrystalize = 48179;
|
||||
public const uint SpellIntenseCold = 48094;
|
||||
public const uint SpellIntenseColdTriggered = 48095;
|
||||
|
||||
//Yells
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SaySlay = 1;
|
||||
public const uint SayEnrage = 2;
|
||||
public const uint SayDeath = 3;
|
||||
public const uint SayCrystalNova = 4;
|
||||
public const uint SayFrenzy = 5;
|
||||
|
||||
//Misc
|
||||
public const uint DataIntenseCold = 1;
|
||||
public const uint DataContainmentSpheres = 3;
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class boss_keristrasza : BossAI
|
||||
{
|
||||
public boss_keristrasza(Creature creature) : base(creature, DataTypes.Keristrasza)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_enrage = false;
|
||||
|
||||
//Crystal FireBreath
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(14), task =>
|
||||
{
|
||||
DoCastVictim(KeristraszaConst.SpellCrystalFireBreath);
|
||||
task.Repeat(TimeSpan.FromSeconds(14));
|
||||
});
|
||||
|
||||
//CrystalChainsCrystalize
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(DungeonMode<uint>(30, 11)), task =>
|
||||
{
|
||||
Talk(KeristraszaConst.SayCrystalNova);
|
||||
if (IsHeroic())
|
||||
DoCast(me, KeristraszaConst.SpellCrystalize);
|
||||
else
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
|
||||
if (target)
|
||||
DoCast(target, KeristraszaConst.SpellCrystalChains);
|
||||
}
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(DungeonMode<uint>(30, 11)));
|
||||
});
|
||||
|
||||
//TailSweep
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
DoCast(me, KeristraszaConst.SpellTailSweep);
|
||||
task.Repeat(TimeSpan.FromSeconds(5));
|
||||
});
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
_intenseColdList.Clear();
|
||||
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.Stunned);
|
||||
|
||||
RemovePrison(CheckContainmentSpheres());
|
||||
_Reset();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
Talk(KeristraszaConst.SayAggro);
|
||||
DoCastAOE(KeristraszaConst.SpellIntenseCold);
|
||||
_EnterCombat();
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(KeristraszaConst.SayDeath);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.IsTypeId(TypeId.Player))
|
||||
Talk(KeristraszaConst.SaySlay);
|
||||
}
|
||||
|
||||
public bool CheckContainmentSpheres(bool removePrison = false)
|
||||
{
|
||||
for (uint i = DataTypes.AnomalusContainmetSphere; i < (DataTypes.AnomalusContainmetSphere + KeristraszaConst.DataContainmentSpheres); ++i)
|
||||
{
|
||||
GameObject containmentSpheres = ObjectAccessor.GetGameObject(me, instance.GetGuidData(i));
|
||||
if (!containmentSpheres || containmentSpheres.GetGoState() != GameObjectState.Active)
|
||||
return false;
|
||||
}
|
||||
if (removePrison)
|
||||
RemovePrison(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemovePrison(bool remove)
|
||||
{
|
||||
if (remove)
|
||||
{
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
if (me.HasAura(KeristraszaConst.SpellFrozenPrison))
|
||||
me.RemoveAurasDueToSpell(KeristraszaConst.SpellFrozenPrison);
|
||||
}
|
||||
else
|
||||
{
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
DoCast(me, KeristraszaConst.SpellFrozenPrison, false);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetGUID(ObjectGuid guid, int id = 0)
|
||||
{
|
||||
if (id == KeristraszaConst.DataIntenseCold)
|
||||
_intenseColdList.Add(guid);
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (!_enrage && me.HealthBelowPctDamaged(25, damage))
|
||||
{
|
||||
Talk(KeristraszaConst.SayEnrage);
|
||||
Talk(KeristraszaConst.SayFrenzy);
|
||||
DoCast(me, KeristraszaConst.SpellEnrage);
|
||||
_enrage = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool _enrage;
|
||||
|
||||
public List<ObjectGuid> _intenseColdList = new List<ObjectGuid>();
|
||||
}
|
||||
|
||||
[Script]
|
||||
class containment_sphere : GameObjectScript
|
||||
{
|
||||
public containment_sphere() : base("containment_sphere") { }
|
||||
|
||||
public override bool OnGossipHello(Player player, GameObject go)
|
||||
{
|
||||
InstanceScript instance = go.GetInstanceScript();
|
||||
|
||||
Creature pKeristrasza = ObjectAccessor.GetCreature(go, instance.GetGuidData(DataTypes.Keristrasza));
|
||||
if (pKeristrasza && pKeristrasza.IsAlive())
|
||||
{
|
||||
// maybe these are hacks :(
|
||||
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
go.SetGoState(GameObjectState.Active);
|
||||
|
||||
((boss_keristrasza)pKeristrasza.GetAI()).CheckContainmentSpheres(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_intense_cold : AuraScript
|
||||
{
|
||||
void HandlePeriodicTick(AuraEffect aurEff)
|
||||
{
|
||||
if (aurEff.GetBase().GetStackAmount() < 2)
|
||||
return;
|
||||
Unit caster = GetCaster();
|
||||
/// @todo the caster should be boss but not the player
|
||||
if (!caster || caster.GetAI() == null)
|
||||
return;
|
||||
|
||||
caster.GetAI().SetGUID(GetTarget().GetGUID(), (int)KeristraszaConst.DataIntenseCold);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodicTick, 1, AuraType.PeriodicDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_intense_cold : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_intense_cold() : base("achievement_intense_cold") { }
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
var _intenseColdList = ((boss_keristrasza)target.ToCreature().GetAI())._intenseColdList;
|
||||
if (!_intenseColdList.Empty())
|
||||
{
|
||||
foreach (var guid in _intenseColdList)
|
||||
if (player.GetGUID() == guid)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace Scripts.Northrend.Nexus.Nexus
|
||||
{
|
||||
struct MagusTelestraConst
|
||||
{
|
||||
//Spells
|
||||
public const uint SpellIceNova = 47772;
|
||||
public const uint SpellIceNovaH = 56935;
|
||||
public const uint SpellFirebomb = 47773;
|
||||
public const uint SpellFirebombH = 56934;
|
||||
public const uint SpellGravityWell = 47756;
|
||||
public const uint SpellTelestraBack = 47714;
|
||||
public const uint SpellFireMagusVisual = 47705;
|
||||
public const uint SpellFrostMagusVisual = 47706;
|
||||
public const uint SpellArcaneMagusVisual = 47704;
|
||||
public const uint SpellWearChristmasHat = 61400;
|
||||
|
||||
//Npcs
|
||||
public const uint NpcFireMagus = 26928;
|
||||
public const uint NpcFrostMagus = 26930;
|
||||
public const uint NpcArcaneMagus = 26929;
|
||||
|
||||
//Texts
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SayKill = 1;
|
||||
public const uint SayDeath = 2;
|
||||
public const uint SayMerge = 3;
|
||||
public const uint SaySplit = 4;
|
||||
|
||||
//Misc
|
||||
public const uint DataSplitPersonality = 1;
|
||||
public const ushort GameEventWinterVeil = 2;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_magus_telestra : ScriptedAI
|
||||
{
|
||||
public boss_magus_telestra(Creature creature) : base(creature)
|
||||
{
|
||||
instance = creature.GetInstanceScript();
|
||||
bFireMagusDead = false;
|
||||
bFrostMagusDead = false;
|
||||
bArcaneMagusDead = false;
|
||||
uiIsWaitingToAppearTimer = 0;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
Phase = 0;
|
||||
|
||||
uiIceNovaTimer = 7 * Time.InMilliseconds;
|
||||
uiFireBombTimer = 0;
|
||||
uiGravityWellTimer = 15 * Time.InMilliseconds;
|
||||
uiCooldown = 0;
|
||||
|
||||
for (byte n = 0; n < 3; ++n)
|
||||
time[n] = 0;
|
||||
|
||||
splitPersonality = 0;
|
||||
bIsWaitingToAppear = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
|
||||
instance.SetBossState(DataTypes.MagusTelestra, EncounterState.NotStarted);
|
||||
|
||||
if (IsHeroic() && Global.GameEventMgr.IsActiveEvent(MagusTelestraConst.GameEventWinterVeil) && !me.HasAura(MagusTelestraConst.SpellWearChristmasHat))
|
||||
me.AddAura(MagusTelestraConst.SpellWearChristmasHat, me);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
Talk(MagusTelestraConst.SayAggro);
|
||||
|
||||
instance.SetBossState(DataTypes.MagusTelestra, EncounterState.InProgress);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(MagusTelestraConst.SayDeath);
|
||||
|
||||
instance.SetBossState(DataTypes.MagusTelestra, EncounterState.Done);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.IsTypeId(TypeId.Player))
|
||||
Talk(MagusTelestraConst.SayKill);
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
if (type == MagusTelestraConst.DataSplitPersonality)
|
||||
return splitPersonality;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (bIsWaitingToAppear)
|
||||
{
|
||||
me.StopMoving();
|
||||
me.AttackStop();
|
||||
if (uiIsWaitingToAppearTimer <= diff)
|
||||
{
|
||||
me.CastSpell(me, 47714, true);
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
bIsWaitingToAppear = false;
|
||||
InVanish = false;
|
||||
me.SendAIReaction(AiReaction.Hostile);
|
||||
}
|
||||
else
|
||||
uiIsWaitingToAppearTimer -= diff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Phase == 1) || (Phase == 3))
|
||||
{
|
||||
if (bFireMagusDead && bFrostMagusDead && bArcaneMagusDead)
|
||||
{
|
||||
for (byte n = 0; n < 3; ++n)
|
||||
time[n] = 0;
|
||||
|
||||
me.GetMotionMaster().Clear();
|
||||
DoCast(me, MagusTelestraConst.SpellTelestraBack);
|
||||
if (Phase == 1)
|
||||
Phase = 2;
|
||||
if (Phase == 3)
|
||||
Phase = 4;
|
||||
bIsWaitingToAppear = true;
|
||||
uiIsWaitingToAppearTimer = 4 * Time.InMilliseconds;
|
||||
Talk(MagusTelestraConst.SayMerge);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Phase == 0) && HealthBelowPct(50))
|
||||
{
|
||||
InVanish = true;
|
||||
Phase = 1;
|
||||
me.CastStop();
|
||||
me.RemoveAllAuras();
|
||||
me.CastSpell(me, 47710, false);
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
bFireMagusDead = false;
|
||||
bFrostMagusDead = false;
|
||||
bArcaneMagusDead = false;
|
||||
Talk(MagusTelestraConst.SaySplit);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsHeroic() && (Phase == 2) && HealthBelowPct(10))
|
||||
{
|
||||
InVanish = true;
|
||||
Phase = 3;
|
||||
me.CastStop();
|
||||
me.RemoveAllAuras();
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
bFireMagusDead = false;
|
||||
bFrostMagusDead = false;
|
||||
bArcaneMagusDead = false;
|
||||
Talk(MagusTelestraConst.SaySplit);
|
||||
return;
|
||||
}
|
||||
|
||||
if (uiCooldown != 0)
|
||||
{
|
||||
if (uiCooldown <= diff)
|
||||
uiCooldown = 0;
|
||||
else
|
||||
{
|
||||
uiCooldown -= diff;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (uiIceNovaTimer <= diff)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, MagusTelestraConst.SpellIceNova, false);
|
||||
uiCooldown = 1500;
|
||||
}
|
||||
uiIceNovaTimer = 15 * Time.InMilliseconds;
|
||||
}
|
||||
else uiIceNovaTimer -= diff;
|
||||
|
||||
if (uiGravityWellTimer <= diff)
|
||||
{
|
||||
Unit target = me.GetVictim();
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, MagusTelestraConst.SpellGravityWell);
|
||||
uiCooldown = 6 * Time.InMilliseconds;
|
||||
}
|
||||
uiGravityWellTimer = 15 * Time.InMilliseconds;
|
||||
}
|
||||
else uiGravityWellTimer -= diff;
|
||||
|
||||
if (uiFireBombTimer <= diff)
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, MagusTelestraConst.SpellFirebomb, false);
|
||||
uiCooldown = 2 * Time.InMilliseconds;
|
||||
}
|
||||
uiFireBombTimer = 2 * Time.InMilliseconds;
|
||||
}
|
||||
else uiFireBombTimer -= diff;
|
||||
|
||||
if (!InVanish)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void SummonedCreatureDies(Creature summon, Unit killer)
|
||||
{
|
||||
if (summon.IsAlive())
|
||||
return;
|
||||
|
||||
switch (summon.GetEntry())
|
||||
{
|
||||
case MagusTelestraConst.NpcFireMagus:
|
||||
bFireMagusDead = true;
|
||||
break;
|
||||
case MagusTelestraConst.NpcFrostMagus:
|
||||
bFrostMagusDead = true;
|
||||
break;
|
||||
case MagusTelestraConst.NpcArcaneMagus:
|
||||
bArcaneMagusDead = true;
|
||||
break;
|
||||
}
|
||||
|
||||
byte i = 0;
|
||||
while (time[i] != 0)
|
||||
++i;
|
||||
|
||||
time[i] = Global.WorldMgr.GetGameTime();
|
||||
if (i == 2 && (time[2] - time[1] < 5) && (time[1] - time[0] < 5))
|
||||
++splitPersonality;
|
||||
}
|
||||
|
||||
InstanceScript instance;
|
||||
|
||||
bool bFireMagusDead;
|
||||
bool bFrostMagusDead;
|
||||
bool bArcaneMagusDead;
|
||||
bool bIsWaitingToAppear;
|
||||
bool InVanish;
|
||||
|
||||
uint uiIsWaitingToAppearTimer;
|
||||
uint uiIceNovaTimer;
|
||||
uint uiFireBombTimer;
|
||||
uint uiGravityWellTimer;
|
||||
uint uiCooldown;
|
||||
|
||||
byte Phase;
|
||||
byte splitPersonality;
|
||||
long[] time = new long[3];
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_split_personality : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_split_personality() : base("achievement_split_personality") { }
|
||||
|
||||
public override bool OnCheck(Player player, Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Creature Telestra = target.ToCreature();
|
||||
if (Telestra)
|
||||
if (Telestra.GetAI().GetData(MagusTelestraConst.DataSplitPersonality) == 2)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.Northrend.Nexus.Nexus
|
||||
{
|
||||
struct NexusCommandersConst
|
||||
{
|
||||
//Spells
|
||||
public const uint SpellBattleShout = 31403;
|
||||
public const uint SpellCharge = 60067;
|
||||
public const uint SpellFrighteningShout = 19134;
|
||||
public const uint SpellWhirlwind = 38618;
|
||||
public const uint SpellFrozenPrison = 47543;
|
||||
|
||||
//Texts
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SayKill = 1;
|
||||
public const uint SayDeath = 2;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_nexus_commanders : BossAI
|
||||
{
|
||||
boss_nexus_commanders(Creature creature) : base(creature, DataTypes.Commander) { }
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(NexusCommandersConst.SayAggro);
|
||||
me.RemoveAurasDueToSpell(NexusCommandersConst.SpellFrozenPrison);
|
||||
DoCast(me, NexusCommandersConst.SpellBattleShout);
|
||||
|
||||
//Charge
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(4), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
|
||||
if (target)
|
||||
DoCast(target, NexusCommandersConst.SpellCharge);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(11), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
|
||||
//Whirlwind
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
DoCast(me, NexusCommandersConst.SpellWhirlwind);
|
||||
task.Repeat(TimeSpan.FromSeconds(19.5), TimeSpan.FromSeconds(25));
|
||||
});
|
||||
|
||||
//Frightening Shout
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCastAOE(NexusCommandersConst.SpellFrighteningShout);
|
||||
task.Repeat(TimeSpan.FromSeconds(45), TimeSpan.FromSeconds(55));
|
||||
});
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(NexusCommandersConst.SayDeath);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.IsTypeId(TypeId.Player))
|
||||
Talk(NexusCommandersConst.SayKill);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
|
||||
namespace Scripts.Northrend.Nexus.Nexus
|
||||
{
|
||||
struct OrmorokConst
|
||||
{
|
||||
//Spells
|
||||
public const uint SpellReflection = 47981;
|
||||
public const uint SpellTrample = 48016;
|
||||
public const uint SpellFrenzy = 48017;
|
||||
public const uint SpellSummonCrystallineTangler = 61564;
|
||||
public const uint SpellCrystalSpikes = 47958;
|
||||
|
||||
//Texts
|
||||
public const uint SayAggro = 1;
|
||||
public const uint SayDeath = 2;
|
||||
public const uint SayReflect = 3;
|
||||
public const uint SayCrystalSpikes = 4;
|
||||
public const uint SayKill = 5;
|
||||
public const uint SayFrenzy = 6;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_ormorok : BossAI
|
||||
{
|
||||
public boss_ormorok(Creature creature) : base(creature, DataTypes.Ormorok)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
frenzy = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
//Crystal Spikes
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
Talk(OrmorokConst.SayCrystalSpikes);
|
||||
DoCast(OrmorokConst.SpellCrystalSpikes);
|
||||
task.Repeat(TimeSpan.FromSeconds(12));
|
||||
});
|
||||
|
||||
//Trample
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
DoCast(me, OrmorokConst.SpellTrample);
|
||||
task.Repeat(TimeSpan.FromSeconds(10));
|
||||
});
|
||||
|
||||
//Spell Reflection
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
Talk(OrmorokConst.SayReflect);
|
||||
DoCast(me, OrmorokConst.SpellReflection);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
});
|
||||
|
||||
//Heroic Crystalline Tangler
|
||||
if (IsHeroic())
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(17), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, new OrmorokTanglerPredicate(me));
|
||||
if (target)
|
||||
DoCast(target, OrmorokConst.SpellSummonCrystallineTangler);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(17));
|
||||
});
|
||||
}
|
||||
|
||||
Talk(OrmorokConst.SayAggro);
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (!frenzy && HealthBelowPct(25))
|
||||
{
|
||||
Talk(OrmorokConst.SayFrenzy);
|
||||
DoCast(me, OrmorokConst.SpellFrenzy);
|
||||
frenzy = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(OrmorokConst.SayDeath);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.IsTypeId(TypeId.Player))
|
||||
Talk(OrmorokConst.SayKill);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool frenzy;
|
||||
}
|
||||
|
||||
class OrmorokTanglerPredicate : ISelector
|
||||
{
|
||||
public OrmorokTanglerPredicate(Unit unit)
|
||||
{
|
||||
me = unit;
|
||||
}
|
||||
|
||||
public bool Check(Unit target)
|
||||
{
|
||||
return target.GetDistance2d(me) >= 5.0f;
|
||||
}
|
||||
|
||||
Unit me;
|
||||
}
|
||||
|
||||
struct CrystalSpikesConst
|
||||
{
|
||||
public const uint NpcCrystalSpikeInitial = 27101;
|
||||
public const uint NpcCrystalSpikeTrigger = 27079;
|
||||
|
||||
public const uint DataCount = 1;
|
||||
public const uint MaxCount = 5;
|
||||
|
||||
public const uint SpellCrystalSpikeDamage = 47944;
|
||||
|
||||
public const uint GoCrystalSpikeTrap = 188537;
|
||||
|
||||
|
||||
public static uint[] CrystalSpikeSummon =
|
||||
{
|
||||
47936,
|
||||
47942,
|
||||
7943
|
||||
};
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_crystal_spike_trigger : ScriptedAI
|
||||
{
|
||||
public npc_crystal_spike_trigger(Creature creature) : base(creature) { }
|
||||
|
||||
public override void IsSummonedBy(Unit owner)
|
||||
{
|
||||
switch (me.GetEntry())
|
||||
{
|
||||
case CrystalSpikesConst.NpcCrystalSpikeInitial:
|
||||
_count = 0;
|
||||
me.SetFacingToObject(owner);
|
||||
break;
|
||||
case CrystalSpikesConst.NpcCrystalSpikeTrigger:
|
||||
Creature trigger = owner.ToCreature();
|
||||
if (trigger)
|
||||
_count = trigger.GetAI().GetData(CrystalSpikesConst.DataCount) + 1;
|
||||
break;
|
||||
default:
|
||||
_count = CrystalSpikesConst.MaxCount;
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeTrigger)
|
||||
{
|
||||
GameObject trap = me.FindNearestGameObject(CrystalSpikesConst.GoCrystalSpikeTrap, 1.0f);
|
||||
if (trap)
|
||||
trap.Use(me);
|
||||
}
|
||||
|
||||
//Despawn
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(2), task =>
|
||||
{
|
||||
if (me.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeTrigger)
|
||||
{
|
||||
GameObject trap = me.FindNearestGameObject(CrystalSpikesConst.GoCrystalSpikeTrap, 1.0f);
|
||||
if (trap)
|
||||
trap.Delete();
|
||||
}
|
||||
|
||||
me.DespawnOrUnsummon();
|
||||
});
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
return type == CrystalSpikesConst.DataCount ? _count : 0;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
uint _count;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_crystal_spike : AuraScript
|
||||
{
|
||||
void HandlePeriodic(AuraEffect aurEff)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
if (target.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeInitial || target.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeTrigger)
|
||||
{
|
||||
Creature trigger = target.ToCreature();
|
||||
if (trigger)
|
||||
{
|
||||
uint spell = target.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeInitial ? CrystalSpikesConst.CrystalSpikeSummon[0] : CrystalSpikesConst.CrystalSpikeSummon[RandomHelper.IRand(0, 2)];
|
||||
if (trigger.GetAI().GetData(CrystalSpikesConst.DataCount) < CrystalSpikesConst.MaxCount)
|
||||
trigger.CastSpell(trigger, spell, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodic, 0, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
|
||||
namespace Scripts.Northrend.Nexus.Nexus
|
||||
{
|
||||
struct DataTypes
|
||||
{
|
||||
public const uint Commander = 0;
|
||||
public const uint MagusTelestra = 1;
|
||||
public const uint Anomalus = 2;
|
||||
public const uint Ormorok = 3;
|
||||
public const uint Keristrasza = 4;
|
||||
|
||||
public const uint AnomalusContainmetSphere = 5;
|
||||
public const uint OrmorokContainmetSphere = 6;
|
||||
public const uint TelestraContainmetSphere = 7;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint Anomalus = 26763;
|
||||
public const uint Keristrasza = 26723;
|
||||
|
||||
// Alliance
|
||||
public const uint AllianceBerserker = 26800;
|
||||
public const uint AllianceRanger = 26802;
|
||||
public const uint AllianceCleric = 26805;
|
||||
public const uint AllianceCommander = 27949;
|
||||
public const uint CommanderStoutbeard = 26796;
|
||||
|
||||
// Horde
|
||||
public const uint HordeBerserker = 26799;
|
||||
public const uint HordeRanger = 26801;
|
||||
public const uint HordeCleric = 26803;
|
||||
public const uint HordeCommander = 27947;
|
||||
public const uint CommanderKolurg = 26798;
|
||||
}
|
||||
|
||||
struct GameObjectIds
|
||||
{
|
||||
public const uint AnomalusContainmetSphere = 188527;
|
||||
public const uint OrmoroksContainmetSphere = 188528;
|
||||
public const uint TelestrasContainmetSphere = 188526;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class instance_nexus : InstanceMapScript
|
||||
{
|
||||
public instance_nexus() : base(nameof(instance_nexus), 576) { }
|
||||
|
||||
class instance_nexus_InstanceMapScript : InstanceScript
|
||||
{
|
||||
public instance_nexus_InstanceMapScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("NEX");
|
||||
SetBossNumber(DataTypes.Keristrasza + 1);
|
||||
_teamInInstance = 0;
|
||||
}
|
||||
|
||||
public override void OnPlayerEnter(Player player)
|
||||
{
|
||||
if (_teamInInstance == 0)
|
||||
_teamInInstance = player.GetTeam();
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case CreatureIds.Anomalus:
|
||||
AnomalusGUID = creature.GetGUID();
|
||||
break;
|
||||
case CreatureIds.Keristrasza:
|
||||
KeristraszaGUID = creature.GetGUID();
|
||||
break;
|
||||
// Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs.
|
||||
case CreatureIds.AllianceBerserker:
|
||||
if (ServerAllowsTwoSideGroups())
|
||||
creature.SetFaction(16);
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.HordeBerserker);
|
||||
break;
|
||||
case CreatureIds.AllianceRanger:
|
||||
if (ServerAllowsTwoSideGroups())
|
||||
creature.SetFaction(16);
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.HordeRanger);
|
||||
break;
|
||||
case CreatureIds.AllianceCleric:
|
||||
if (ServerAllowsTwoSideGroups())
|
||||
creature.SetFaction(16);
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.HordeCleric);
|
||||
break;
|
||||
case CreatureIds.AllianceCommander:
|
||||
if (ServerAllowsTwoSideGroups())
|
||||
creature.SetFaction(16);
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.HordeCommander);
|
||||
break;
|
||||
case CreatureIds.CommanderStoutbeard:
|
||||
if (ServerAllowsTwoSideGroups())
|
||||
creature.SetFaction(16);
|
||||
if (_teamInInstance == Team.Alliance)
|
||||
creature.UpdateEntry(CreatureIds.CommanderKolurg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GameObjectIds.AnomalusContainmetSphere:
|
||||
AnomalusContainmentSphere = go.GetGUID();
|
||||
if (GetBossState(DataTypes.Anomalus) == EncounterState.Done)
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
break;
|
||||
case GameObjectIds.OrmoroksContainmetSphere:
|
||||
OrmoroksContainmentSphere = go.GetGUID();
|
||||
if (GetBossState(DataTypes.Ormorok) == EncounterState.Done)
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
break;
|
||||
case GameObjectIds.TelestrasContainmetSphere:
|
||||
TelestrasContainmentSphere = go.GetGUID();
|
||||
if (GetBossState(DataTypes.MagusTelestra) == EncounterState.Done)
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SetBossState(uint type, EncounterState state)
|
||||
{
|
||||
if (!base.SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.MagusTelestra:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
GameObject sphere = instance.GetGameObject(TelestrasContainmentSphere);
|
||||
if (sphere)
|
||||
sphere.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
}
|
||||
break;
|
||||
case DataTypes.Anomalus:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
GameObject sphere = instance.GetGameObject(AnomalusContainmentSphere);
|
||||
if (sphere)
|
||||
sphere.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
}
|
||||
break;
|
||||
case DataTypes.Ormorok:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
GameObject sphere = instance.GetGameObject(OrmoroksContainmentSphere);
|
||||
if (sphere)
|
||||
sphere.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.Anomalus:
|
||||
return AnomalusGUID;
|
||||
case DataTypes.Keristrasza:
|
||||
return KeristraszaGUID;
|
||||
case DataTypes.AnomalusContainmetSphere:
|
||||
return AnomalusContainmentSphere;
|
||||
case DataTypes.OrmorokContainmetSphere:
|
||||
return OrmoroksContainmentSphere;
|
||||
case DataTypes.TelestraContainmetSphere:
|
||||
return TelestrasContainmentSphere;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
ObjectGuid AnomalusGUID;
|
||||
ObjectGuid KeristraszaGUID;
|
||||
ObjectGuid AnomalusContainmentSphere;
|
||||
ObjectGuid OrmoroksContainmentSphere;
|
||||
ObjectGuid TelestrasContainmentSphere;
|
||||
Team _teamInInstance;
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_nexus_InstanceMapScript(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Scripts.Northrend.Nexus.Oculus
|
||||
{
|
||||
/*
|
||||
struct DataTypes
|
||||
{
|
||||
// Encounter States/Boss GUIDs
|
||||
public const uint Drakos = 0;
|
||||
public const uint Varos = 1;
|
||||
public const uint Urom = 2;
|
||||
public const uint Eregos = 3;
|
||||
// GPS System
|
||||
public const uint Constructs = 4;
|
||||
}
|
||||
|
||||
class instance_oculus : InstanceMapScript
|
||||
{
|
||||
public instance_oculus() : base(nameof(instance_oculus), 578) { }
|
||||
|
||||
class instance_oculus_InstanceMapScript : InstanceScript
|
||||
{
|
||||
public instance_oculus_InstanceMapScript(Map map) : base(map)
|
||||
{
|
||||
SetHeaders("OC");
|
||||
SetBossNumber(DataTypes.Eregos + 1);
|
||||
LoadDoorData(doorData);
|
||||
|
||||
CentrifugueConstructCounter = 0;
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case NPC_DRAKOS:
|
||||
DrakosGUID = creature.GetGUID();
|
||||
break;
|
||||
case NPC_VAROS:
|
||||
VarosGUID = creature.GetGUID();
|
||||
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
|
||||
creature.SetPhaseMask(1, true);
|
||||
break;
|
||||
case NPC_UROM:
|
||||
UromGUID = creature.GetGUID();
|
||||
if (GetBossState(DATA_VAROS) == EncounterState.Done)
|
||||
creature.SetPhaseMask(1, true);
|
||||
break;
|
||||
case NPC_EREGOS:
|
||||
EregosGUID = creature.GetGUID();
|
||||
if (GetBossState(DATA_UROM) == EncounterState.Done)
|
||||
creature.SetPhaseMask(1, true);
|
||||
break;
|
||||
case NPC_CENTRIFUGE_CONSTRUCT:
|
||||
if (creature.IsAlive())
|
||||
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, ++CentrifugueConstructCounter);
|
||||
break;
|
||||
case NPC_BELGARISTRASZ:
|
||||
BelgaristraszGUID = creature.GetGUID();
|
||||
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
|
||||
{
|
||||
creature.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
creature.Relocate(BelgaristraszMove);
|
||||
}
|
||||
break;
|
||||
case NPC_ETERNOS:
|
||||
EternosGUID = creature.GetGUID();
|
||||
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
|
||||
{
|
||||
creature.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
creature.Relocate(EternosMove);
|
||||
}
|
||||
break;
|
||||
case NPC_VERDISA:
|
||||
VerdisaGUID = creature.GetGUID();
|
||||
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
|
||||
{
|
||||
creature.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
|
||||
creature.Relocate(VerdisaMove);
|
||||
}
|
||||
break;
|
||||
case NPC_GREATER_WHELP:
|
||||
if (GetBossState(DATA_UROM) == EncounterState.Done)
|
||||
{
|
||||
creature.SetPhaseMask(1, true);
|
||||
GreaterWhelpList.Add(creature.GetGUID());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GO_DRAGON_CAGE_DOOR:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
case GO_EREGOS_CACHE_N:
|
||||
case GO_EREGOS_CACHE_H:
|
||||
EregosCacheGUID = go.GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectRemove(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case GO_DRAGON_CAGE_DOOR:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnUnitDeath(Unit unit)
|
||||
{
|
||||
Creature creature = unit.ToCreature();
|
||||
if (!creature)
|
||||
return;
|
||||
|
||||
if (creature.GetEntry() == NPC_CENTRIFUGE_CONSTRUCT)
|
||||
{
|
||||
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, --CentrifugueConstructCounter);
|
||||
|
||||
if (CentrifugueConstructCounter == 0)
|
||||
{
|
||||
Creature varos = instance.GetCreature(VarosGUID);
|
||||
if (varos)
|
||||
varos.RemoveAllAuras();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void FillInitialWorldStates(InitWorldStates packet)
|
||||
{
|
||||
if (GetBossState(DATA_DRAKOS) == EncounterState.Done && GetBossState(DATA_VAROS) != EncounterState.Done)
|
||||
{
|
||||
packet.Worldstates.Add(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
|
||||
packet.Worldstates.Add(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, CentrifugueConstructCounter);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.Worldstates.Add(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
|
||||
packet.Worldstates.Add(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ProcessEvent(WorldObject Unit, uint eventId)
|
||||
{
|
||||
if (eventId != EVENT_CALL_DRAGON)
|
||||
return;
|
||||
|
||||
Creature varos = instance.GetCreature(VarosGUID);
|
||||
if (varos)
|
||||
{
|
||||
Creature drake = varos.SummonCreature(NPC_AZURE_RING_GUARDIAN, varos.GetPositionX(), varos.GetPositionY(), varos.GetPositionZ() + 40);
|
||||
if (drake)
|
||||
drake.GetAI().DoAction(ACTION_CALL_DRAGON_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SetBossState(uint type, EncounterState state)
|
||||
{
|
||||
if (!base.SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DATA_DRAKOS:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
|
||||
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, CentrifugueConstructCounter);
|
||||
FreeDragons();
|
||||
Creature varos = instance.GetCreature(VarosGUID);
|
||||
if (varos)
|
||||
varos.SetPhaseMask(1, true);
|
||||
events.ScheduleEvent(EVENT_VAROS_INTRO, 15000);
|
||||
}
|
||||
break;
|
||||
case DATA_VAROS:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
|
||||
Creature urom = instance.GetCreature(UromGUID);
|
||||
if (urom)
|
||||
urom.SetPhaseMask(1, true);
|
||||
}
|
||||
break;
|
||||
case DATA_UROM:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
Creature eregos = instance.GetCreature(EregosGUID);
|
||||
if (eregos)
|
||||
{
|
||||
eregos.SetPhaseMask(1, true);
|
||||
GreaterWhelps();
|
||||
events.ScheduleEvent(EVENT_EREGOS_INTRO, 5000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DATA_EREGOS:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
GameObject cache = instance.GetGameObject(EregosCacheGUID);
|
||||
if (cache)
|
||||
{
|
||||
cache.SetRespawnTime((int)cache.GetRespawnDelay());
|
||||
cache.RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
if (type == DATA_CONSTRUCTS)
|
||||
{
|
||||
if (CentrifugueConstructCounter == 0)
|
||||
return KILL_NO_CONSTRUCT;
|
||||
else if (CentrifugueConstructCounter == 1)
|
||||
return KILL_ONE_CONSTRUCT;
|
||||
else if (CentrifugueConstructCounter > 1)
|
||||
return KILL_MORE_CONSTRUCT;
|
||||
}
|
||||
|
||||
return KILL_NO_CONSTRUCT;
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_DRAKOS:
|
||||
return DrakosGUID;
|
||||
case DATA_VAROS:
|
||||
return VarosGUID;
|
||||
case DATA_UROM:
|
||||
return UromGUID;
|
||||
case DATA_EREGOS:
|
||||
return EregosGUID;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
void FreeDragons()
|
||||
{
|
||||
Creature belgaristrasz = instance.GetCreature(BelgaristraszGUID);
|
||||
if (belgaristrasz)
|
||||
{
|
||||
belgaristrasz.SetWalk(true);
|
||||
belgaristrasz.GetMotionMaster().MovePoint(POINT_MOVE_OUT, BelgaristraszMove);
|
||||
}
|
||||
|
||||
Creature eternos = instance.GetCreature(EternosGUID);
|
||||
if (eternos)
|
||||
{
|
||||
eternos.SetWalk(true);
|
||||
eternos.GetMotionMaster().MovePoint(POINT_MOVE_OUT, EternosMove);
|
||||
}
|
||||
|
||||
Creature verdisa = instance.GetCreature(VerdisaGUID);
|
||||
if (verdisa)
|
||||
{
|
||||
verdisa.SetWalk(true);
|
||||
verdisa.GetMotionMaster().MovePoint(POINT_MOVE_OUT, VerdisaMove);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(uint diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_VAROS_INTRO:
|
||||
Creature varos = instance.GetCreature(VarosGUID);
|
||||
if (varos)
|
||||
varos.GetAI().Talk(SAY_VAROS_INTRO_TEXT);
|
||||
break;
|
||||
case EVENT_EREGOS_INTRO:
|
||||
Creature eregos = instance.GetCreature(EregosGUID);
|
||||
if (eregos)
|
||||
eregos.GetAI().Talk(SAY_EREGOS_INTRO_TEXT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void GreaterWhelps()
|
||||
{
|
||||
foreach (ObjectGuid guid in GreaterWhelpList)
|
||||
{
|
||||
Creature gwhelp = instance.GetCreature(guid);
|
||||
if (gwhelp)
|
||||
gwhelp.SetPhaseMask(1, true);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid DrakosGUID;
|
||||
ObjectGuid VarosGUID;
|
||||
ObjectGuid UromGUID;
|
||||
ObjectGuid EregosGUID;
|
||||
|
||||
ObjectGuid BelgaristraszGUID;
|
||||
ObjectGuid EternosGUID;
|
||||
ObjectGuid VerdisaGUID;
|
||||
|
||||
byte CentrifugueConstructCounter;
|
||||
|
||||
ObjectGuid EregosCacheGUID;
|
||||
|
||||
List<ObjectGuid> GreaterWhelpList = new List<ObjectGuid>();
|
||||
|
||||
EventMap events = new EventMap();
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 Game.Entities;
|
||||
|
||||
namespace Scripts.Northrend.Ulduar
|
||||
{
|
||||
namespace Algalon
|
||||
{
|
||||
class AlgalonTheObserver
|
||||
{
|
||||
public static Position AlgalonSummonPos = new Position(1632.531f, -304.8516f, 450.1123f, 1.530165f);
|
||||
public static Position AlgalonLandPos = new Position(1632.668f, -302.7656f, 417.3211f, 1.530165f);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Scripts.Northrend.Ulduar
|
||||
{
|
||||
namespace Razorscale
|
||||
{
|
||||
/*class boss_razorscale_controller : BossAI
|
||||
{
|
||||
public boss_razorscale_controller(Creature creature) : base(creature, InstanceData.RazorscaleControl)
|
||||
{
|
||||
me.SetDisplayId(me.GetCreatureTemplate().ModelId2);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
}
|
||||
|
||||
public override void SpellHit(Unit caster, SpellInfo spell)
|
||||
{
|
||||
switch (spell.Id)
|
||||
{
|
||||
case SPELL_FLAMED:
|
||||
GameObject Harpoon = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GO_RAZOR_HARPOON_1));
|
||||
if (Harpoon)
|
||||
Harpoon.RemoveFromWorld();
|
||||
Harpoon = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GO_RAZOR_HARPOON_2));
|
||||
if (Harpoon)
|
||||
Harpoon.RemoveFromWorld();
|
||||
Harpoon = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GO_RAZOR_HARPOON_3));
|
||||
if (Harpoon)
|
||||
Harpoon.RemoveFromWorld();
|
||||
Harpoon = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GO_RAZOR_HARPOON_4));
|
||||
if (Harpoon)
|
||||
Harpoon.RemoveFromWorld();
|
||||
|
||||
DoAction(ACTION_HARPOON_BUILD);
|
||||
DoAction(ACTION_PLACE_BROKEN_HARPOON);
|
||||
break;
|
||||
case SPELL_HARPOON_SHOT_1:
|
||||
case SPELL_HARPOON_SHOT_2:
|
||||
case SPELL_HARPOON_SHOT_3:
|
||||
case SPELL_HARPOON_SHOT_4:
|
||||
DoCast(SPELL_HARPOON_TRIGGER);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
if (instance.GetBossState(BOSS_RAZORSCALE) != EncounterState.InProgress)
|
||||
return;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_HARPOON_BUILD:
|
||||
events.ScheduleEvent(EVENT_BUILD_HARPOON_1, 50000);
|
||||
if (me->GetMap()->GetSpawnMode() == DIFFICULTY_25_N)
|
||||
events.ScheduleEvent(EVENT_BUILD_HARPOON_3, 90000);
|
||||
break;
|
||||
case ACTION_PLACE_BROKEN_HARPOON:
|
||||
for (uint8 n = 0; n < RAID_MODE(2, 4); n++)
|
||||
me->SummonGameObject(GO_RAZOR_BROKEN_HARPOON, PosHarpoon[n].GetPositionX(), PosHarpoon[n].GetPositionY(), PosHarpoon[n].GetPositionZ(), 2.286f, 0, 0, 0, 0, 180);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint Diff)
|
||||
{
|
||||
_events.Update(Diff);
|
||||
|
||||
while (uint eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BUILD_HARPOON_1:
|
||||
Talk(EMOTE_HARPOON);
|
||||
if (GameObject * Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_1, PosHarpoon[0].GetPositionX(), PosHarpoon[0].GetPositionY(), PosHarpoon[0].GetPositionZ(), 4.790f, 0.0f, 0.0f, 0.0f, 0.0f, uint32(me->GetRespawnTime())))
|
||||
{
|
||||
if (GameObject * BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) //only nearest broken harpoon
|
||||
BrokenHarpoon->RemoveFromWorld();
|
||||
events.ScheduleEvent(EVENT_BUILD_HARPOON_2, 20000);
|
||||
events.CancelEvent(EVENT_BUILD_HARPOON_1);
|
||||
}
|
||||
return;
|
||||
case EVENT_BUILD_HARPOON_2:
|
||||
Talk(EMOTE_HARPOON);
|
||||
if (GameObject * Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_2, PosHarpoon[1].GetPositionX(), PosHarpoon[1].GetPositionY(), PosHarpoon[1].GetPositionZ(), 4.659f, 0, 0, 0, 0, uint32(me->GetRespawnTime())))
|
||||
{
|
||||
if (GameObject * BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
|
||||
BrokenHarpoon->RemoveFromWorld();
|
||||
events.CancelEvent(EVENT_BUILD_HARPOON_2);
|
||||
}
|
||||
return;
|
||||
case EVENT_BUILD_HARPOON_3:
|
||||
Talk(EMOTE_HARPOON);
|
||||
if (GameObject * Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_3, PosHarpoon[2].GetPositionX(), PosHarpoon[2].GetPositionY(), PosHarpoon[2].GetPositionZ(), 5.382f, 0, 0, 0, 0, uint32(me->GetRespawnTime())))
|
||||
{
|
||||
if (GameObject * BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
|
||||
BrokenHarpoon->RemoveFromWorld();
|
||||
events.ScheduleEvent(EVENT_BUILD_HARPOON_4, 20000);
|
||||
events.CancelEvent(EVENT_BUILD_HARPOON_3);
|
||||
}
|
||||
return;
|
||||
case EVENT_BUILD_HARPOON_4:
|
||||
Talk(EMOTE_HARPOON);
|
||||
if (GameObject * Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_4, PosHarpoon[3].GetPositionX(), PosHarpoon[3].GetPositionY(), PosHarpoon[3].GetPositionZ(), 4.266f, 0, 0, 0, 0, uint32(me->GetRespawnTime())))
|
||||
{
|
||||
if (GameObject * BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
|
||||
BrokenHarpoon->RemoveFromWorld();
|
||||
events.CancelEvent(EVENT_BUILD_HARPOON_4);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override CreatureAI Get(Creature creature)
|
||||
{
|
||||
return GetInstanceAI<boss_razorscale_controllerAI>(creature);
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
namespace Scripts.Northrend.Ulduar
|
||||
{
|
||||
struct BossIds
|
||||
{
|
||||
public const uint MaxEncounter = 17;
|
||||
|
||||
public const uint Leviathan = 0;
|
||||
public const uint Ignis = 1;
|
||||
public const uint Razorscale = 2;
|
||||
public const uint Xt002 = 3;
|
||||
public const uint AssemblyOfIron = 4;
|
||||
public const uint Kologarn = 5;
|
||||
public const uint Auriaya = 6;
|
||||
public const uint Mimiron = 7;
|
||||
public const uint Hodir = 8;
|
||||
public const uint Thorim = 9;
|
||||
public const uint Freya = 10;
|
||||
public const uint Brightleaf = 11;
|
||||
public const uint Ironbranch = 12;
|
||||
public const uint Stonebark = 13;
|
||||
public const uint Vezax = 14;
|
||||
public const uint YoggSaron = 15;
|
||||
public const uint Algalon = 16;
|
||||
}
|
||||
|
||||
struct InstanceCreatureIds
|
||||
{
|
||||
// General
|
||||
public const uint Leviathan = 33113;
|
||||
public const uint SalvagedDemolisher = 33109;
|
||||
public const uint SalvagedSiegeEngine = 33060;
|
||||
public const uint SalvagedChopper = 33062;
|
||||
public const uint Ignis = 33118;
|
||||
public const uint Razorscale = 33186;
|
||||
public const uint RazorscaleController = 33233;
|
||||
public const uint SteelforgedDeffender = 33236;
|
||||
public const uint ExpeditionCommander = 33210;
|
||||
public const uint Xt002 = 33293;
|
||||
public const uint XtToyPile = 33337;
|
||||
public const uint Steelbreaker = 32867;
|
||||
public const uint Molgeim = 32927;
|
||||
public const uint Brundir = 32857;
|
||||
public const uint Kologarn = 32930;
|
||||
public const uint FocusedEyebeam = 33632;
|
||||
public const uint FocusedEyebeamRight = 33802;
|
||||
public const uint LeftArm = 32933;
|
||||
public const uint RightArm = 32934;
|
||||
public const uint Rubble = 33768;
|
||||
public const uint Auriaya = 33515;
|
||||
public const uint Mimiron = 33350;
|
||||
public const uint Hodir = 32845;
|
||||
public const uint Thorim = 32865;
|
||||
public const uint Freya = 32906;
|
||||
public const uint Vezax = 33271;
|
||||
public const uint YoggSaron = 33288;
|
||||
public const uint Algalon = 32871;
|
||||
|
||||
//XT002
|
||||
public const uint XS013Scrapbot = 33343;
|
||||
|
||||
// Mimiron
|
||||
public const uint LeviathanMkII = 33432;
|
||||
public const uint Vx001 = 33651;
|
||||
public const uint AerialCommandUnit = 33670;
|
||||
public const uint AssaultBot = 34057;
|
||||
public const uint BombBot = 33836;
|
||||
public const uint JunkBot = 33855;
|
||||
public const uint EmergencyFireBot = 34147;
|
||||
public const uint FrostBomb = 34149;
|
||||
public const uint BurstTarget = 34211;
|
||||
public const uint Flame = 34363;
|
||||
public const uint FlameSpread = 34121;
|
||||
public const uint DBTarget = 33576;
|
||||
public const uint RocketMimironVisual = 34050;
|
||||
public const uint WorldTriggerMimiron = 21252;
|
||||
public const uint Computer = 34143;
|
||||
|
||||
// Freya'S Keepers
|
||||
public const uint Ironbranch = 32913;
|
||||
public const uint Brightleaf = 32915;
|
||||
public const uint Stonebark = 32914;
|
||||
|
||||
// Hodir'S Helper Npcs
|
||||
public const uint TorGreycloud = 32941;
|
||||
public const uint KarGreycloud = 33333;
|
||||
public const uint EiviNightfeather = 33325;
|
||||
public const uint EllieNightfeather = 32901;
|
||||
public const uint SpiritwalkerTara = 33332;
|
||||
public const uint SpiritwalkerYona = 32950;
|
||||
public const uint ElementalistMahfuun = 33328;
|
||||
public const uint ElementalistAvuun = 32900;
|
||||
public const uint AmiraBlazeweaver = 33331;
|
||||
public const uint VeeshaBlazeweaver = 32946;
|
||||
public const uint MissyFlamecuffs = 32893;
|
||||
public const uint SissyFlamecuffs = 33327;
|
||||
public const uint BattlePriestEliza = 32948;
|
||||
public const uint BattlePriestGina = 33330;
|
||||
public const uint FieldMedicPenny = 32897;
|
||||
public const uint FieldMedicJessi = 33326;
|
||||
|
||||
// Freya'S Trash Npcs
|
||||
public const uint CorruptedServitor = 33354;
|
||||
public const uint MisguidedNymph = 33355;
|
||||
public const uint GuardianLasher = 33430;
|
||||
public const uint ForestSwarmer = 33431;
|
||||
public const uint MangroveEnt = 33525;
|
||||
public const uint IronrootLasher = 33526;
|
||||
public const uint NaturesBlade = 33527;
|
||||
public const uint GuardianOfLife = 33528;
|
||||
|
||||
// Freya Achievement Trigger
|
||||
public const uint FreyaAchieveTrigger = 33406;
|
||||
|
||||
// Yogg-Saron
|
||||
public const uint Sara = 33134;
|
||||
public const uint GuardianOfYoggSaron = 33136;
|
||||
public const uint HodirObservationRing = 33213;
|
||||
public const uint FreyaObservationRing = 33241;
|
||||
public const uint ThorimObservationRing = 33242;
|
||||
public const uint MimironObservationRing = 33244;
|
||||
public const uint VoiceOfYoggSaron = 33280;
|
||||
public const uint OminousCloud = 33292;
|
||||
public const uint FreyaYs = 33410;
|
||||
public const uint HodirYs = 33411;
|
||||
public const uint MimironYs = 33412;
|
||||
public const uint ThorimYs = 33413;
|
||||
public const uint SuitOfArmor = 33433;
|
||||
public const uint KingLlane = 33437;
|
||||
public const uint TheLichKing = 33441;
|
||||
public const uint ImmolatedChampion = 33442;
|
||||
public const uint Ysera = 33495;
|
||||
public const uint Neltharion = 33523;
|
||||
public const uint Malygos = 33535;
|
||||
public const uint DeathRay = 33881;
|
||||
public const uint DeathOrb = 33882;
|
||||
public const uint BrainOfYoggSaron = 33890;
|
||||
public const uint InfluenceTentacle = 33943;
|
||||
public const uint TurnedChampion = 33962;
|
||||
public const uint CrusherTentacle = 33966;
|
||||
public const uint ConstrictorTentacle = 33983;
|
||||
public const uint CorruptorTentacle = 33985;
|
||||
public const uint ImmortalGuardian = 33988;
|
||||
public const uint SanityWell = 33991;
|
||||
public const uint DescendIntoMadness = 34072;
|
||||
public const uint MarkedImmortalGuardian = 36064;
|
||||
|
||||
// Algalon The Observer
|
||||
public const uint BrannBronzbeardAlg = 34064;
|
||||
public const uint Azeroth = 34246;
|
||||
public const uint LivingConstellation = 33052;
|
||||
public const uint AlgalonStalker = 33086;
|
||||
public const uint CollapsingStar = 32955;
|
||||
public const uint BlackHole = 32953;
|
||||
public const uint WormHole = 34099;
|
||||
public const uint AlgalonVoidZoneVisualStalker = 34100;
|
||||
public const uint AlgalonStalkerAsteroidTarget01 = 33104;
|
||||
public const uint AlgalonStalkerAsteroidTarget02 = 33105;
|
||||
public const uint UnleashedDarkMatter = 34097;
|
||||
}
|
||||
|
||||
struct InstanceGameObjectIds
|
||||
{
|
||||
// Leviathan
|
||||
public const uint LeviathanDoor = 194905;
|
||||
public const uint LeviathanGate = 194630;
|
||||
|
||||
// Razorscale
|
||||
public const uint MoleMachine = 194316;
|
||||
public const uint RazorHarpoon1 = 194542;
|
||||
public const uint RazorHarpoon2 = 194541;
|
||||
public const uint RazorHarpoon3 = 194543;
|
||||
public const uint RazorHarpoon4 = 194519;
|
||||
public const uint RazorBrokenHarpoon = 194565;
|
||||
|
||||
// Xt-002
|
||||
public const uint Xt002Door = 194631;
|
||||
|
||||
// Assembly Of Iron
|
||||
public const uint IronCouncilDoor = 194554;
|
||||
public const uint ArchivumDoor = 194556;
|
||||
|
||||
// Kologarn
|
||||
public const uint KologarnChestHero = 195047;
|
||||
public const uint KologarnChest = 195046;
|
||||
public const uint KologarnBridge = 194232;
|
||||
public const uint KologarnDoor = 194553;
|
||||
|
||||
// Hodir
|
||||
public const uint HodirEntrance = 194442;
|
||||
public const uint HodirDoor = 194634;
|
||||
public const uint HodirIceDoor = 194441;
|
||||
public const uint HodirRareCacheOfWinter = 194200;
|
||||
public const uint HodirRareCacheOfWinterHero = 194201;
|
||||
public const uint HodirChestHero = 194308;
|
||||
public const uint HodirChest = 194307;
|
||||
|
||||
// Thorim
|
||||
public const uint ThorimChestHero = 194315;
|
||||
public const uint ThorimChest = 194314;
|
||||
|
||||
// Mimiron
|
||||
public const uint MimironTram = 194675;
|
||||
public const uint MimironElevator = 194749;
|
||||
public const uint MimironButton = 194739;
|
||||
public const uint MimironDoor1 = 194774;
|
||||
public const uint MimironDoor2 = 194775;
|
||||
public const uint MimironDoor3 = 194776;
|
||||
public const uint CacheOfInnovation = 194789;
|
||||
public const uint CacheOfInnovationFirefighter = 194957;
|
||||
public const uint CacheOfInnovationHero = 194956;
|
||||
public const uint CacheOfInnovationFirefighterHero = 194958;
|
||||
|
||||
// Vezax
|
||||
public const uint VezaxDoor = 194750;
|
||||
|
||||
// Yogg-Saron
|
||||
public const uint YoggSaronDoor = 194773;
|
||||
public const uint BrainRoomDoor1 = 194635;
|
||||
public const uint BrainRoomDoor2 = 194636;
|
||||
public const uint BrainRoomDoor3 = 194637;
|
||||
|
||||
// Algalon The Observer
|
||||
public const uint CelestialPlanetariumAccess10 = 194628;
|
||||
public const uint CelestialPlanetariumAccess25 = 194752;
|
||||
public const uint DoodadUlSigildoor01 = 194767;
|
||||
public const uint DoodadUlSigildoor02 = 194911;
|
||||
public const uint DoodadUlSigildoor03 = 194910;
|
||||
public const uint DoodadUlUniversefloor01 = 194715;
|
||||
public const uint DoodadUlUniversefloor02 = 194716;
|
||||
public const uint DoodadUlUniverseglobe01 = 194148;
|
||||
public const uint DoodadUlUlduarTrapdoor03 = 194253;
|
||||
public const uint GiftOfTheObserver10 = 194821;
|
||||
public const uint GiftOfTheObserver25 = 194822;
|
||||
}
|
||||
|
||||
struct InstanceEventIds
|
||||
{
|
||||
public const int TowerOfStormDestroyed = 21031;
|
||||
public const int TowerOfFrostDestroyed = 21032;
|
||||
public const int TowerOfFlamesDestroyed = 21033;
|
||||
public const int TowerOfLifeDestroyed = 21030;
|
||||
public const int ActivateSanityWell = 21432;
|
||||
public const int HodirsProtectiveGazeProc = 21437;
|
||||
}
|
||||
|
||||
struct LeviathanActions
|
||||
{
|
||||
public const int TowerOfStormDestroyed = 1;
|
||||
public const int TowerOfFrostDestroyed = 2;
|
||||
public const int TowerOfFlamesDestroyed = 3;
|
||||
public const int TowerOfLifeDestroyed = 4;
|
||||
public const int MoveToCenterPosition = 10;
|
||||
}
|
||||
|
||||
struct InstanceCriteriaIds
|
||||
{
|
||||
public const uint ConSpeedAtory = 21597;
|
||||
public const uint Lumberjacked = 21686;
|
||||
public const uint Disarmed = 21687;
|
||||
public const uint WaitsDreamingStormwind25 = 10321;
|
||||
public const uint WaitsDreamingChamber25 = 10322;
|
||||
public const uint WaitsDreamingIcecrown25 = 10323;
|
||||
public const uint WaitsDreamingStormwind10 = 10324;
|
||||
public const uint WaitsDreamingChamber10 = 10325;
|
||||
public const uint WaitsDreamingIcecrown10 = 10326;
|
||||
public const uint DriveMeCrazy10 = 10185;
|
||||
public const uint DriveMeCrazy25 = 10296;
|
||||
public const uint ThreeLightsInTheDarkness10 = 10410;
|
||||
public const uint ThreeLightsInTheDarkness25 = 10414;
|
||||
public const uint TwoLightsInTheDarkness10 = 10388;
|
||||
public const uint TwoLightsInTheDarkness25 = 10415;
|
||||
public const uint OneLightInTheDarkness10 = 10409;
|
||||
public const uint OneLightInTheDarkness25 = 10416;
|
||||
public const uint AloneInTheDarkness10 = 10412;
|
||||
public const uint AloneInTheDarkness25 = 10417;
|
||||
public const uint HeraldOfTitans = 10678;
|
||||
|
||||
// Champion Of Ulduar
|
||||
public const uint ChampionLeviathan10 = 10042;
|
||||
public const uint ChampionIgnis10 = 10342;
|
||||
public const uint ChampionRazorscale10 = 10340;
|
||||
public const uint ChampionXt002_10 = 10341;
|
||||
public const uint ChampionIronCouncil10 = 10598;
|
||||
public const uint ChampionKologarn10 = 10348;
|
||||
public const uint ChampionAuriaya10 = 10351;
|
||||
public const uint ChampionHodir10 = 10439;
|
||||
public const uint ChampionThorim10 = 10403;
|
||||
public const uint ChampionFreya10 = 10582;
|
||||
public const uint ChampionMimiron10 = 10347;
|
||||
public const uint ChampionVezax10 = 10349;
|
||||
public const uint ChampionYoggSaron10 = 10350;
|
||||
// Conqueror Of Ulduar
|
||||
public const uint ChampionLeviathan25 = 10352;
|
||||
public const uint ChampionIgnis25 = 10355;
|
||||
public const uint ChampionRazorscale25 = 10353;
|
||||
public const uint ChampionXt002_25 = 10354;
|
||||
public const uint ChampionIronCouncil25 = 10599;
|
||||
public const uint ChampionKologarn25 = 10357;
|
||||
public const uint ChampionAuriaya25 = 10363;
|
||||
public const uint ChampionHodir25 = 10719;
|
||||
public const uint ChampionThorim25 = 10404;
|
||||
public const uint ChampionFreya25 = 10583;
|
||||
public const uint ChampionMimiron25 = 10361;
|
||||
public const uint ChampionVezax25 = 10362;
|
||||
public const uint ChampionYoggSaron25 = 10364;
|
||||
}
|
||||
|
||||
struct InstanceData
|
||||
{
|
||||
// Colossus (Leviathan)
|
||||
public const uint Colossus = 20;
|
||||
|
||||
// Razorscale
|
||||
public const uint ExpeditionCommander = 21;
|
||||
public const uint RazorscaleControl = 22;
|
||||
|
||||
// Xt-002
|
||||
public const uint ToyPile0 = 23;
|
||||
public const uint ToyPile1 = 24;
|
||||
public const uint ToyPile2 = 25;
|
||||
public const uint ToyPile3 = 26;
|
||||
|
||||
// Assembly Of Iron
|
||||
public const uint Steelbreaker = 27;
|
||||
public const uint Molgeim = 28;
|
||||
public const uint Brundir = 29;
|
||||
|
||||
// Hodir
|
||||
public const uint HodirRareCache = 30;
|
||||
|
||||
// Mimiron
|
||||
public const uint LeviathanMKII = 31;
|
||||
public const uint VX001 = 32;
|
||||
public const uint AerialCommandUnit = 33;
|
||||
public const uint Computer = 34;
|
||||
public const uint MimironWorldTrigger = 35;
|
||||
public const uint MimironElevator = 36;
|
||||
public const uint MimironTram = 37;
|
||||
public const uint MimironButton = 38;
|
||||
|
||||
// Yogg-Saron
|
||||
public const uint VoiceOfYoggSaron = 39;
|
||||
public const uint Sara = 40;
|
||||
public const uint BrainOfYoggSaron = 41;
|
||||
public const uint FreyaYs = 42;
|
||||
public const uint HodirYs = 43;
|
||||
public const uint ThorimYs = 44;
|
||||
public const uint MimironYs = 45;
|
||||
public const uint Illusion = 46;
|
||||
public const uint DriveMeCrazy = 47;
|
||||
public const uint KeepersCount = 48;
|
||||
|
||||
// Algalon The Observer
|
||||
public const uint AlgalonSummonState = 49;
|
||||
public const uint Sigildoor01 = 50;
|
||||
public const uint Sigildoor02 = 51;
|
||||
public const uint Sigildoor03 = 52;
|
||||
public const uint UniverseFloor01 = 53;
|
||||
public const uint UniverseFloor02 = 54;
|
||||
public const uint UniverseGlobe = 55;
|
||||
public const uint AlgalonTrapdoor = 56;
|
||||
public const uint BrannBronzebeardAlg = 57;
|
||||
|
||||
// Misc
|
||||
public const uint BrannBronzebeardIntro = 58;
|
||||
public const uint LoreKeeperOfNorgannon = 59;
|
||||
public const uint Dellorah = 60;
|
||||
public const uint BronzebeardRadio = 61;
|
||||
}
|
||||
|
||||
struct InstanceWorldStates
|
||||
{
|
||||
public const uint AlgalonDespawnTimer = 4131;
|
||||
public const uint AlgalonTimerEnabled = 4132;
|
||||
}
|
||||
|
||||
struct InstanceAchievementData
|
||||
{
|
||||
// Fl Achievement Boolean
|
||||
public const uint DataUnbroken = 29052906; // 2905, 2906 Are Achievement Ids,
|
||||
public const uint MaxHeraldArmorItemlevel = 226;
|
||||
public const uint MaxHeraldWeaponItemlevel = 232;
|
||||
}
|
||||
|
||||
struct InstanceEvents
|
||||
{
|
||||
public const uint EventDespawnAlgalon = 1;
|
||||
public const uint EventUpdateAlgalonTimer = 2;
|
||||
public const uint ActionInitAlgalon = 6;
|
||||
}
|
||||
|
||||
struct YoggSaronIllusions
|
||||
{
|
||||
public const uint ChamberIllusion = 0;
|
||||
public const uint IcecrownIllusion = 1;
|
||||
public const uint StormwindIllusion = 2;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,884 @@
|
||||
/*
|
||||
* 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 Framework.Dynamic;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Northrend.Ulduar.Xt002
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint TympanicTantrum = 62776;
|
||||
public const uint SearingLight = 63018;
|
||||
|
||||
public const uint SummonLifeSpark = 64210;
|
||||
public const uint SummonVoidZone = 64203;
|
||||
|
||||
public const uint GravityBomb = 63024;
|
||||
|
||||
public const uint Heartbreak = 65737;
|
||||
|
||||
// Cast By 33337 At Heartbreak:
|
||||
public const uint RechargePummeler = 62831; // Summons 33344
|
||||
public const uint RechargeScrapbot = 62828; // Summons 33343
|
||||
public const uint RechargeBoombot = 62835; // Summons 33346
|
||||
|
||||
// Cast By 33329 On 33337 (Visual?)
|
||||
public const uint EnergyOrb = 62790; // Triggers 62826 - Needs Spellscript For Periodic Tick To Cast One Of The Random Spells Above
|
||||
|
||||
public const uint HeartHealToFull = 17683;
|
||||
public const uint HeartOverload = 62789;
|
||||
|
||||
public const uint HeartLightningTether = 64799; // Cast On Self?
|
||||
public const uint Enrage = 26662;
|
||||
public const uint Stand = 37752;
|
||||
public const uint Submerge = 37751;
|
||||
|
||||
//------------------Void Zone--------------------
|
||||
public const uint VoidZone = 64203;
|
||||
public const uint Consumption = 64208;
|
||||
|
||||
// Life Spark
|
||||
public const uint ArcanePowerState = 49411;
|
||||
public const uint StaticCharged = 64227;
|
||||
public const uint Shock = 64230;
|
||||
|
||||
//----------------Xt-002 Heart-------------------
|
||||
public const uint ExposedHeart = 63849;
|
||||
public const uint HeartRideVehicle = 63852;
|
||||
public const uint RideVehicleExposed = 63313; //Heart Exposed
|
||||
|
||||
//---------------Xm-024 Pummeller----------------
|
||||
public const uint ArcingSmash = 8374;
|
||||
public const uint Trample = 5568;
|
||||
public const uint Uppercut = 10966;
|
||||
|
||||
// Scrabot:
|
||||
public const uint ScrapbotRideVehicle = 47020;
|
||||
public const uint ScrapRepair = 62832;
|
||||
public const uint Suicide = 7;
|
||||
|
||||
//------------------Boombot-----------------------
|
||||
public const uint AuraBoombot = 65032;
|
||||
public const uint Boom = 62834;
|
||||
|
||||
// Achievement-Related Spells
|
||||
public const uint AchievementCreditNerfScrapbots = 65037;
|
||||
}
|
||||
|
||||
struct XT002Data
|
||||
{
|
||||
public const uint TransferedHealth = 0;
|
||||
public const uint HardMode = 1;
|
||||
public const uint HealthRecovered = 2;
|
||||
public const uint GravityBombCasualty = 3;
|
||||
}
|
||||
|
||||
struct Texts
|
||||
{
|
||||
public const uint Aggro = 0;
|
||||
public const uint HeartOpened = 1;
|
||||
public const uint HeartClosed = 2;
|
||||
public const uint TympanicTantrum = 3;
|
||||
public const uint Slay = 4;
|
||||
public const uint Berserk = 5;
|
||||
public const uint Death = 6;
|
||||
public const uint Summon = 7;
|
||||
public const uint EmoteHeartOpened = 8;
|
||||
public const uint EmoteHeartClosed = 9;
|
||||
public const uint EmoteTympanicTantrum = 10;
|
||||
public const uint EmoteScrapbot = 11;
|
||||
}
|
||||
|
||||
struct Misc
|
||||
{
|
||||
public const uint PhaseOneGroup = 1;
|
||||
public const int ActionHardMode = 1;
|
||||
public const uint AchievMustDeconstructFaster = 21027;
|
||||
|
||||
public const sbyte SeatHeartNormal = 0;
|
||||
public const sbyte SeatHeartExposed = 1;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_xt002 : BossAI
|
||||
{
|
||||
public boss_xt002(Creature creature) : base(creature, BossIds.Xt002)
|
||||
{
|
||||
Initialize();
|
||||
_transferHealth = 0;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_healthRecovered = false;
|
||||
_gravityBombCasualty = false;
|
||||
_hardMode = false;
|
||||
|
||||
_heartExposed = 0;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
me.SetReactState(ReactStates.Aggressive);
|
||||
DoCastSelf(SpellIds.Stand);
|
||||
|
||||
Initialize();
|
||||
|
||||
instance.DoStopCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievMustDeconstructFaster);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
Talk(Texts.Aggro);
|
||||
_EnterCombat();
|
||||
|
||||
//Enrage
|
||||
_scheduler.Schedule(TimeSpan.FromMinutes(10), task =>
|
||||
{
|
||||
Talk(Texts.Berserk);
|
||||
DoCastSelf(SpellIds.Enrage);
|
||||
});
|
||||
|
||||
//Gavity Bomb
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), Misc.PhaseOneGroup, task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.GravityBomb);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(20));
|
||||
});
|
||||
|
||||
//Searing Light
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), Misc.PhaseOneGroup, task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.SearingLight);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(20));
|
||||
});
|
||||
|
||||
//Tympanic Tantrum
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), Misc.PhaseOneGroup, task =>
|
||||
{
|
||||
Talk(Texts.TympanicTantrum);
|
||||
Talk(Texts.EmoteTympanicTantrum);
|
||||
DoCast(SpellIds.TympanicTantrum);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
});
|
||||
|
||||
instance.DoStartCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievMustDeconstructFaster);
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case Misc.ActionHardMode:
|
||||
_scheduler.Schedule(TimeSpan.FromMilliseconds(1), task =>
|
||||
{
|
||||
SetPhaseOne(true);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit who)
|
||||
{
|
||||
if (who.GetTypeId() == TypeId.Player)
|
||||
Talk(Texts.Slay);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Talk(Texts.Death);
|
||||
_JustDied();
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage)
|
||||
{
|
||||
if (!_hardMode && !me.HasReactState(ReactStates.Passive) && !HealthAbovePct(100 - 25 * (_heartExposed + 1)))
|
||||
ExposeHeart();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (!me.HasReactState(ReactStates.Passive))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override void PassengerBoarded(Unit who, sbyte seatId, bool apply)
|
||||
{
|
||||
if (apply && who.GetEntry() == InstanceCreatureIds.XS013Scrapbot)
|
||||
{
|
||||
// Need this so we can properly determine when to expose heart again in damagetaken hook
|
||||
if (me.GetHealthPct() > (25 * (4 - _heartExposed)))
|
||||
++_heartExposed;
|
||||
|
||||
Talk(Texts.EmoteScrapbot);
|
||||
DoCast(who, SpellIds.ScrapRepair, true);
|
||||
_healthRecovered = true;
|
||||
}
|
||||
|
||||
if (apply && seatId == Misc.SeatHeartExposed)
|
||||
who.CastSpell(who, SpellIds.ExposedHeart); // Channeled
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case XT002Data.HardMode:
|
||||
return _hardMode ? 1 : 0u;
|
||||
case XT002Data.HealthRecovered:
|
||||
return _healthRecovered ? 1 : 0u;
|
||||
case XT002Data.GravityBombCasualty:
|
||||
return _gravityBombCasualty ? 1 : 0u;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void SetData(uint type, uint data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case XT002Data.TransferedHealth:
|
||||
_transferHealth = data;
|
||||
break;
|
||||
case XT002Data.GravityBombCasualty:
|
||||
_gravityBombCasualty = (data > 0) ? true : false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ExposeHeart()
|
||||
{
|
||||
Talk(Texts.HeartOpened);
|
||||
Talk(Texts.EmoteHeartOpened);
|
||||
|
||||
DoCastSelf(SpellIds.Submerge); // WIll make creature untargetable
|
||||
me.AttackStop();
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
|
||||
Unit heart = me.GetVehicleKit() ? me.GetVehicleKit().GetPassenger(Misc.SeatHeartNormal) : null;
|
||||
if (heart)
|
||||
{
|
||||
heart.CastSpell(heart, SpellIds.HeartOverload);
|
||||
heart.CastSpell(me, SpellIds.HeartLightningTether);
|
||||
heart.CastSpell(heart, SpellIds.HeartHealToFull, true);
|
||||
heart.CastSpell(me, SpellIds.RideVehicleExposed, true);
|
||||
heart.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
heart.SetFlag(UnitFields.Flags, UnitFlags.Unk29);
|
||||
}
|
||||
_scheduler.DelayGroup(Misc.PhaseOneGroup, TimeSpan.FromSeconds(30));
|
||||
|
||||
// Start "end of phase 2 timer"
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task => { SetPhaseOne(false); });
|
||||
|
||||
_heartExposed++;
|
||||
}
|
||||
|
||||
void SetPhaseOne(bool isHardMode)
|
||||
{
|
||||
if (isHardMode)
|
||||
{
|
||||
me.SetFullHealth();
|
||||
DoCastSelf(SpellIds.Heartbreak, true);
|
||||
me.AddLootMode(LootModes.HardMode1);
|
||||
_hardMode = true;
|
||||
}
|
||||
|
||||
Talk(Texts.HeartClosed);
|
||||
Talk(Texts.EmoteHeartClosed);
|
||||
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
me.SetReactState(ReactStates.Aggressive);
|
||||
DoCastSelf(SpellIds.Stand);
|
||||
|
||||
//_events.RescheduleEvent(EVENT_SEARING_LIGHT, TIMER_SEARING_LIGHT / 2);
|
||||
//_events.RescheduleEvent(EVENT_GRAVITY_BOMB, TIMER_GRAVITY_BOMB);
|
||||
//_events.RescheduleEvent(EVENT_TYMPANIC_TANTRUM, RandomHelper.URand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX));
|
||||
|
||||
Unit heart = me.GetVehicleKit() ? me.GetVehicleKit().GetPassenger(Misc.SeatHeartExposed) : null;
|
||||
if (!heart)
|
||||
return;
|
||||
|
||||
heart.CastSpell(me, SpellIds.HeartRideVehicle, true);
|
||||
heart.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
heart.RemoveFlag(UnitFields.Flags, UnitFlags.Unk29);
|
||||
heart.RemoveAurasDueToSpell(SpellIds.ExposedHeart);
|
||||
|
||||
if (!_hardMode)
|
||||
{
|
||||
if (_transferHealth == 0)
|
||||
_transferHealth = (uint)(heart.GetMaxHealth() - heart.GetHealth());
|
||||
|
||||
if (_transferHealth >= me.GetHealth())
|
||||
_transferHealth = (uint)me.GetHealth() - 1;
|
||||
|
||||
me.ModifyHealth(-(int)_transferHealth);
|
||||
me.LowerPlayerDamageReq(_transferHealth);
|
||||
}
|
||||
}
|
||||
|
||||
// Achievement related
|
||||
bool _healthRecovered; // Did a scrapbot recover XT-002's health during the encounter?
|
||||
bool _hardMode; // Are we in hard mode? Or: was the heart killed during phase 2?
|
||||
bool _gravityBombCasualty; // Did someone die because of Gravity Bomb damage?
|
||||
|
||||
byte _heartExposed;
|
||||
uint _transferHealth;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_xt002_heart : ScriptedAI
|
||||
{
|
||||
public npc_xt002_heart(Creature creature) : base(creature)
|
||||
{
|
||||
_instance = creature.GetInstanceScript();
|
||||
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff) { }
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
Creature xt002 = _instance != null ? ObjectAccessor.GetCreature(me, _instance.GetGuidData(BossIds.Xt002)) : null;
|
||||
if (!xt002 || xt002.GetAI() == null)
|
||||
return;
|
||||
|
||||
xt002.GetAI().SetData(XT002Data.TransferedHealth, (uint)me.GetHealth());
|
||||
xt002.GetAI().DoAction(Misc.ActionHardMode);
|
||||
}
|
||||
|
||||
InstanceScript _instance;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_scrapbot : ScriptedAI
|
||||
{
|
||||
public npc_scrapbot(Creature creature) : base(creature)
|
||||
{
|
||||
_instance = me.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
Creature pXT002 = ObjectAccessor.GetCreature(me, _instance.GetGuidData(BossIds.Xt002));
|
||||
if (pXT002)
|
||||
me.GetMotionMaster().MoveFollow(pXT002, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
ObjectGuid guid = _instance.GetGuidData(BossIds.Xt002);
|
||||
if (type == MovementGeneratorType.Follow && id == guid.GetCounter())
|
||||
{
|
||||
Creature xt002 = ObjectAccessor.GetCreature(me, guid);
|
||||
if (xt002)
|
||||
{
|
||||
if (me.IsWithinMeleeRange(xt002))
|
||||
{
|
||||
DoCast(xt002, SpellIds.ScrapbotRideVehicle);
|
||||
// Unapply vehicle aura again
|
||||
xt002.RemoveAurasDueToSpell(SpellIds.ScrapbotRideVehicle);
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InstanceScript _instance;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_pummeller : ScriptedAI
|
||||
{
|
||||
public npc_pummeller(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
_instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_scheduler.SetValidator(() => me.IsWithinMeleeRange(me.GetVictim()));
|
||||
|
||||
//Arcing Smash
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(27), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.ArcingSmash);
|
||||
task.Repeat(TimeSpan.FromSeconds(27));
|
||||
});
|
||||
|
||||
//Trample
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(22), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Trample);
|
||||
task.Repeat(TimeSpan.FromSeconds(22));
|
||||
});
|
||||
|
||||
//Uppercut
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(17), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Uppercut);
|
||||
task.Repeat(TimeSpan.FromSeconds(17));
|
||||
});
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
Creature xt002 = ObjectAccessor.GetCreature(me, _instance.GetGuidData(BossIds.Xt002));
|
||||
if (xt002)
|
||||
{
|
||||
Position pos = xt002.GetPosition();
|
||||
me.GetMotionMaster().MovePoint(0, pos);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
InstanceScript _instance;
|
||||
}
|
||||
|
||||
class BoomEvent : BasicEvent
|
||||
{
|
||||
public BoomEvent(Creature me)
|
||||
{
|
||||
_me = me;
|
||||
}
|
||||
|
||||
public override bool Execute(ulong time, uint diff)
|
||||
{
|
||||
// This hack is here because we suspect our implementation of spell effect execution on targets
|
||||
// is done in the wrong order. We suspect that 0 needs to be applied on all targets,
|
||||
// then 1, etc - instead of applying each effect on target1, then target2, etc.
|
||||
// The above situation causes the visual for this spell to be bugged, so we remove the instakill
|
||||
// effect and implement a script hack for that.
|
||||
|
||||
_me.CastSpell(_me, SpellIds.Boom, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
Creature _me;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_boombot : ScriptedAI
|
||||
{
|
||||
public npc_boombot(Creature creature) : base(creature)
|
||||
{
|
||||
Initialize();
|
||||
_instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_boomed = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
DoCast(SpellIds.AuraBoombot); // For achievement
|
||||
|
||||
// HACK/workaround:
|
||||
// these values aren't confirmed - lack of data - and the values in DB are incorrect
|
||||
// these values are needed for correct damage of Boom spell
|
||||
me.SetFloatValue(UnitFields.MinDamage, 15000.0f);
|
||||
me.SetFloatValue(UnitFields.MaxDamage, 18000.0f);
|
||||
|
||||
// @todo proper waypoints?
|
||||
Creature pXT002 = ObjectAccessor.GetCreature(me, _instance.GetGuidData(BossIds.Xt002));
|
||||
if (pXT002)
|
||||
me.GetMotionMaster().MoveFollow(pXT002, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit who, ref uint damage)
|
||||
{
|
||||
if (damage >= (me.GetHealth() - me.GetMaxHealth() * 0.5f) && !_boomed)
|
||||
{
|
||||
_boomed = true; // Prevent recursive calls
|
||||
|
||||
//me.SendSpellInstakillLog(Spells.Boom, me);
|
||||
|
||||
//me.DealDamage(me, me.GetHealth(), null, DamageEffectType.NoDamage, SpellSchoolMask.Normal, null, false);
|
||||
|
||||
damage = 0;
|
||||
|
||||
me.CastSpell(me, SpellIds.Boom, false);
|
||||
|
||||
// Visual only seems to work if the instant kill event is delayed or the spell itself is delayed
|
||||
// Casting done from player and caster source has the same targetinfo flags,
|
||||
// so that can't be the issue
|
||||
// See BoomEvent class
|
||||
// Schedule 1s delayed
|
||||
//me.m_Events.AddEvent(new BoomEvent(me), me.m_Events.CalculateTime(1 * Time.InMilliseconds));
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// No melee attack
|
||||
}
|
||||
|
||||
InstanceScript _instance;
|
||||
bool _boomed;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_life_spark : ScriptedAI
|
||||
{
|
||||
public npc_life_spark(Creature creature) : base(creature) { }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromMilliseconds(1), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Shock);
|
||||
task.Repeat(TimeSpan.FromSeconds(12));
|
||||
});
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
DoCastSelf(SpellIds.ArcanePowerState);
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit victim)
|
||||
{
|
||||
DoCastSelf(SpellIds.StaticCharged);
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Shock);
|
||||
task.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, DoMeleeAttackIfReady);
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_xt_void_zone : PassiveAI
|
||||
{
|
||||
public npc_xt_void_zone(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(1), consumption =>
|
||||
{
|
||||
DoCastSelf(SpellIds.Consumption);
|
||||
consumption.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_xt002_searing_light_spawn_life_spark : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SummonLifeSpark);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Player player = GetOwner().ToPlayer();
|
||||
if (player)
|
||||
{
|
||||
Unit xt002 = GetCaster();
|
||||
if (xt002)
|
||||
if (xt002.HasAura((uint)aurEff.GetAmount())) // Heartbreak aura indicating hard mode
|
||||
xt002.CastSpell(player, SpellIds.SummonLifeSpark, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.PeriodicTriggerSpell, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_xt002_gravity_bomb_aura : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SummonVoidZone);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Player player = GetOwner().ToPlayer();
|
||||
if (player)
|
||||
{
|
||||
Unit xt002 = GetCaster();
|
||||
if (xt002)
|
||||
if (xt002.HasAura((uint)aurEff.GetAmount())) // Heartbreak aura indicating hard mode
|
||||
xt002.CastSpell(player, SpellIds.SummonVoidZone, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPeriodic(AuraEffect aurEff)
|
||||
{
|
||||
Unit xt002 = GetCaster();
|
||||
if (!xt002)
|
||||
return;
|
||||
|
||||
Unit owner = GetOwner().ToUnit();
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
if ((uint)aurEff.GetAmount() >= owner.GetHealth())
|
||||
if (xt002.GetAI() != null)
|
||||
xt002.GetAI().SetData(XT002Data.GravityBombCasualty, 1);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(OnPeriodic, 2, AuraType.PeriodicDamage));
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.PeriodicTriggerSpell, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_xt002_gravity_bomb_damage : SpellScript
|
||||
{
|
||||
void HandleScript(uint eff)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
if ((uint)GetHitDamage() >= GetHitUnit().GetHealth())
|
||||
if (caster.GetAI() != null)
|
||||
caster.GetAI().SetData(XT002Data.GravityBombCasualty, 1);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.SchoolDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_xt002_heart_overload_periodic : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.EnergyOrb, SpellIds.RechargeBoombot, SpellIds.RechargePummeler, SpellIds.RechargeScrapbot);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
{
|
||||
InstanceScript instance = caster.GetInstanceScript();
|
||||
if (instance != null)
|
||||
{
|
||||
Unit toyPile = Global.ObjAccessor.GetUnit(caster, instance.GetGuidData(InstanceData.ToyPile0 + RandomHelper.URand(0, 3)));
|
||||
if (toyPile)
|
||||
{
|
||||
caster.CastSpell(toyPile, SpellIds.EnergyOrb, true);
|
||||
|
||||
// This should probably be incorporated in a dummy effect handler, but I've had trouble getting the correct target
|
||||
// Weighed randomization (approximation)
|
||||
uint[] spells = { SpellIds.RechargeScrapbot, SpellIds.RechargeScrapbot, SpellIds.RechargeScrapbot, SpellIds.RechargePummeler, SpellIds.RechargeBoombot };
|
||||
|
||||
for (byte i = 0; i < 5; ++i)
|
||||
{
|
||||
uint spellId = spells[RandomHelper.IRand(0, 4)];
|
||||
toyPile.CastSpell(toyPile, spellId, true, null, null, instance.GetGuidData(BossIds.Xt002));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Creature creatureBase = caster.GetVehicleCreatureBase();
|
||||
if (creatureBase)
|
||||
creatureBase.GetAI().Talk(Texts.Summon);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHit.Add(new EffectHandler(HandleScript, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_xt002_tympanic_tantrum : SpellScript
|
||||
{
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.RemoveAll(new PlayerOrPetCheck());
|
||||
}
|
||||
|
||||
void RecalculateDamage()
|
||||
{
|
||||
SetHitDamage((int)GetHitUnit().CountPctFromMaxHealth(GetHitDamage()));
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEnemy));
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 1, Targets.UnitSrcAreaEnemy));
|
||||
OnHit.Add(new HitHandler(RecalculateDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_xt002_submerged : SpellScript
|
||||
{
|
||||
void HandleScript(uint eff)
|
||||
{
|
||||
Creature target = GetHitCreature();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
target.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
target.SetStandState(UnitStandStateType.Submerged);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_xt002_321_boombot_aura : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.AchievementCreditNerfScrapbots);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
if (eventInfo.GetActionTarget().GetEntry() != InstanceCreatureIds.XS013Scrapbot)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
InstanceScript instance = eventInfo.GetActor().GetInstanceScript();
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
instance.DoCastSpellOnPlayers(SpellIds.AchievementCreditNerfScrapbots);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_nerf_engineering : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_nerf_engineering() : base("achievement_nerf_engineering") { }
|
||||
|
||||
public override bool OnCheck(Player source, Unit target)
|
||||
{
|
||||
if (!target || target.GetAI() == null)
|
||||
return false;
|
||||
|
||||
return target.GetAI().GetData(XT002Data.HealthRecovered) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_heartbreaker : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_heartbreaker() : base("achievement_heartbreaker") { }
|
||||
|
||||
public override bool OnCheck(Player source, Unit target)
|
||||
{
|
||||
if (!target || target.GetAI() == null)
|
||||
return false;
|
||||
|
||||
return target.GetAI().GetData(XT002Data.HardMode) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class achievement_nerf_gravity_bombs : AchievementCriteriaScript
|
||||
{
|
||||
public achievement_nerf_gravity_bombs() : base("achievement_nerf_gravity_bombs") { }
|
||||
|
||||
public override bool OnCheck(Player source, Unit target)
|
||||
{
|
||||
if (!target || target.GetAI() == null)
|
||||
return false;
|
||||
|
||||
return target.GetAI().GetData(XT002Data.GravityBombCasualty) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 Game.Entities;
|
||||
|
||||
namespace Scripts.Northrend.Ulduar
|
||||
{
|
||||
class YoggSaron
|
||||
{
|
||||
public static Position[] ObservationRingKeepersPos =
|
||||
{
|
||||
new Position(1945.682f, 33.34201f, 411.4408f, 5.270895f), // Freya
|
||||
new Position(1945.761f, -81.52171f, 411.4407f, 1.029744f), // Hodir
|
||||
new Position(2028.822f, -65.73573f, 411.4426f, 2.460914f), // Thorim
|
||||
new Position(2028.766f, 17.42014f, 411.4446f, 3.857178f), // Mimiron
|
||||
};
|
||||
public static Position[] YSKeepersPos =
|
||||
{
|
||||
new Position(2036.873f, 25.42513f, 338.4984f, 3.909538f), // Freya
|
||||
new Position(1939.045f, -90.87457f, 338.5426f, 0.994837f), // Hodir
|
||||
new Position(1939.148f, 42.49035f, 338.5427f, 5.235988f), // Thorim
|
||||
new Position(2036.658f, -73.58822f, 338.4985f, 2.460914f), // Mimiron
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
namespace Scripts.Northrend.VioletHold
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.BattleFields;
|
||||
using Game.Conditions;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
|
||||
namespace Scripts.Northrend
|
||||
{
|
||||
[Script]
|
||||
class spell_wintergrasp_defender_teleport : SpellScript
|
||||
{
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
BattleField wg = Global.BattleFieldMgr.GetBattlefieldByBattleId(1);
|
||||
if (wg != null)
|
||||
{
|
||||
Player target = GetExplTargetUnit().ToPlayer();
|
||||
if (target)
|
||||
// check if we are in Wintergrasp at all, SotA uses same teleport spells
|
||||
if ((target.GetZoneId() == 4197 && target.GetTeamId() != wg.GetDefenderTeam()) || target.HasAura(54643))
|
||||
return SpellCastResult.BadTargets;
|
||||
}
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_wintergrasp_defender_teleport_trigger : SpellScript
|
||||
{
|
||||
void HandleDummy(uint effindex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
{
|
||||
WorldLocation loc = target.GetWorldLocation();
|
||||
SetExplTargetDest(loc);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class condition_is_wintergrasp_horde : ConditionScript
|
||||
{
|
||||
public condition_is_wintergrasp_horde() : base("condition_is_wintergrasp_horde") { }
|
||||
|
||||
public override bool OnConditionCheck(Condition condition, ConditionSourceInfo sourceInfo)
|
||||
{
|
||||
BattleField wintergrasp = Global.BattleFieldMgr.GetBattlefieldByBattleId(BattlefieldIds.WG);
|
||||
if (wintergrasp.IsEnabled() && wintergrasp.GetDefenderTeam() == TeamId.Horde)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class condition_is_wintergrasp_alliance : ConditionScript
|
||||
{
|
||||
public condition_is_wintergrasp_alliance() : base("condition_is_wintergrasp_alliance") { }
|
||||
|
||||
public override bool OnConditionCheck(Condition condition, ConditionSourceInfo sourceInfo)
|
||||
{
|
||||
BattleField wintergrasp = Global.BattleFieldMgr.GetBattlefieldByBattleId(BattlefieldIds.WG);
|
||||
if (wintergrasp.IsEnabled() && wintergrasp.GetDefenderTeam() == TeamId.Alliance)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* 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;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.PvP;
|
||||
|
||||
namespace Scripts.Outlands
|
||||
{
|
||||
struct Aeranas
|
||||
{
|
||||
public const uint SaySummon = 0;
|
||||
public const uint SayFree = 1;
|
||||
|
||||
public const uint FactionHostile = 16;
|
||||
public const uint FactionFriendly = 35;
|
||||
|
||||
public const uint SpellEncelopingWinds = 15535;
|
||||
public const uint SpellShock = 12553;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_aeranas : ScriptedAI
|
||||
{
|
||||
public npc_aeranas(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
faction_Timer = 8000;
|
||||
envelopingWinds_Timer = 9000;
|
||||
shock_Timer = 5000;
|
||||
|
||||
me.RemoveFlag64(UnitFields.NpcFlags, NPCFlags.QuestGiver);
|
||||
me.SetFaction(Aeranas.FactionFriendly);
|
||||
|
||||
Talk(Aeranas.SaySummon);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (faction_Timer != 0)
|
||||
{
|
||||
if (faction_Timer <= diff)
|
||||
{
|
||||
me.SetFaction(Aeranas.FactionHostile);
|
||||
faction_Timer = 0;
|
||||
}
|
||||
else
|
||||
faction_Timer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (HealthBelowPct(30))
|
||||
{
|
||||
me.SetFaction(Aeranas.FactionFriendly);
|
||||
me.SetFlag64(UnitFields.NpcFlags, NPCFlags.QuestGiver);
|
||||
me.RemoveAllAuras();
|
||||
me.DeleteThreatList();
|
||||
me.CombatStop(true);
|
||||
Talk(Aeranas.SayFree);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shock_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(Aeranas.SpellShock);
|
||||
shock_Timer = 10000;
|
||||
}
|
||||
else
|
||||
shock_Timer -= diff;
|
||||
|
||||
if (envelopingWinds_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(Aeranas.SpellEncelopingWinds);
|
||||
envelopingWinds_Timer = 25000;
|
||||
}
|
||||
else
|
||||
envelopingWinds_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
uint faction_Timer;
|
||||
uint envelopingWinds_Timer;
|
||||
uint shock_Timer;
|
||||
}
|
||||
|
||||
struct AncestralWolf
|
||||
{
|
||||
public const uint EmoteWoldLiftHead = 0;
|
||||
public const uint EmoteWolfHowl = 1;
|
||||
public const uint SayWolfWelcome = 2;
|
||||
|
||||
public const uint SpellAncestralWoldBuff = 29981;
|
||||
|
||||
public const uint NpcRyga = 17123;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_ancestral_wolf : npc_escortAI
|
||||
{
|
||||
public npc_ancestral_wolf(Creature creature) : base(creature)
|
||||
{
|
||||
if (creature.GetOwner() && creature.GetOwner().IsTypeId(TypeId.Player))
|
||||
Start(false, false, creature.GetOwner().GetGUID());
|
||||
else
|
||||
Log.outError(LogFilter.Scripts, "Scripts: npc_ancestral_wolf can not obtain owner or owner is not a player.");
|
||||
|
||||
creature.SetSpeed(UnitMoveType.Walk, 1.5f);
|
||||
Reset();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
ryga = null;
|
||||
DoCast(me, AncestralWolf.SpellAncestralWoldBuff, true);
|
||||
}
|
||||
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
if (!ryga && who.GetEntry() == AncestralWolf.NpcRyga && me.IsWithinDistInMap(who, 15.0f))
|
||||
{
|
||||
Creature temp = who.ToCreature();
|
||||
if (temp)
|
||||
ryga = temp;
|
||||
}
|
||||
|
||||
base.MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
public override void WaypointReached(uint waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(AncestralWolf.EmoteWoldLiftHead);
|
||||
break;
|
||||
case 2:
|
||||
Talk(AncestralWolf.EmoteWolfHowl);
|
||||
break;
|
||||
case 50:
|
||||
if (ryga && ryga.IsAlive() && !ryga.IsInCombat())
|
||||
ryga.GetAI().Talk(AncestralWolf.SayWolfWelcome);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Creature ryga;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_wounded_blood_elf : npc_escortAI
|
||||
{
|
||||
public npc_wounded_blood_elf(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset() { }
|
||||
|
||||
public override void EnterCombat(Unit who)
|
||||
{
|
||||
if (HasEscortState(eEscortState.Escorting))
|
||||
Talk(SAY_ELF_AGGRO);
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summoned)
|
||||
{
|
||||
summoned.GetAI().AttackStart(me);
|
||||
}
|
||||
|
||||
public override void sQuestAccept(Player player, Quest quest)
|
||||
{
|
||||
if (quest.Id == QUEST_ROAD_TO_FALCON_WATCH)
|
||||
{
|
||||
me.SetFaction(FACTION_FALCON_WATCH_QUEST);
|
||||
base.Start(true, false, player.GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
public override void WaypointReached(uint waypointId)
|
||||
{
|
||||
Player player = GetPlayerForEscort();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_ELF_START, player);
|
||||
break;
|
||||
case 9:
|
||||
Talk(SAY_ELF_SUMMON1, player);
|
||||
// Spawn two Haal'eshi Talonguard
|
||||
DoSpawnCreature(NPC_HAALESHI_TALONGUARD, -15, -15, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
|
||||
DoSpawnCreature(NPC_HAALESHI_TALONGUARD, -17, -17, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
|
||||
break;
|
||||
case 13:
|
||||
Talk(SAY_ELF_RESTING, player);
|
||||
break;
|
||||
case 14:
|
||||
Talk(SAY_ELF_SUMMON2, player);
|
||||
// Spawn two Haal'eshi Windwalker
|
||||
DoSpawnCreature(NPC_HAALESHI_WINDWALKER, -15, -15, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
|
||||
DoSpawnCreature(NPC_HAALESHI_WINDWALKER, -17, -17, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
|
||||
break;
|
||||
case 27:
|
||||
Talk(SAY_ELF_COMPLETE, player);
|
||||
// Award quest credit
|
||||
player.GroupEventHappens(QUEST_ROAD_TO_FALCON_WATCH, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const uint SAY_ELF_START = 0;
|
||||
const uint SAY_ELF_SUMMON1 = 1;
|
||||
const uint SAY_ELF_RESTING = 2;
|
||||
const uint SAY_ELF_SUMMON2 = 3;
|
||||
const uint SAY_ELF_COMPLETE = 4;
|
||||
const uint SAY_ELF_AGGRO = 5;
|
||||
const uint QUEST_ROAD_TO_FALCON_WATCH = 9375;
|
||||
const uint NPC_HAALESHI_WINDWALKER = 16966;
|
||||
const uint NPC_HAALESHI_TALONGUARD = 16967;
|
||||
const uint FACTION_FALCON_WATCH_QUEST = 775;
|
||||
}
|
||||
|
||||
|
||||
[Script]
|
||||
class npc_fel_guard_hound : ScriptedAI
|
||||
{
|
||||
public npc_fel_guard_hound(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
checkTimer = 5000; //check for creature every 5 sec
|
||||
helboarGUID.Clear();
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Point || id != 1)
|
||||
return;
|
||||
|
||||
Creature helboar = me.GetMap().GetCreature(helboarGUID);
|
||||
if (helboar)
|
||||
{
|
||||
helboar.RemoveCorpse();
|
||||
DoCast(SPELL_SUMMON_POO);
|
||||
|
||||
Player owner = me.GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
if (owner)
|
||||
me.GetMotionMaster().MoveFollow(owner, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (checkTimer <= diff)
|
||||
{
|
||||
Creature helboar = me.FindNearestCreature(NPC_DERANGED_HELBOAR, 10.0f, false);
|
||||
if (helboar)
|
||||
{
|
||||
if (helboar.GetGUID() != helboarGUID && me.GetMotionMaster().GetCurrentMovementGeneratorType() != MovementGeneratorType.Point && !me.FindCurrentSpellBySpellId(SPELL_SUMMON_POO))
|
||||
{
|
||||
helboarGUID = helboar.GetGUID();
|
||||
me.GetMotionMaster().MovePoint(1, helboar.GetPositionX(), helboar.GetPositionY(), helboar.GetPositionZ());
|
||||
}
|
||||
}
|
||||
checkTimer = 5000;
|
||||
}
|
||||
else checkTimer -= diff;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
uint checkTimer;
|
||||
ObjectGuid helboarGUID;
|
||||
|
||||
const uint SPELL_SUMMON_POO = 37688;
|
||||
const uint NPC_DERANGED_HELBOAR = 16863;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class HellfirePeninsulaPvPScript : OutdoorPvPScript
|
||||
{
|
||||
public HellfirePeninsulaPvPScript() : base("outdoorpvp_hp") { }
|
||||
|
||||
public override OutdoorPvP GetOutdoorPvP()
|
||||
{
|
||||
return new HellfirePeninsulaPvP();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* 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;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Outlands
|
||||
{
|
||||
[Script]
|
||||
class npcs_ashyen_and_keleth : CreatureScript
|
||||
{
|
||||
public npcs_ashyen_and_keleth() : base("npcs_ashyen_and_keleth") { }
|
||||
|
||||
public override bool OnGossipHello(Player player, Creature creature)
|
||||
{
|
||||
if (player.GetReputationRank(942) > ReputationRank.Neutral)
|
||||
{
|
||||
if (creature.GetEntry() == NPC_ASHYEN)
|
||||
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_BLESS_ASH, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
|
||||
|
||||
if (creature.GetEntry() == NPC_KELETH)
|
||||
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_BLESS_KEL, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
|
||||
}
|
||||
player.SEND_GOSSIP_MENU(player.GetGossipTextId(creature), creature.GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnGossipSelect(Player player, Creature creature, uint sender, uint action)
|
||||
{
|
||||
player.PlayerTalkClass.ClearMenus();
|
||||
if (action == eTradeskill.GossipActionInfoDef + 1)
|
||||
{
|
||||
creature.setPowerType(PowerType.Mana);
|
||||
creature.SetMaxPower(PowerType.Mana, 200); //set a "fake" mana value, we can't depend on database doing it in this case
|
||||
creature.SetPower(PowerType.Mana, 200);
|
||||
|
||||
if (creature.GetEntry() == NPC_ASHYEN) //check which Creature we are dealing with
|
||||
{
|
||||
uint spell = 0;
|
||||
switch (player.GetReputationRank(942))
|
||||
{ //mark of lore
|
||||
case ReputationRank.Friendly:
|
||||
spell = SPELL_BLESS_ASH_FRI;
|
||||
break;
|
||||
case ReputationRank.Honored:
|
||||
spell = SPELL_BLESS_ASH_HON;
|
||||
break;
|
||||
case ReputationRank.Revered:
|
||||
spell = SPELL_BLESS_ASH_REV;
|
||||
break;
|
||||
case ReputationRank.Exalted:
|
||||
spell = SPELL_BLESS_ASH_EXA;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (spell != 0)
|
||||
{
|
||||
creature.CastSpell(player, spell, true);
|
||||
creature.GetAI().Talk(GOSSIP_REWARD_BLESS);
|
||||
}
|
||||
}
|
||||
|
||||
if (creature.GetEntry() == NPC_KELETH)
|
||||
{
|
||||
uint spell = 0;
|
||||
switch (player.GetReputationRank(942)) //mark of war
|
||||
{
|
||||
case ReputationRank.Friendly:
|
||||
spell = SPELL_BLESS_KEL_FRI;
|
||||
break;
|
||||
case ReputationRank.Honored:
|
||||
spell = SPELL_BLESS_KEL_HON;
|
||||
break;
|
||||
case ReputationRank.Revered:
|
||||
spell = SPELL_BLESS_KEL_REV;
|
||||
break;
|
||||
case ReputationRank.Exalted:
|
||||
spell = SPELL_BLESS_KEL_EXA;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (spell != 0)
|
||||
{
|
||||
creature.CastSpell(player, spell, true);
|
||||
creature.GetAI().Talk(GOSSIP_REWARD_BLESS);
|
||||
}
|
||||
}
|
||||
player.CLOSE_GOSSIP_MENU();
|
||||
player.TalkedToCreature(creature.GetEntry(), creature.GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint GOSSIP_REWARD_BLESS = 0;
|
||||
|
||||
const uint NPC_ASHYEN = 17900;
|
||||
const uint NPC_KELETH = 17901;
|
||||
|
||||
const uint SPELL_BLESS_ASH_EXA = 31815;
|
||||
const uint SPELL_BLESS_ASH_REV = 31811;
|
||||
const uint SPELL_BLESS_ASH_HON = 31810;
|
||||
const uint SPELL_BLESS_ASH_FRI = 31808;
|
||||
|
||||
const uint SPELL_BLESS_KEL_EXA = 31814;
|
||||
const uint SPELL_BLESS_KEL_REV = 31813;
|
||||
const uint SPELL_BLESS_KEL_HON = 31812;
|
||||
const uint SPELL_BLESS_KEL_FRI = 31807;
|
||||
|
||||
const string GOSSIP_ITEM_BLESS_ASH = "Grant me your mark, wise ancient.";
|
||||
const string GOSSIP_ITEM_BLESS_KEL = "Grant me your mark, mighty ancient.";
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_cooshcoosh : CreatureScript
|
||||
{
|
||||
public npc_cooshcoosh() : base("npc_cooshcoosh") { }
|
||||
|
||||
class npc_cooshcooshAI : ScriptedAI
|
||||
{
|
||||
public npc_cooshcooshAI(Creature creature) : base(creature)
|
||||
{
|
||||
m_uiNormFaction = creature.getFaction();
|
||||
}
|
||||
|
||||
uint m_uiNormFaction;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.ScheduleEvent(Event_LightningBolt, 2000);
|
||||
if (me.getFaction() != m_uiNormFaction)
|
||||
me.SetFaction(m_uiNormFaction);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(id =>
|
||||
{
|
||||
DoCastVictim(SPELL_LIGHTNING_BOLT);
|
||||
_events.ScheduleEvent(Event_LightningBolt, 5000);
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
public override CreatureAI GetAI(Creature creature)
|
||||
{
|
||||
return new npc_cooshcooshAI(creature);
|
||||
}
|
||||
|
||||
public override bool OnGossipHello(Player player, Creature creature)
|
||||
{
|
||||
if (player.GetQuestStatus(QUEST_CRACK_SKULLS) == QuestStatus.Incomplete)
|
||||
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_COOSH, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef);
|
||||
|
||||
player.SEND_GOSSIP_MENU(9441, creature.GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnGossipSelect(Player player, Creature creature, uint sender, uint action)
|
||||
{
|
||||
player.PlayerTalkClass.ClearMenus();
|
||||
if (action == eTradeskill.GossipActionInfoDef)
|
||||
{
|
||||
player.CLOSE_GOSSIP_MENU();
|
||||
creature.SetFaction(FACTION_HOSTILE_CO);
|
||||
creature.GetAI().AttackStart(player);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint SPELL_LIGHTNING_BOLT = 9532;
|
||||
const uint QUEST_CRACK_SKULLS = 10009;
|
||||
const uint FACTION_HOSTILE_CO = 45;
|
||||
const int Event_LightningBolt = 1;
|
||||
|
||||
const string GOSSIP_COOSH = "You owe Sim'salabim money. Hand them over or die!";
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_elder_kuruti : CreatureScript
|
||||
{
|
||||
public npc_elder_kuruti() : base("npc_elder_kuruti") { }
|
||||
|
||||
public override bool OnGossipHello(Player player, Creature creature)
|
||||
{
|
||||
if (player.GetQuestStatus(9803) == QuestStatus.Incomplete)
|
||||
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_KUR1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef);
|
||||
|
||||
player.SEND_GOSSIP_MENU(9226, creature.GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnGossipSelect(Player player, Creature creature, uint sender, uint action)
|
||||
{
|
||||
player.PlayerTalkClass.ClearMenus();
|
||||
switch (action)
|
||||
{
|
||||
case eTradeskill.GossipActionInfoDef:
|
||||
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_KUR2, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
|
||||
player.SEND_GOSSIP_MENU(9227, creature.GetGUID());
|
||||
break;
|
||||
case eTradeskill.GossipActionInfoDef + 1:
|
||||
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_KUR3, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 2);
|
||||
player.SEND_GOSSIP_MENU(9229, creature.GetGUID());
|
||||
break;
|
||||
case eTradeskill.GossipActionInfoDef + 2:
|
||||
{
|
||||
if (!player.HasItemCount(24573))
|
||||
{
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
uint itemId = 24573;
|
||||
uint temp;
|
||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, itemId, 1, out temp);
|
||||
if (msg == InventoryResult.Ok)
|
||||
{
|
||||
player.StoreNewItem(dest, itemId, true);
|
||||
}
|
||||
else
|
||||
player.SendEquipError(msg, null, null, itemId);
|
||||
}
|
||||
player.SEND_GOSSIP_MENU(9231, creature.GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const string GOSSIP_ITEM_KUR1 = "Greetings, elder. It is time for your people to end their hostility towards the draenei and their allies.";
|
||||
const string GOSSIP_ITEM_KUR2 = "I did not mean to deceive you, elder. The draenei of Telredor thought to approach you in a way that would seem familiar to you.";
|
||||
const string GOSSIP_ITEM_KUR3 = "I will tell them. Farewell, elder.";
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_kayra_longmane : CreatureScript
|
||||
{
|
||||
public npc_kayra_longmane() : base("npc_kayra_longmane") { }
|
||||
|
||||
class npc_kayra_longmaneAI : npc_escortAI
|
||||
{
|
||||
public npc_kayra_longmaneAI(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset() { }
|
||||
|
||||
public override void WaypointReached(uint waypointId)
|
||||
{
|
||||
Player player = GetPlayerForEscort();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (waypointId)
|
||||
{
|
||||
case 4:
|
||||
Talk(SAY_AMBUSH1, player);
|
||||
DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOOC, 30000);
|
||||
DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOOC, 30000);
|
||||
break;
|
||||
case 5:
|
||||
Talk(SAY_PROGRESS, player);
|
||||
SetRun();
|
||||
break;
|
||||
case 16:
|
||||
Talk(SAY_AMBUSH2, player);
|
||||
DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOOC, 30000);
|
||||
DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOOC, 30000);
|
||||
break;
|
||||
case 17:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 25:
|
||||
Talk(SAY_END, player);
|
||||
player.GroupEventHappens(QUEST_ESCAPE_FROM, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnQuestAccept(Player player, Creature creature, Quest quest)
|
||||
{
|
||||
if (quest.Id == QUEST_ESCAPE_FROM)
|
||||
{
|
||||
creature.GetAI().Talk(SAY_START, player);
|
||||
|
||||
npc_escortAI pEscortAI = (npc_kayra_longmaneAI)creature.GetAI();
|
||||
if (pEscortAI != null)
|
||||
pEscortAI.Start(false, false, player.GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override CreatureAI GetAI(Creature creature)
|
||||
{
|
||||
return new npc_kayra_longmaneAI(creature);
|
||||
}
|
||||
|
||||
const uint SAY_START = 0;
|
||||
const uint SAY_AMBUSH1 = 1;
|
||||
const uint SAY_PROGRESS = 2;
|
||||
const uint SAY_AMBUSH2 = 3;
|
||||
const uint SAY_END = 4;
|
||||
|
||||
const uint QUEST_ESCAPE_FROM = 9752;
|
||||
const uint NPC_SLAVEBINDER = 18042;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace Scripts.Pets
|
||||
{
|
||||
[Script]
|
||||
class npc_pet_dk_ebon_gargoyle : CasterAI
|
||||
{
|
||||
public npc_pet_dk_ebon_gargoyle(Creature creature) : base(creature) { }
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
base.InitializeAI();
|
||||
ObjectGuid ownerGuid = me.GetOwnerGUID();
|
||||
if (ownerGuid.IsEmpty())
|
||||
return;
|
||||
|
||||
// Find victim of Summon Gargoyle spell
|
||||
List<Unit> targets = new List<Unit>();
|
||||
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
|
||||
var searcher = new UnitListSearcher(me, targets, u_check);
|
||||
Cell.VisitAllObjects(me, searcher, 30.0f);
|
||||
foreach (var iter in targets)
|
||||
{
|
||||
if (iter.GetAura(SpellSummonGargoyle1, ownerGuid) != null)
|
||||
{
|
||||
me.Attack(iter, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
// Stop Feeding Gargoyle when it dies
|
||||
Unit owner = me.GetOwner();
|
||||
if (owner)
|
||||
owner.RemoveAurasDueToSpell(SpellSummonGargoyle2);
|
||||
}
|
||||
|
||||
// Fly away when dismissed
|
||||
public override void SpellHit(Unit source, SpellInfo spell)
|
||||
{
|
||||
if (spell.Id != SpellDismissGargoyle || !me.IsAlive())
|
||||
return;
|
||||
|
||||
Unit owner = me.GetOwner();
|
||||
if (!owner || owner != source)
|
||||
return;
|
||||
|
||||
// Stop Fighting
|
||||
me.ApplyModFlag(UnitFields.Flags, UnitFlags.NonAttackable, true);
|
||||
|
||||
// Sanctuary
|
||||
me.CastSpell(me, SpellSanctuary, true);
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
|
||||
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
|
||||
// Fly Away
|
||||
me.SetCanFly(true);
|
||||
me.SetSpeedRate(UnitMoveType.Flight, 0.75f);
|
||||
me.SetSpeedRate(UnitMoveType.Run, 0.75f);
|
||||
float x = me.GetPositionX() + 20 * (float)Math.Cos(me.GetOrientation());
|
||||
float y = me.GetPositionY() + 20 * (float)Math.Sin(me.GetOrientation());
|
||||
float z = me.GetPositionZ() + 40;
|
||||
me.GetMotionMaster().Clear(false);
|
||||
me.GetMotionMaster().MovePoint(0, x, y, z);
|
||||
|
||||
// Despawn as soon as possible
|
||||
me.DespawnOrUnsummon(4 * Time.InMilliseconds);
|
||||
}
|
||||
|
||||
const uint SpellSummonGargoyle1 = 49206;
|
||||
const uint SpellSummonGargoyle2 = 50514;
|
||||
const uint SpellDismissGargoyle = 50515;
|
||||
const uint SpellSanctuary = 54661;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_pet_dk_guardian : AggressorAI
|
||||
{
|
||||
public npc_pet_dk_guardian(Creature creature) : base(creature) { }
|
||||
|
||||
public override bool CanAIAttack(Unit target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
Unit owner = me.GetOwner();
|
||||
if (owner && !target.IsInCombatWith(owner))
|
||||
return false;
|
||||
return base.CanAIAttack(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
|
||||
namespace Scripts.Pets
|
||||
{
|
||||
[Script]
|
||||
class npc_pet_gen_mojo : ScriptedAI
|
||||
{
|
||||
public npc_pet_gen_mojo(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_victimGUID.Clear();
|
||||
|
||||
Unit owner = me.GetOwner();
|
||||
if (owner)
|
||||
me.GetMotionMaster().MoveFollow(owner, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
|
||||
public override void UpdateAI(uint diff) { }
|
||||
|
||||
public override void ReceiveEmote(Player player, TextEmotes emote)
|
||||
{
|
||||
me.HandleEmoteCommand((Emote)emote);
|
||||
Unit owner = me.GetOwner();
|
||||
if (emote != TextEmotes.Kiss || !owner || !owner.IsTypeId(TypeId.Player) ||
|
||||
owner.ToPlayer().GetTeam() != player.GetTeam())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Talk(SayMojo, player);
|
||||
|
||||
if (!_victimGUID.IsEmpty())
|
||||
{
|
||||
Player victim = Global.ObjAccessor.GetPlayer(me, _victimGUID);
|
||||
if (victim)
|
||||
victim.RemoveAura(SpellFeelingFroggy);
|
||||
}
|
||||
|
||||
_victimGUID = player.GetGUID();
|
||||
|
||||
DoCast(player, SpellFeelingFroggy, true);
|
||||
DoCast(me, SpellSeductionVisual, true);
|
||||
me.GetMotionMaster().MoveFollow(player, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
ObjectGuid _victimGUID;
|
||||
|
||||
const uint SayMojo = 0;
|
||||
const uint SpellFeelingFroggy = 43906;
|
||||
const uint SpellSeductionVisual = 43919;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
|
||||
namespace Scripts.Pets
|
||||
{
|
||||
[Script]
|
||||
class npc_pet_hunter_snake_trap : ScriptedAI
|
||||
{
|
||||
public npc_pet_hunter_snake_trap(Creature creature) : base(creature) { }
|
||||
|
||||
public override void EnterCombat(Unit who) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_spellTimer = 0;
|
||||
|
||||
CreatureTemplate Info = me.GetCreatureTemplate();
|
||||
|
||||
_isViper = Info.Entry == NpcViper ? true : false;
|
||||
|
||||
me.SetMaxHealth((uint)(107 * (me.getLevel() - 40) * 0.025f));
|
||||
// Add delta to make them not all hit the same time
|
||||
uint delta = (RandomHelper.Rand32() % 7) * 100;
|
||||
me.SetStatFloatValue(UnitFields.BaseAttackTime, Info.BaseAttackTime + delta);
|
||||
//me.SetStatFloatValue(UnitFields.RangedAttackPower, (float)Info.AttackPower);
|
||||
|
||||
// Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
|
||||
if (!me.GetVictim() && me.IsSummon())
|
||||
{
|
||||
Unit owner = me.ToTempSummon().GetSummoner();
|
||||
if (owner)
|
||||
if (owner.getAttackerForHelper())
|
||||
AttackStart(owner.getAttackerForHelper());
|
||||
}
|
||||
|
||||
if (!_isViper)
|
||||
DoCast(me, SpellDeadlyPoisonPassive, true);
|
||||
}
|
||||
|
||||
// Redefined for random target selection:
|
||||
public override void MoveInLineOfSight(Unit who)
|
||||
{
|
||||
if (!me.GetVictim() && me.CanCreatureAttack(who))
|
||||
{
|
||||
if (me.GetDistanceZ(who) > SharedConst.CreatureAttackRangeZ)
|
||||
return;
|
||||
|
||||
float attackRadius = me.GetAttackDistance(who);
|
||||
if (me.IsWithinDistInMap(who, attackRadius) && me.IsWithinLOSInMap(who))
|
||||
{
|
||||
if ((RandomHelper.Rand32() % 5) == 0)
|
||||
{
|
||||
me.setAttackTimer(WeaponAttackType.BaseAttack, (RandomHelper.Rand32() % 10) * 100);
|
||||
_spellTimer = (RandomHelper.Rand32() % 10) * 100;
|
||||
AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim() || !me.GetVictim())
|
||||
return;
|
||||
|
||||
if (me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
|
||||
{
|
||||
me.InterruptNonMeleeSpells(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//Viper
|
||||
if (_isViper)
|
||||
{
|
||||
if (_spellTimer <= diff)
|
||||
{
|
||||
if (RandomHelper.IRand(0, 2) == 0) //33% chance to cast
|
||||
DoCastVictim(RandomHelper.RAND(SpellMindNumbingPoison, SpellCripplingPoison));
|
||||
|
||||
_spellTimer = 3000;
|
||||
}
|
||||
else
|
||||
_spellTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool _isViper;
|
||||
uint _spellTimer;
|
||||
|
||||
const uint SpellCripplingPoison = 30981; // Viper
|
||||
const uint SpellDeadlyPoisonPassive = 34657; // Venomous Snake
|
||||
const uint SpellMindNumbingPoison = 25810; // Viper
|
||||
|
||||
const int NpcViper = 19921;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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 System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Pets
|
||||
{
|
||||
struct PetMageConst
|
||||
{
|
||||
public const uint SpellCloneMe = 45204;
|
||||
public const uint SpellMastersThreatList = 58838;
|
||||
public const uint SpellMageFrostBolt = 59638;
|
||||
public const uint SpellMageFireBlast = 59637;
|
||||
|
||||
|
||||
public const uint TimerMirrorImageInit = 0;
|
||||
public const uint TimerMirrorImageFrostBolt = 4000;
|
||||
public const uint TimerMirrorImageFireBlast = 6000;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_pet_mage_mirror_image : CasterAI
|
||||
{
|
||||
public npc_pet_mage_mirror_image(Creature creature) : base(creature) { }
|
||||
|
||||
void Init()
|
||||
{
|
||||
Unit owner = me.GetCharmerOrOwner();
|
||||
|
||||
List<Unit> targets = new List<Unit>();
|
||||
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
|
||||
var searcher = new UnitListSearcher(me, targets, u_check);
|
||||
Cell.VisitAllObjects(me, searcher, 40.0f);
|
||||
|
||||
Unit highestThreatUnit = null;
|
||||
float highestThreat = 0.0f;
|
||||
Unit nearestPlayer = null;
|
||||
foreach (var unit in targets)
|
||||
{
|
||||
// Consider only units without CC
|
||||
if (!unit.HasBreakableByDamageCrowdControlAura(unit))
|
||||
{
|
||||
// Take first found unit
|
||||
if (!highestThreatUnit && !unit.IsTypeId(TypeId.Player))
|
||||
{
|
||||
highestThreatUnit = unit;
|
||||
continue;
|
||||
}
|
||||
if (!nearestPlayer && unit.IsTypeId(TypeId.Player))
|
||||
{
|
||||
nearestPlayer = unit;
|
||||
continue;
|
||||
}
|
||||
// else compare best fit unit with current unit
|
||||
var triggers = unit.GetThreatManager().getThreatList();
|
||||
foreach (var reference in triggers)
|
||||
{
|
||||
// Try to find threat referenced to owner
|
||||
if (reference.getTarget() == owner)
|
||||
{
|
||||
// Check if best fit hostile unit hs lower threat than this current unit
|
||||
if (highestThreat < reference.getThreat())
|
||||
{
|
||||
// If so, update best fit unit
|
||||
highestThreat = reference.getThreat();
|
||||
highestThreatUnit = unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// In case no unit with threat was found so far, always check for nearest unit (only for players)
|
||||
if (unit.IsTypeId(TypeId.Player))
|
||||
{
|
||||
// If this player is closer than the previous one, update it
|
||||
if (me.GetDistance(unit.GetPosition()) < me.GetDistance(nearestPlayer.GetPosition()))
|
||||
nearestPlayer = unit;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Prioritize units with threat referenced to owner
|
||||
if (highestThreat > 0.0f && highestThreatUnit)
|
||||
me.Attack(highestThreatUnit, false);
|
||||
// If there is no such target, try to attack nearest hostile unit if such exists
|
||||
else if (nearestPlayer)
|
||||
me.Attack(nearestPlayer, false);
|
||||
}
|
||||
|
||||
bool IsInThreatList(Unit target)
|
||||
{
|
||||
Unit owner = me.GetCharmerOrOwner();
|
||||
|
||||
List<Unit> targets = new List<Unit>();
|
||||
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
|
||||
var searcher = new UnitListSearcher(me, targets, u_check);
|
||||
Cell.VisitAllObjects(me, searcher, 40.0f);
|
||||
|
||||
foreach (var unit in targets)
|
||||
{
|
||||
if (unit == target)
|
||||
{
|
||||
// Consider only units without CC
|
||||
if (!unit.HasBreakableByDamageCrowdControlAura(unit))
|
||||
{
|
||||
var triggers = unit.GetThreatManager().getThreatList();
|
||||
foreach (var reference in triggers)
|
||||
{
|
||||
// Try to find threat referenced to owner
|
||||
if (reference.getTarget() == owner)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
base.InitializeAI();
|
||||
Unit owner = me.GetOwner();
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
// here mirror image casts on summoner spell (not present in client dbc) 49866
|
||||
// here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcasted by mirror images (stats related?)
|
||||
// Clone Me!
|
||||
owner.CastSpell(me, PetMageConst.SpellCloneMe, false);
|
||||
}
|
||||
|
||||
public override void EnterCombat(Unit victim)
|
||||
{
|
||||
if (me.GetVictim() && !me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
|
||||
{
|
||||
me.CastSpell(victim, PetMageConst.SpellMageFireBlast, false);
|
||||
_events.ScheduleEvent(PetMageConst.SpellMageFrostBolt, PetMageConst.TimerMirrorImageInit);
|
||||
_events.ScheduleEvent(PetMageConst.SpellMageFireBlast, PetMageConst.TimerMirrorImageFireBlast);
|
||||
}
|
||||
else
|
||||
EnterEvadeMode(EvadeReason.Other);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.Reset();
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
Unit owner = me.GetCharmerOrOwner();
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
Unit target = owner.getAttackerForHelper();
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
// prevent CC interrupts by images
|
||||
if (me.GetVictim() && me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
|
||||
{
|
||||
me.InterruptNonMeleeSpells(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
// assign target if image doesnt have any or the target is not actual
|
||||
if (!target || me.GetVictim() != target)
|
||||
{
|
||||
Unit ownerTarget = null;
|
||||
Player owner1 = me.GetCharmerOrOwner().ToPlayer();
|
||||
if (owner1)
|
||||
ownerTarget = owner1.GetSelectedUnit();
|
||||
|
||||
// recognize which victim will be choosen
|
||||
if (ownerTarget && ownerTarget.IsTypeId(TypeId.Player))
|
||||
{
|
||||
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
|
||||
me.Attack(ownerTarget, false);
|
||||
}
|
||||
else if (ownerTarget && !ownerTarget.IsTypeId(TypeId.Player) && IsInThreatList(ownerTarget))
|
||||
{
|
||||
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
|
||||
me.Attack(ownerTarget, false);
|
||||
}
|
||||
else
|
||||
Init();
|
||||
}
|
||||
|
||||
_events.ExecuteEvents(spellId =>
|
||||
{
|
||||
if (spellId == PetMageConst.SpellMageFrostBolt)
|
||||
{
|
||||
_events.ScheduleEvent(PetMageConst.SpellMageFrostBolt, PetMageConst.TimerMirrorImageFrostBolt);
|
||||
DoCastVictim(spellId);
|
||||
}
|
||||
else if (spellId == PetMageConst.SpellMageFireBlast)
|
||||
{
|
||||
DoCastVictim(spellId);
|
||||
_events.ScheduleEvent(PetMageConst.SpellMageFireBlast, PetMageConst.TimerMirrorImageFireBlast);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Do not reload Creature templates on evade mode enter - prevent visual lost
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
if (me.IsInEvadeMode() || !me.IsAlive())
|
||||
return;
|
||||
|
||||
Unit owner = me.GetCharmerOrOwner();
|
||||
|
||||
me.CombatStop(true);
|
||||
if (owner && !me.HasUnitState(UnitState.Follow))
|
||||
{
|
||||
me.GetMotionMaster().Clear(false);
|
||||
me.GetMotionMaster().MoveFollow(owner, SharedConst.PetFollowDist, me.GetFollowAngle(), MovementSlot.Active);
|
||||
}
|
||||
Init();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
|
||||
namespace Scripts.Pets.Priest
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint GlyphOfShadowFiend = 58228;
|
||||
public const uint ShadowFiendDeath = 57989;
|
||||
public const uint LightWellCharges = 59907;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_pet_pri_lightwell : PassiveAI
|
||||
{
|
||||
public npc_pet_pri_lightwell(Creature creature) : base(creature)
|
||||
{
|
||||
DoCast(creature, SpellIds.LightWellCharges, false);
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
if (!me.IsAlive())
|
||||
return;
|
||||
|
||||
me.DeleteThreatList();
|
||||
me.CombatStop(true);
|
||||
me.ResetPlayerDamageReq();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_pet_pri_shadowfiend : PetAI
|
||||
{
|
||||
public npc_pet_pri_shadowfiend(Creature creature) : base(creature) { }
|
||||
|
||||
public override void IsSummonedBy(Unit summoner)
|
||||
{
|
||||
if (summoner.HasAura(SpellIds.GlyphOfShadowFiend))
|
||||
DoCastAOE(SpellIds.ShadowFiendDeath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.Scripting;
|
||||
|
||||
namespace Scripts.Pets
|
||||
{
|
||||
[Script]
|
||||
class npc_pet_shaman_earth_elemental : ScriptedAI
|
||||
{
|
||||
public npc_pet_shaman_earth_elemental(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EventAngeredEarth, 0);
|
||||
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Nature, true);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (_events.ExecuteEvent() == EventAngeredEarth)
|
||||
{
|
||||
DoCastVictim(SpellAngeredEarth);
|
||||
_events.ScheduleEvent(EventAngeredEarth, RandomHelper.URand(5000, 20000));
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
const int EventAngeredEarth = 1;
|
||||
const uint SpellAngeredEarth = 36213;
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class npc_pet_shaman_fire_elemental : ScriptedAI
|
||||
{
|
||||
public npc_pet_shaman_fire_elemental(Creature creature) : base(creature) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EventFireNova, RandomHelper.URand(5000, 20000));
|
||||
_events.ScheduleEvent(EventFireBlast, RandomHelper.URand(5000, 20000));
|
||||
_events.ScheduleEvent(EventFireShield, 0);
|
||||
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Fire, true);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EventFireNova:
|
||||
DoCastVictim(SpellFireNova);
|
||||
_events.ScheduleEvent(EventFireNova, RandomHelper.URand(5000, 20000));
|
||||
break;
|
||||
case EventFireShield:
|
||||
DoCastVictim(SpellFireShield);
|
||||
_events.ScheduleEvent(EventFireShield, 2000);
|
||||
break;
|
||||
case EventFireBlast:
|
||||
DoCastVictim(SpellFireBlast);
|
||||
_events.ScheduleEvent(EventFireBlast, RandomHelper.URand(5000, 20000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
const int EventFireNova = 1;
|
||||
const int EventFireShield = 2;
|
||||
const int EventFireBlast = 3;
|
||||
|
||||
const uint SpellFireBlast = 57984;
|
||||
const uint SpellFireNova = 12470;
|
||||
const uint SpellFireShield = 13376;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Game\Game.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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;
|
||||
using Game.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.DataStorage;
|
||||
|
||||
namespace Scripts.Smart
|
||||
{
|
||||
[Script]
|
||||
class SmartTrigger : AreaTriggerScript
|
||||
{
|
||||
public SmartTrigger() : base("SmartTrigger") { }
|
||||
|
||||
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
|
||||
{
|
||||
if (!player.IsAlive())
|
||||
return false;
|
||||
|
||||
Log.outDebug(LogFilter.ScriptsAi, "AreaTrigger {0} is using SmartTrigger script", trigger.Id);
|
||||
SmartScript script = new SmartScript();
|
||||
script.OnInitialize(trigger);
|
||||
script.ProcessEventsFor(SmartEvents.AreatriggerOntrigger, player, trigger.Id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class SmartScene : SceneScript
|
||||
{
|
||||
public SmartScene() : base("SmartScene") { }
|
||||
|
||||
public override void OnSceneStart(Player player, uint sceneInstanceID, SceneTemplate sceneTemplate)
|
||||
{
|
||||
SmartScript smartScript = new SmartScript();
|
||||
smartScript.OnInitialize(sceneTemplate);
|
||||
smartScript.ProcessEventsFor(SmartEvents.SceneStart, player);
|
||||
}
|
||||
|
||||
public override void OnSceneTriggerEvent(Player player, uint sceneInstanceID, SceneTemplate sceneTemplate, string triggerName)
|
||||
{
|
||||
SmartScript smartScript = new SmartScript();
|
||||
smartScript.OnInitialize(sceneTemplate);
|
||||
smartScript.ProcessEventsFor(SmartEvents.SceneTrigger, player, 0, 0, false, null, null, triggerName);
|
||||
}
|
||||
|
||||
public override void OnSceneCancel(Player player, uint sceneInstanceID, SceneTemplate sceneTemplate)
|
||||
{
|
||||
SmartScript smartScript = new SmartScript();
|
||||
smartScript.OnInitialize(sceneTemplate);
|
||||
smartScript.ProcessEventsFor(SmartEvents.SceneCancel, player);
|
||||
}
|
||||
|
||||
public override void OnSceneComplete(Player player, uint sceneInstanceID, SceneTemplate sceneTemplate)
|
||||
{
|
||||
SmartScript smartScript = new SmartScript();
|
||||
smartScript.OnInitialize(sceneTemplate);
|
||||
smartScript.ProcessEventsFor(SmartEvents.SceneComplete, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,685 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Spells.DeathKnight
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint ArmyFleshBeastTransform = 127533;
|
||||
public const uint ArmyGeistTransform = 127534;
|
||||
public const uint ArmyNorthrendSkeletonTransform = 127528;
|
||||
public const uint ArmySkeletonTransform = 127527;
|
||||
public const uint ArmySpikedGhoulTransform = 127525;
|
||||
public const uint ArmySuperZombieTransform = 127526;
|
||||
public const uint Blood = 137008;
|
||||
public const uint BloodPlague = 55078;
|
||||
public const uint BloodShieldAbsorb = 77535;
|
||||
public const uint BloodShieldMastery = 77513;
|
||||
public const uint CorpseExplosionTriggered = 43999;
|
||||
public const uint DeathAndDecayDamage = 52212;
|
||||
public const uint DeathCoilDamage = 47632;
|
||||
public const uint DeathGripDummy = 243912;
|
||||
public const uint DeathGripJump = 49575;
|
||||
public const uint DeathGripTaunt = 51399;
|
||||
public const uint DeathStrikeHeal = 45470;
|
||||
public const uint DeathStrikeOffhand = 66188;
|
||||
public const uint FesteringWound = 194310;
|
||||
public const uint Frost = 137006;
|
||||
public const uint FrostFever = 55095;
|
||||
public const uint GlyphOfFoulMenagerie = 58642;
|
||||
public const uint GlyphOfTheGeist = 58640;
|
||||
public const uint GlyphOfTheSkeleton = 146652;
|
||||
public const uint MarkOfBloodHeal = 206945;
|
||||
public const uint NecrosisEffect = 216974;
|
||||
public const uint RaiseDeadSummon = 52150;
|
||||
public const uint RecentlyUsedDeathStrike = 180612;
|
||||
public const uint RunicPowerEnergize = 49088;
|
||||
public const uint RunicReturn = 61258;
|
||||
public const uint SludgeBelcher = 207313;
|
||||
public const uint SludgeBelcherSummon = 212027;
|
||||
public const uint TighteningGrasp = 206970;
|
||||
public const uint TighteningGraspSlow = 143375;
|
||||
public const uint Unholy = 137007;
|
||||
public const uint UnholyVigor = 196263;
|
||||
public const uint VolatileShielding = 207188;
|
||||
public const uint VolatileShieldingDamage = 207194;
|
||||
|
||||
public static uint[] ArmyTransforms =
|
||||
{
|
||||
ArmyFleshBeastTransform,
|
||||
ArmyGeistTransform,
|
||||
ArmyNorthrendSkeletonTransform,
|
||||
ArmySkeletonTransform,
|
||||
ArmySpikedGhoulTransform,
|
||||
ArmySuperZombieTransform
|
||||
};
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint DancingRuneWeapon = 27893;
|
||||
}
|
||||
|
||||
[Script] // 70656 - Advantage (T10 4P Melee Bonus)
|
||||
class spell_dk_advantage_t10_4p : AuraScript
|
||||
{
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
Unit caster = eventInfo.GetActor();
|
||||
if (caster)
|
||||
{
|
||||
if (!caster.IsTypeId(TypeId.Player) || caster.GetClass() != Class.Deathknight)
|
||||
return false;
|
||||
|
||||
for (byte i = 0; i < PlayerConst.MaxRunes; ++i)
|
||||
if (caster.ToPlayer().GetRuneCooldown(i) == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 48707 - Anti-Magic Shell
|
||||
class spell_dk_anti_magic_shell : AuraScript
|
||||
{
|
||||
public spell_dk_anti_magic_shell()
|
||||
{
|
||||
absorbPct = 0;
|
||||
maxHealth = 0;
|
||||
absorbedAmount = 0;
|
||||
}
|
||||
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.RunicPowerEnergize, SpellIds.VolatileShielding);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
absorbPct = GetSpellInfo().GetEffect(1).CalcValue(GetCaster());
|
||||
maxHealth = (int)GetCaster().GetMaxHealth();
|
||||
absorbedAmount = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
amount = MathFunctions.CalculatePct(maxHealth, absorbPct);
|
||||
}
|
||||
|
||||
void Trigger(AuraEffect aurEff, DamageInfo dmgInfo, ref uint absorbAmount)
|
||||
{
|
||||
absorbedAmount += absorbAmount;
|
||||
|
||||
if (!GetTarget().HasAura(SpellIds.VolatileShielding))
|
||||
{
|
||||
int bp = (int)(2 * absorbAmount * 100 / maxHealth);
|
||||
GetTarget().CastCustomSpell(SpellIds.RunicPowerEnergize, SpellValueMod.BasePoint0, bp, GetTarget(), true, null, aurEff);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
AuraEffect volatileShielding = GetTarget().GetAuraEffect(SpellIds.VolatileShielding, 1);
|
||||
if (volatileShielding != null)
|
||||
{
|
||||
int damage = (int)MathFunctions.CalculatePct(absorbedAmount, volatileShielding.GetAmount());
|
||||
GetTarget().CastCustomSpell(SpellIds.VolatileShieldingDamage, SpellValueMod.BasePoint0, damage, null, TriggerCastFlags.FullMask, null, volatileShielding);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.SchoolAbsorb));
|
||||
AfterEffectAbsorb.Add(new EffectAbsorbHandler(Trigger, 0));
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.SchoolAbsorb, AuraEffectHandleModes.Real));
|
||||
}
|
||||
|
||||
int absorbPct;
|
||||
int maxHealth;
|
||||
uint absorbedAmount;
|
||||
}
|
||||
|
||||
[Script] // 127517 - Army Transform // 6.x, does this belong here or in spell_generic? where do we cast this? sniffs say this is only cast when caster has glyph of foul menagerie.
|
||||
class spell_dk_army_transform : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.GlyphOfFoulMenagerie);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsGuardian();
|
||||
}
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit owner = GetCaster().GetOwner();
|
||||
if (owner)
|
||||
if (owner.HasAura(SpellIds.GlyphOfFoulMenagerie))
|
||||
return SpellCastResult.SpellCastOk;
|
||||
|
||||
return SpellCastResult.SpellUnavailable;
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
GetCaster().CastSpell(GetCaster(), SpellIds.ArmyTransforms.SelectRandom(), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 50842 - Blood Boil
|
||||
class spell_dk_blood_boil : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.BloodPlague);
|
||||
}
|
||||
|
||||
void HandleEffect()
|
||||
{
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.BloodPlague, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnHit.Add(new HitHandler(HandleEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 49028 - Dancing Rune Weapon 7.1.5
|
||||
class spell_dk_dancing_rune_weapon : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
if (Global.ObjectMgr.GetCreatureTemplate(CreatureIds.DancingRuneWeapon) == null)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is a port of the old switch hack in Unit.cpp, it's not correct
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
Unit drw = null;
|
||||
foreach (Unit controlled in caster.m_Controlled)
|
||||
{
|
||||
if (controlled.GetEntry() == CreatureIds.DancingRuneWeapon)
|
||||
{
|
||||
drw = controlled;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!drw || !drw.GetVictim())
|
||||
return;
|
||||
|
||||
SpellInfo spellInfo = eventInfo.GetSpellInfo();
|
||||
if (spellInfo == null)
|
||||
return;
|
||||
|
||||
DamageInfo damageInfo = eventInfo.GetDamageInfo();
|
||||
if (damageInfo == null || damageInfo.GetDamage() == 0)
|
||||
return;
|
||||
|
||||
int amount = (int)(damageInfo.GetDamage() / 2);
|
||||
SpellNonMeleeDamage log = new SpellNonMeleeDamage(drw, drw.GetVictim(), spellInfo.Id, spellInfo.GetSpellXSpellVisualId(drw), spellInfo.GetSchoolMask());
|
||||
log.damage = (uint)amount;
|
||||
drw.DealDamage(drw.GetVictim(), (uint)amount, null, DamageEffectType.Direct, spellInfo.GetSchoolMask(), spellInfo, true);
|
||||
drw.SendSpellNonMeleeDamageLog(log);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 1, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 43265 - Death and Decay
|
||||
class spell_dk_death_and_decay : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.TighteningGrasp, SpellIds.TighteningGraspSlow);
|
||||
}
|
||||
|
||||
void HandleDummy()
|
||||
{
|
||||
if (GetCaster().HasAura(SpellIds.TighteningGrasp))
|
||||
{
|
||||
Position pos = GetExplTargetDest();
|
||||
if (pos != null)
|
||||
GetCaster().CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SpellIds.TighteningGraspSlow, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCast.Add(new CastHandler(HandleDummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_dk_death_and_decay_AuraScript: AuraScript
|
||||
{
|
||||
void HandleDummyTick(AuraEffect aurEff)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
caster.CastSpell(GetTarget(), SpellIds.DeathAndDecayDamage, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleDummyTick, 2, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 47541 - Death Coil
|
||||
class spell_dk_death_coil : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.DeathCoilDamage, SpellIds.Unholy, SpellIds.UnholyVigor);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
caster.CastSpell(GetHitUnit(), SpellIds.DeathCoilDamage, true);
|
||||
|
||||
AuraEffect unholyAura = caster.GetAuraEffect(SpellIds.Unholy, 6);
|
||||
if (unholyAura != null) // can be any effect, just here to send SPELL_FAILED_DONT_REPORT on failure
|
||||
caster.CastSpell(caster, SpellIds.UnholyVigor, true, null, unholyAura);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 52751 - Death Gate
|
||||
class spell_dk_death_gate : SpellScript
|
||||
{
|
||||
SpellCastResult CheckClass()
|
||||
{
|
||||
if (GetCaster().GetClass() != Class.Deathknight)
|
||||
{
|
||||
SetCustomCastResultMessage(SpellCustomErrors.MustBeDeathKnight);
|
||||
return SpellCastResult.CustomError;
|
||||
}
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
target.CastSpell(target, (uint)GetEffectValue(), false);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckClass));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] //49576 - Death Grip Initial
|
||||
class spell_dk_death_grip_initial : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.DeathGripDummy, SpellIds.DeathGripJump, SpellIds.Blood, SpellIds.DeathGripTaunt);
|
||||
}
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
// Death Grip should not be castable while jumping/falling
|
||||
if (caster.HasUnitState(UnitState.Jumping) || caster.HasUnitMovementFlag(MovementFlag.Falling))
|
||||
return SpellCastResult.Moving;
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.DeathGripDummy, true);
|
||||
GetHitUnit().CastSpell(GetCaster(), SpellIds.DeathGripJump, true);
|
||||
if (GetCaster().HasAura(SpellIds.Blood))
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.DeathGripTaunt, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 48743 - Death Pact
|
||||
class spell_dk_death_pact : AuraScript
|
||||
{
|
||||
void HandleCalcAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
amount = (int)caster.CountPctFromMaxHealth(amount);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(HandleCalcAmount, 1, AuraType.SchoolHealAbsorb));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 49998 - Death Strike
|
||||
class spell_dk_death_strike : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.DeathStrikeHeal, SpellIds.BloodShieldMastery, SpellIds.BloodShieldAbsorb,
|
||||
SpellIds.RecentlyUsedDeathStrike, SpellIds.Frost, SpellIds.DeathStrikeOffhand);
|
||||
}
|
||||
|
||||
void HandleHeal(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
//TODO: heal = std::min(10% health, 20% of all damage taken in last 5 seconds)
|
||||
int heal = (int)MathFunctions.CalculatePct(caster.GetMaxHealth(), GetSpellInfo().GetEffect(4).CalcValue());
|
||||
caster.CastCustomSpell(SpellIds.DeathStrikeHeal, SpellValueMod.BasePoint0, heal, caster, true);
|
||||
|
||||
AuraEffect aurEff = caster.GetAuraEffect(SpellIds.BloodShieldMastery, 0);
|
||||
if (aurEff != null)
|
||||
caster.CastCustomSpell(SpellIds.BloodShieldAbsorb, SpellValueMod.BasePoint0, MathFunctions.CalculatePct(heal, aurEff.GetAmount()), caster);
|
||||
|
||||
if (caster.HasAura(SpellIds.Frost))
|
||||
caster.CastSpell(GetHitUnit(), SpellIds.DeathStrikeOffhand, true);
|
||||
}
|
||||
|
||||
void TriggerRecentlyUsedDeathStrike()
|
||||
{
|
||||
GetCaster().CastSpell(GetCaster(), SpellIds.RecentlyUsedDeathStrike, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleHeal, 1, SpellEffectName.WeaponPercentDamage));
|
||||
AfterCast.Add(new CastHandler(TriggerRecentlyUsedDeathStrike));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 85948 - Festering Strike
|
||||
class spell_dk_festering_strike : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.FesteringWound);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
GetCaster().CastCustomSpell(SpellIds.FesteringWound, SpellValueMod.AuraStack, GetEffectValue(), GetHitUnit(), TriggerCastFlags.FullMask);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 2, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 47496 - Explode, Ghoul spell for Corpse Explosion
|
||||
class spell_dk_ghoul_explode : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.CorpseExplosionTriggered);
|
||||
}
|
||||
|
||||
void HandleDamage(uint effIndex)
|
||||
{
|
||||
SetHitDamage((int)GetCaster().CountPctFromMaxHealth(GetEffectInfo(2).CalcValue(GetCaster())));
|
||||
}
|
||||
|
||||
void Suicide(uint effIndex)
|
||||
{
|
||||
Unit unitTarget = GetHitUnit();
|
||||
if (unitTarget)
|
||||
{
|
||||
// Corpse Explosion (Suicide)
|
||||
unitTarget.CastSpell(unitTarget, SpellIds.CorpseExplosionTriggered, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDamage, 0, SpellEffectName.SchoolDamage));
|
||||
OnEffectHitTarget.Add(new EffectHandler(Suicide, 1, SpellEffectName.SchoolDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 206940 - Mark of Blood
|
||||
class spell_dk_mark_of_blood : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.MarkOfBloodHeal);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
caster.CastSpell(eventInfo.GetProcTarget(), SpellIds.MarkOfBloodHeal, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 207346 - Necrosis
|
||||
class spell_dk_necrosis : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.NecrosisEffect);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastSpell(eventInfo.GetProcTarget(), SpellIds.NecrosisEffect, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 121916 - Glyph of the Geist (Unholy) // 6.x, does this belong here or in spell_generic? apply this in creature_template_addon? sniffs say this is always cast on raise dead.
|
||||
class spell_dk_pet_geist_transform : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.GlyphOfTheGeist);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsPet();
|
||||
}
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit owner = GetCaster().GetOwner();
|
||||
if (owner)
|
||||
if (owner.HasAura(SpellIds.GlyphOfTheGeist))
|
||||
return SpellCastResult.SpellCastOk;
|
||||
|
||||
return SpellCastResult.SpellUnavailable;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 147157 Glyph of the Skeleton (Unholy) // 6.x, does this belong here or in spell_generic? apply this in creature_template_addon? sniffs say this is always cast on raise dead.
|
||||
class spell_dk_pet_skeleton_transform : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.GlyphOfTheSkeleton);
|
||||
}
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit owner = GetCaster().GetOwner();
|
||||
if (owner)
|
||||
if (owner.HasAura(SpellIds.GlyphOfTheSkeleton))
|
||||
return SpellCastResult.SpellCastOk;
|
||||
|
||||
return SpellCastResult.SpellUnavailable;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 61257 - Runic Power Back on Snare/Root 7.1.5
|
||||
class spell_dk_pvp_4p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.RunicReturn);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
SpellInfo spellInfo = eventInfo.GetSpellInfo();
|
||||
if (spellInfo == null)
|
||||
return false;
|
||||
|
||||
return (spellInfo.GetAllEffectsMechanicMask() & ((1 << (int)Mechanics.Root) | (1 << (int)Mechanics.Snare))) != 0;
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
eventInfo.GetActionTarget().CastSpell((Unit)null, SpellIds.RunicReturn, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 46584 - Raise Dead
|
||||
class spell_dk_raise_dead : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.RaiseDeadSummon, SpellIds.SludgeBelcher, SpellIds.SludgeBelcherSummon);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
uint spellId = SpellIds.RaiseDeadSummon;
|
||||
if (GetCaster().HasAura(SpellIds.SludgeBelcher))
|
||||
spellId = SpellIds.SludgeBelcherSummon;
|
||||
|
||||
GetCaster().CastSpell((Unit)null, spellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 115994 - Unholy Blight
|
||||
class spell_dk_unholy_blight : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.FrostFever, SpellIds.BloodPlague);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.FrostFever, true);
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.BloodPlague, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 55233 - Vampiric Blood
|
||||
class spell_dk_vampiric_blood : AuraScript
|
||||
{
|
||||
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
amount = (int)GetUnitOwner().CountPctFromMaxHealth(amount);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 1, AuraType.ModIncreaseHealth2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Scripts.Spells
|
||||
{
|
||||
class DemonHunter
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,900 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Scripts.Spells.Druid
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint BalanceT10Bonus = 70718;
|
||||
public const uint BalanceT10BonusProc = 70721;
|
||||
public const uint BlessingOfTheClaw = 28750;
|
||||
public const uint BlessingOfTheRemulos = 40445;
|
||||
public const uint BlessingOfTheElune = 40446;
|
||||
public const uint BlessingOfTheCenarius = 40452;
|
||||
public const uint Exhilarate = 28742;
|
||||
public const uint FeralChargeBear = 16979;
|
||||
public const uint FeralChargeCat = 49376;
|
||||
public const uint FormsTrinketBear = 37340;
|
||||
public const uint FormsTrinketCat = 37341;
|
||||
public const uint FormsTrinketMoonkin = 37343;
|
||||
public const uint FormsTrinketNone = 37344;
|
||||
public const uint FormsTrinketTree = 37342;
|
||||
public const uint IdolOfFeralShadows = 34241;
|
||||
public const uint IdolOfWorship = 60774;
|
||||
public const uint Infusion = 37238;
|
||||
public const uint Languish = 71023;
|
||||
public const uint LifebloomEnergize = 64372;
|
||||
public const uint LifebloomFinalHeal = 33778;
|
||||
public const uint LivingSeedHeal = 48503;
|
||||
public const uint LivingSeedProc = 48504;
|
||||
public const uint MoonfireDamage = 164812;
|
||||
public const uint RejuvenationT10Proc = 70691;
|
||||
public const uint SavageRoar = 62071;
|
||||
public const uint StampedeBearRank1 = 81016;
|
||||
public const uint StampedeCatRank1 = 81021;
|
||||
public const uint StampedeCatState = 109881;
|
||||
public const uint SunfireDamage = 164815;
|
||||
public const uint SurvivalInstincts = 50322;
|
||||
}
|
||||
|
||||
[Script] // 1850 - Dash
|
||||
public class spell_dru_dash : AuraScript
|
||||
{
|
||||
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
// do not set speed if not in cat form
|
||||
if (GetUnitOwner().GetShapeshiftForm() != ShapeShiftForm.CatForm)
|
||||
amount = 0;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.ModIncreaseSpeed));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 33943 - Flight Form
|
||||
class spell_dru_flight_form : SpellScript
|
||||
{
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster.IsInDisallowedMountForm())
|
||||
return SpellCastResult.NotShapeshift;
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 37336 - Druid Forms Trinket
|
||||
class spell_dru_forms_trinket : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.FormsTrinketBear, SpellIds.FormsTrinketCat, SpellIds.FormsTrinketMoonkin, SpellIds.FormsTrinketNone, SpellIds.FormsTrinketTree);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
Unit target = eventInfo.GetActor();
|
||||
|
||||
switch (target.GetShapeshiftForm())
|
||||
{
|
||||
case ShapeShiftForm.BearForm:
|
||||
case ShapeShiftForm.DireBearForm:
|
||||
case ShapeShiftForm.CatForm:
|
||||
case ShapeShiftForm.MoonkinForm:
|
||||
case ShapeShiftForm.None:
|
||||
case ShapeShiftForm.TreeOfLife:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit target = eventInfo.GetActor();
|
||||
uint triggerspell = 0;
|
||||
|
||||
switch (target.GetShapeshiftForm())
|
||||
{
|
||||
case ShapeShiftForm.BearForm:
|
||||
case ShapeShiftForm.DireBearForm:
|
||||
triggerspell = SpellIds.FormsTrinketBear;
|
||||
break;
|
||||
case ShapeShiftForm.CatForm:
|
||||
triggerspell = SpellIds.FormsTrinketCat;
|
||||
break;
|
||||
case ShapeShiftForm.MoonkinForm:
|
||||
triggerspell = SpellIds.FormsTrinketMoonkin;
|
||||
break;
|
||||
case ShapeShiftForm.None:
|
||||
triggerspell = SpellIds.FormsTrinketNone;
|
||||
break;
|
||||
case ShapeShiftForm.TreeOfLife:
|
||||
triggerspell = SpellIds.FormsTrinketTree;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
target.CastSpell(target, triggerspell, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
// 34246 - Idol of the Emerald Queen
|
||||
[Script] // 60779 - Idol of Lush Moss
|
||||
class spell_dru_idol_lifebloom : AuraScript
|
||||
{
|
||||
void HandleEffectCalcSpellMod(AuraEffect aurEff, ref SpellModifier spellMod)
|
||||
{
|
||||
if (spellMod == null)
|
||||
{
|
||||
spellMod = new SpellModifier(GetAura());
|
||||
spellMod.op = SpellModOp.Dot;
|
||||
spellMod.type = SpellModType.Flat;
|
||||
spellMod.spellId = GetId();
|
||||
spellMod.mask = GetSpellInfo().GetEffect(aurEff.GetEffIndex()).SpellClassMask;
|
||||
}
|
||||
spellMod.value = aurEff.GetAmount() / 7;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcSpellMod.Add(new EffectCalcSpellModHandler(HandleEffectCalcSpellMod, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 29166 - Innervate
|
||||
[Script]
|
||||
class spell_dru_innervate : AuraScript
|
||||
{
|
||||
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
amount = MathFunctions.CalculatePct(caster.GetCreatePowers(PowerType.Mana), amount) / aurEff.GetTotalTicks();
|
||||
else
|
||||
amount = 0;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.PeriodicEnergize));
|
||||
}
|
||||
}
|
||||
|
||||
// 33763 - Lifebloom
|
||||
[Script]
|
||||
class spell_dru_lifebloom : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LifebloomFinalHeal, SpellIds.LifebloomEnergize);
|
||||
}
|
||||
|
||||
void AfterRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
// Final heal only on duration end
|
||||
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Expire)
|
||||
return;
|
||||
|
||||
// final heal
|
||||
uint stack = GetStackAmount();
|
||||
uint healAmount = (uint)aurEff.GetAmount();
|
||||
Unit caster = GetCaster();
|
||||
if (caster != null)
|
||||
{
|
||||
healAmount = caster.SpellHealingBonusDone(GetTarget(), GetSpellInfo(), healAmount, DamageEffectType.Heal, aurEff.GetSpellEffectInfo(), stack);
|
||||
healAmount = GetTarget().SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, DamageEffectType.Heal, aurEff.GetSpellEffectInfo(), stack);
|
||||
|
||||
GetTarget().CastCustomSpell(GetTarget(), SpellIds.LifebloomFinalHeal, (int)healAmount, 0, 0, true, null, aurEff, GetCasterGUID());
|
||||
|
||||
// restore mana
|
||||
var costs = GetSpellInfo().CalcPowerCost(caster, GetSpellInfo().GetSchoolMask());
|
||||
var m = costs.Find(cost => cost.Power == PowerType.Mana);
|
||||
if (m != null)
|
||||
{
|
||||
int returnMana = m.Amount * (int)stack / 2;
|
||||
caster.CastCustomSpell(caster, SpellIds.LifebloomEnergize, returnMana, 0, 0, true, null, aurEff, GetCasterGUID());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
GetTarget().CastCustomSpell(GetTarget(), SpellIds.LifebloomFinalHeal, (int)healAmount, 0, 0, true, null, aurEff, GetCasterGUID());
|
||||
}
|
||||
|
||||
void HandleDispel(DispelInfo dispelInfo)
|
||||
{
|
||||
Unit target = GetUnitOwner();
|
||||
if (target != null)
|
||||
{
|
||||
AuraEffect aurEff = GetEffect(1);
|
||||
if (aurEff != null)
|
||||
{
|
||||
// final heal
|
||||
uint healAmount = (uint)aurEff.GetAmount();
|
||||
Unit caster = GetCaster();
|
||||
if (caster != null)
|
||||
{
|
||||
healAmount = caster.SpellHealingBonusDone(target, GetSpellInfo(), healAmount, DamageEffectType.Heal, aurEff.GetSpellEffectInfo(), dispelInfo.GetRemovedCharges());
|
||||
healAmount = target.SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, DamageEffectType.Heal, aurEff.GetSpellEffectInfo(), dispelInfo.GetRemovedCharges());
|
||||
target.CastCustomSpell(target, SpellIds.LifebloomFinalHeal, (int)healAmount, 0, 0, true, null, null, GetCasterGUID());
|
||||
|
||||
// restore mana
|
||||
var costs = GetSpellInfo().CalcPowerCost(caster, GetSpellInfo().GetSchoolMask());
|
||||
var m = costs.Find(cost => cost.Power == PowerType.Mana);
|
||||
if (m != null)
|
||||
{
|
||||
int returnMana = m.Amount * dispelInfo.GetRemovedCharges() / 2;
|
||||
caster.CastCustomSpell(caster, SpellIds.LifebloomEnergize, returnMana, 0, 0, true, null, null, GetCasterGUID());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
target.CastCustomSpell(target, SpellIds.LifebloomFinalHeal, (int)healAmount, 0, 0, true, null, null, GetCasterGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 1, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
AfterDispel.Add(new AuraDispelHandler(HandleDispel));
|
||||
}
|
||||
}
|
||||
|
||||
// 48496 - Living Seed
|
||||
[Script]
|
||||
class spell_dru_living_seed : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LivingSeedProc);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
int amount = (int)MathFunctions.CalculatePct(eventInfo.GetHealInfo().GetHeal(), aurEff.GetAmount());
|
||||
GetTarget().CastCustomSpell(SpellIds.LivingSeedProc, SpellValueMod.BasePoint0, amount, eventInfo.GetProcTarget(), true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 48504 - Living Seed (Proc)
|
||||
[Script]
|
||||
class spell_dru_living_seed_proc : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LivingSeedHeal);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastCustomSpell(SpellIds.LivingSeedHeal, SpellValueMod.BasePoint0, aurEff.GetAmount(), GetTarget(), true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 8921 - Moonfire
|
||||
class spell_dru_moonfire : SpellScript
|
||||
{
|
||||
void HandleOnHit(uint effIndex)
|
||||
{
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.MoonfireDamage, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleOnHit, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 16972 - Predatory Strikes
|
||||
[Script]
|
||||
class spell_dru_predatory_strikes : AuraScript
|
||||
{
|
||||
void UpdateAmount(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Player target = GetTarget().ToPlayer();
|
||||
if (target != null)
|
||||
target.UpdateAttackPowerAndDamage();
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(UpdateAmount, SpellConst.EffectAll, AuraType.Dummy, AuraEffectHandleModes.ChangeAmountMask));
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(UpdateAmount, SpellConst.EffectAll, AuraType.Dummy, AuraEffectHandleModes.ChangeAmountMask));
|
||||
}
|
||||
}
|
||||
|
||||
// 1079 - Rip
|
||||
[Script]
|
||||
class spell_dru_rip : AuraScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
return caster != null && caster.IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
canBeRecalculated = false;
|
||||
|
||||
Unit caster = GetCaster();
|
||||
if (caster != null)
|
||||
{
|
||||
// 0.01 * $AP * cp
|
||||
byte cp = caster.ToPlayer().GetComboPoints();
|
||||
|
||||
// Idol of Feral Shadows. Can't be handled as SpellMod due its dependency from CPs
|
||||
AuraEffect idol = caster.GetAuraEffect(SpellIds.IdolOfFeralShadows, 0);
|
||||
if (idol != null)
|
||||
amount += cp * idol.GetAmount();
|
||||
// Idol of Worship. Can't be handled as SpellMod due its dependency from CPs
|
||||
else if ((idol = caster.GetAuraEffect(SpellIds.IdolOfWorship, 0)) != null)
|
||||
amount += cp * idol.GetAmount();
|
||||
|
||||
amount += (int)MathFunctions.CalculatePct(caster.GetTotalAttackPowerValue(WeaponAttackType.BaseAttack), cp);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.PeriodicDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 16864 - Omen of Clarity
|
||||
class spell_dru_omen_of_clarity : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.BalanceT10Bonus, SpellIds.BalanceT10BonusProc);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
if (target.HasAura(SpellIds.BalanceT10Bonus))
|
||||
target.CastSpell((Unit)null, SpellIds.BalanceT10BonusProc, true, null);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
// 52610 - Savage Roar
|
||||
[Script]
|
||||
class spell_dru_savage_roar : SpellScript
|
||||
{
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster.GetShapeshiftForm() != ShapeShiftForm.CatForm)
|
||||
return SpellCastResult.OnlyShapeshift;
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_dru_savage_roar_AuraScript : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SavageRoar);
|
||||
}
|
||||
|
||||
void AfterApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
target.CastSpell(target, SpellIds.SavageRoar, true, null, aurEff, GetCasterGUID());
|
||||
}
|
||||
|
||||
void AfterRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().RemoveAurasDueToSpell(SpellIds.SavageRoar);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(AfterApply, 1, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 1, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 78892 - Stampede
|
||||
class spell_dru_stampede : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.StampedeBearRank1, SpellIds.StampedeCatRank1, SpellIds.StampedeCatState, SpellIds.FeralChargeCat, SpellIds.FeralChargeBear);
|
||||
}
|
||||
|
||||
void HandleEffectCatProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (GetTarget().GetShapeshiftForm() != ShapeShiftForm.CatForm || eventInfo.GetDamageInfo().GetSpellInfo().Id != SpellIds.FeralChargeCat)
|
||||
return;
|
||||
|
||||
GetTarget().CastSpell(GetTarget(), Global.SpellMgr.GetSpellWithRank(SpellIds.StampedeCatRank1, GetSpellInfo().GetRank()), true, null, aurEff);
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.StampedeCatState, true, null, aurEff);
|
||||
}
|
||||
|
||||
void HandleEffectBearProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (GetTarget().GetShapeshiftForm() != ShapeShiftForm.BearForm || eventInfo.GetDamageInfo().GetSpellInfo().Id != SpellIds.FeralChargeBear)
|
||||
return;
|
||||
|
||||
GetTarget().CastSpell(GetTarget(), Global.SpellMgr.GetSpellWithRank(SpellIds.StampedeBearRank1, GetSpellInfo().GetRank()), true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectCatProc, 0, AuraType.Dummy));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectBearProc, 1, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 50286 - Starfall (Dummy)
|
||||
[Script]
|
||||
class spell_dru_starfall_dummy : SpellScript
|
||||
{
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.Resize(2);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
// Shapeshifting into an animal form or mounting cancels the effect
|
||||
if (caster.GetCreatureType() == CreatureType.Beast || caster.IsMounted())
|
||||
{
|
||||
SpellInfo spellInfo = GetTriggeringSpell();
|
||||
if (spellInfo != null)
|
||||
caster.RemoveAurasDueToSpell(spellInfo.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
// Any effect which causes you to lose control of your character will supress the starfall effect.
|
||||
if (caster.HasUnitState(UnitState.Controlled))
|
||||
return;
|
||||
|
||||
caster.CastSpell(GetHitUnit(), (uint)GetEffectValue(), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEnemy));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 93402 - Sunfire
|
||||
class spell_dru_sunfire : SpellScript
|
||||
{
|
||||
void HandleOnHit(uint effIndex)
|
||||
{
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.SunfireDamage, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleOnHit, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 61336 - Survival Instincts
|
||||
[Script]
|
||||
class spell_dru_survival_instincts : SpellScript
|
||||
{
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (!caster.IsInFeralForm())
|
||||
return SpellCastResult.OnlyShapeshift;
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_dru_survival_instincts_AuraScript : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SurvivalInstincts);
|
||||
}
|
||||
|
||||
void AfterApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
int bp0 = (int)target.CountPctFromMaxHealth(aurEff.GetAmount());
|
||||
target.CastCustomSpell(target, SpellIds.SurvivalInstincts, bp0, 0, 0, true);
|
||||
}
|
||||
|
||||
void AfterRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().RemoveAurasDueToSpell(SpellIds.SurvivalInstincts);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(AfterApply, 0, AuraType.Dummy, AuraEffectHandleModes.ChangeAmountMask));
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 0, AuraType.Dummy, AuraEffectHandleModes.ChangeAmountMask));
|
||||
}
|
||||
}
|
||||
|
||||
// 40121 - Swift Flight Form (Passive)
|
||||
[Script]
|
||||
class spell_dru_swift_flight_passive : AuraScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
Player caster = GetCaster().ToPlayer();
|
||||
if (caster != null)
|
||||
if (caster.GetSkillValue(SkillType.Riding) >= 375)
|
||||
amount = 310;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 1, AuraType.ModIncreaseVehicleFlightSpeed));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 28744 - Regrowth
|
||||
class spell_dru_t3_6p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.BlessingOfTheClaw);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
eventInfo.GetActor().CastSpell(eventInfo.GetProcTarget(), SpellIds.BlessingOfTheClaw, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.OverrideClassScripts));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 28719 - Healing Touch
|
||||
class spell_dru_t3_8p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Exhilarate);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Spell spell = eventInfo.GetProcSpell();
|
||||
if (spell == null)
|
||||
return;
|
||||
|
||||
Unit caster = eventInfo.GetActor();
|
||||
var costs = spell.GetPowerCost();
|
||||
var m = costs.First(cost => { return cost.Power == PowerType.Mana; });
|
||||
if (m == null)
|
||||
return;
|
||||
|
||||
int amount = MathFunctions.CalculatePct(m.Amount, aurEff.GetAmount());
|
||||
caster.CastCustomSpell(SpellIds.Exhilarate, SpellValueMod.BasePoint0, amount, (Unit)null, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 37288 - Mana Restore
|
||||
[Script] // 37295 - Mana Restore
|
||||
class spell_dru_t4_2p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Infusion);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
eventInfo.GetActor().CastSpell((Unit)null, SpellIds.Infusion, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 40442 - Druid Tier 6 Trinket
|
||||
class spell_dru_item_t6_trinket : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.BlessingOfTheRemulos, SpellIds.BlessingOfTheElune, SpellIds.BlessingOfTheCenarius);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
SpellInfo spellInfo = eventInfo.GetSpellInfo();
|
||||
if (spellInfo == null)
|
||||
return;
|
||||
|
||||
uint spellId;
|
||||
int chance;
|
||||
|
||||
// Starfire
|
||||
if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00000004u))
|
||||
{
|
||||
spellId = SpellIds.BlessingOfTheRemulos;
|
||||
chance = 25;
|
||||
}
|
||||
// Rejuvenation
|
||||
else if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00000010u))
|
||||
{
|
||||
spellId = SpellIds.BlessingOfTheElune;
|
||||
chance = 25;
|
||||
}
|
||||
// Mangle (Bear) and Mangle (Cat)
|
||||
else if (spellInfo.SpellFamilyFlags[1].HasAnyFlag(0x00000440u))
|
||||
{
|
||||
spellId = SpellIds.BlessingOfTheCenarius;
|
||||
chance = 40;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if (RandomHelper.randChance(chance))
|
||||
eventInfo.GetActor().CastSpell((Unit)null, spellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 70723 - Item - Druid T10 Balance 4P Bonus
|
||||
class spell_dru_t10_balance_4p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Languish);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
DamageInfo damageInfo = eventInfo.GetDamageInfo();
|
||||
if (damageInfo == null || damageInfo.GetDamage() == 0)
|
||||
return;
|
||||
|
||||
Unit caster = eventInfo.GetActor();
|
||||
Unit target = eventInfo.GetProcTarget();
|
||||
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.Languish);
|
||||
int amount = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount());
|
||||
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
|
||||
// Add remaining ticks to damage done
|
||||
amount += (int)target.GetRemainingPeriodicAmount(caster.GetGUID(), SpellIds.Languish, AuraType.PeriodicDamage);
|
||||
|
||||
caster.CastCustomSpell(SpellIds.Languish, SpellValueMod.BasePoint0, amount, target, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 70691 - Item T10 Restoration 4P Bonus
|
||||
[Script]
|
||||
class spell_dru_t10_restoration_4p_bonus : SpellScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
if (GetCaster().ToPlayer().GetGroup() == null)
|
||||
{
|
||||
targets.Clear();
|
||||
targets.Add(GetCaster());
|
||||
}
|
||||
else
|
||||
{
|
||||
targets.Remove(GetExplTargetUnit());
|
||||
List<Unit> tempTargets = new List<Unit>();
|
||||
foreach (var obj in targets)
|
||||
if (obj.IsTypeId(TypeId.Player) && GetCaster().IsInRaidWith(obj.ToUnit()))
|
||||
tempTargets.Add(obj.ToUnit());
|
||||
|
||||
if (tempTargets.Empty())
|
||||
{
|
||||
targets.Clear();
|
||||
FinishCast(SpellCastResult.DontReport);
|
||||
return;
|
||||
}
|
||||
|
||||
Unit target = tempTargets.SelectRandom();
|
||||
targets.Clear();
|
||||
targets.Add(target);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaAlly));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 70664 - Druid T10 Restoration 4P Bonus (Rejuvenation)
|
||||
class spell_dru_t10_restoration_4p_bonus_dummy : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.RejuvenationT10Proc);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
SpellInfo spellInfo = eventInfo.GetSpellInfo();
|
||||
if (spellInfo == null || spellInfo.Id == SpellIds.RejuvenationT10Proc)
|
||||
return false;
|
||||
|
||||
HealInfo healInfo = eventInfo.GetHealInfo();
|
||||
if (healInfo == null || healInfo.GetHeal() == 0)
|
||||
return false;
|
||||
|
||||
Player caster = eventInfo.GetActor().ToPlayer();
|
||||
if (!caster)
|
||||
return false;
|
||||
|
||||
return caster.GetGroup() || caster != eventInfo.GetProcTarget();
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
int amount = (int)eventInfo.GetHealInfo().GetHeal();
|
||||
eventInfo.GetActor().CastCustomSpell(SpellIds.RejuvenationT10Proc, SpellValueMod.BasePoint0, amount, (Unit)null, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 48438 - Wild Growth
|
||||
class spell_dru_wild_growth : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
SpellEffectInfo effect2 = spellInfo.GetEffect(2);
|
||||
if (effect2 == null || effect2.IsEffect() || effect2.CalcValue() <= 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.RemoveAll(obj =>
|
||||
{
|
||||
Unit target = obj.ToUnit();
|
||||
if (target)
|
||||
return !GetCaster().IsInRaidWith(target);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
int maxTargets = GetSpellInfo().GetEffect(2).CalcValue(GetCaster());
|
||||
|
||||
if (targets.Count > maxTargets)
|
||||
{
|
||||
targets.Sort(new HealthPctOrderPred());
|
||||
targets.RemoveRange(maxTargets, targets.Count - maxTargets);
|
||||
}
|
||||
|
||||
_targets = targets;
|
||||
}
|
||||
|
||||
void SetTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.Clear();
|
||||
targets.AddRange(_targets);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaAlly));
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(SetTargets, 1, Targets.UnitDestAreaAlly));
|
||||
}
|
||||
|
||||
List<WorldObject> _targets;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,788 @@
|
||||
/*
|
||||
* 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;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Spells.Holiday
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
//Romantic Picnic
|
||||
public const uint BasketCheck = 45119; // Holiday - Valentine - Romantic Picnic Near Basket Check
|
||||
public const uint MealPeriodic = 45103; // Holiday - Valentine - Romantic Picnic Meal Periodic - Effect Dummy
|
||||
public const uint MealEatVisual = 45120; // Holiday - Valentine - Romantic Picnic Meal Eat Visual
|
||||
//public const uint MealParticle = 45114; // Holiday - Valentine - Romantic Picnic Meal Particle - Unused
|
||||
public const uint DrinkVisual = 45121; // Holiday - Valentine - Romantic Picnic Drink Visual
|
||||
public const uint RomanticPicnicAchiev = 45123; // Romantic Picnic Periodic = 5000
|
||||
|
||||
//Trickspells
|
||||
public const uint PirateCostumeMale = 24708;
|
||||
public const uint PirateCostumeFemale = 24709;
|
||||
public const uint NinjaCostumeMale = 24710;
|
||||
public const uint NinjaCostumeFemale = 24711;
|
||||
public const uint LeperGnomeCostumeMale = 24712;
|
||||
public const uint LeperGnomeCostumeFemale = 24713;
|
||||
public const uint SkeletonCostume = 24723;
|
||||
public const uint GhostCostumeMale = 24735;
|
||||
public const uint GhostCostumeFemale = 24736;
|
||||
public const uint TrickBuff = 24753;
|
||||
|
||||
//Trickortreatspells
|
||||
public const uint Trick = 24714;
|
||||
public const uint Treat = 24715;
|
||||
public const uint TrickedOrTreated = 24755;
|
||||
public const uint TrickyTreatSpeed = 42919;
|
||||
public const uint TrickyTreatTrigger = 42965;
|
||||
public const uint UpsetTummy = 42966;
|
||||
|
||||
//Wand Spells
|
||||
public const uint HallowedWandPirate = 24717;
|
||||
public const uint HallowedWandNinja = 24718;
|
||||
public const uint HallowedWandLeperGnome = 24719;
|
||||
public const uint HallowedWandRandom = 24720;
|
||||
public const uint HallowedWandSkeleton = 24724;
|
||||
public const uint HallowedWandWisp = 24733;
|
||||
public const uint HallowedWandGhost = 24737;
|
||||
public const uint HallowedWandBat = 24741;
|
||||
|
||||
//Pilgrims Bounty
|
||||
public const uint WellFedApTrigger = 65414;
|
||||
public const uint WellFedZmTrigger = 65412;
|
||||
public const uint WellFedHitTrigger = 65416;
|
||||
public const uint WellFedHasteTrigger = 65410;
|
||||
public const uint WellFedSpiritTrigger = 65415;
|
||||
|
||||
//Mistletoe
|
||||
public const uint CreateMistletoe = 26206;
|
||||
public const uint CreateHolly = 26207;
|
||||
public const uint CreateSnowflakes = 45036;
|
||||
|
||||
//Winter Wondervolt
|
||||
public const uint Px238WinterWondervoltTransform1 = 26157;
|
||||
public const uint Px238WinterWondervoltTransform2 = 26272;
|
||||
public const uint Px238WinterWondervoltTransform3 = 26273;
|
||||
public const uint Px238WinterWondervoltTransform4 = 26274;
|
||||
|
||||
//Ramblabla
|
||||
public const uint Giddyup = 42924;
|
||||
public const uint RentalRacingRam = 43883;
|
||||
public const uint SwiftWorkRam = 43880;
|
||||
public const uint RentalRacingRamAura = 42146;
|
||||
public const uint RamLevelNeutral = 43310;
|
||||
public const uint RamTrot = 42992;
|
||||
public const uint RamCanter = 42993;
|
||||
public const uint RamGallop = 42994;
|
||||
public const uint RamFatigue = 43052;
|
||||
public const uint ExhaustedRam = 43332;
|
||||
public const uint RelayRaceTurnIn = 44501;
|
||||
|
||||
//Brazierhit
|
||||
public const uint TorchTossingTraining = 45716;
|
||||
public const uint TorchTossingPractice = 46630;
|
||||
public const uint TorchTossingTrainingSuccessAlliance = 45719;
|
||||
public const uint TorchTossingTrainingSuccessHorde = 46651;
|
||||
public const uint BraziersHit = 45724;
|
||||
|
||||
//Ribbonpoledata
|
||||
public const uint HasFullMidsummerSet = 58933;
|
||||
public const uint BurningHotPoleDance = 58934;
|
||||
public const uint RibbonDanceCosmetic = 29726;
|
||||
public const uint RibbonDance = 29175;
|
||||
}
|
||||
|
||||
struct QuestIds
|
||||
{
|
||||
//Ramblabla
|
||||
public const uint BrewfestSpeedBunnyGreen = 43345;
|
||||
public const uint BrewfestSpeedBunnyYellow = 43346;
|
||||
public const uint BrewfestSpeedBunnyRed = 43347;
|
||||
|
||||
//Barkerbunny
|
||||
// Horde
|
||||
public const uint BarkForDrohnsDistillery = 11407;
|
||||
public const uint BarkForTchalisVoodooBrewery = 11408;
|
||||
|
||||
// Alliance
|
||||
public const uint BarkBarleybrew = 11293;
|
||||
public const uint BarkForThunderbrews = 11294;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
// Bark For Drohn'S Distillery!
|
||||
public const uint DrohnDistillery1 = 23520;
|
||||
public const uint DrohnDistillery2 = 23521;
|
||||
public const uint DrohnDistillery3 = 23522;
|
||||
public const uint DrohnDistillery4 = 23523;
|
||||
|
||||
// Bark For T'Chali'S Voodoo Brewery!
|
||||
public const uint TChalisVoodoo1 = 23524;
|
||||
public const uint TChalisVoodoo2 = 23525;
|
||||
public const uint TChalisVoodoo3 = 23526;
|
||||
public const uint TChalisVoodoo4 = 23527;
|
||||
|
||||
// Bark For The Barleybrews!
|
||||
public const uint Barleybrew1 = 23464;
|
||||
public const uint Barleybrew2 = 23465;
|
||||
public const uint Barleybrew3 = 23466;
|
||||
public const uint Barleybrew4 = 22941;
|
||||
|
||||
// Bark For The Thunderbrews!
|
||||
public const uint Thunderbrews1 = 23467;
|
||||
public const uint Thunderbrews2 = 23468;
|
||||
public const uint Thunderbrews3 = 23469;
|
||||
public const uint Thunderbrews4 = 22942;
|
||||
}
|
||||
|
||||
struct GameobjectIds
|
||||
{
|
||||
public const uint RibbonPole = 181605;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Script] // 45102 Romantic Picnic
|
||||
class spell_love_is_in_the_air_romantic_picnic : AuraScript
|
||||
{
|
||||
void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
target.SetStandState(UnitStandStateType.Sit);
|
||||
target.CastSpell(target, SpellIds.MealPeriodic, false);
|
||||
}
|
||||
|
||||
void OnPeriodic(AuraEffect aurEff)
|
||||
{
|
||||
// Every 5 seconds
|
||||
Unit target = GetTarget();
|
||||
Unit caster = GetCaster();
|
||||
|
||||
// If our player is no longer sit, remove all auras
|
||||
if (target.GetStandState() != UnitStandStateType.Sit)
|
||||
{
|
||||
target.RemoveAura(SpellIds.RomanticPicnicAchiev);
|
||||
target.RemoveAura(GetAura());
|
||||
return;
|
||||
}
|
||||
|
||||
target.CastSpell(target, SpellIds.BasketCheck, false); // unknown use, it targets Romantic Basket
|
||||
target.CastSpell(target, RandomHelper.RAND(SpellIds.MealEatVisual, SpellIds.DrinkVisual), false);
|
||||
|
||||
bool foundSomeone = false;
|
||||
// For nearby players, check if they have the same aura. If so, cast Romantic Picnic (45123)
|
||||
// required by achievement and "hearts" visual
|
||||
List<Player> playerList = new List<Player>();
|
||||
AnyPlayerInObjectRangeCheck checker = new AnyPlayerInObjectRangeCheck(target, SharedConst.InteractionDistance * 2);
|
||||
var searcher = new PlayerListSearcher(target, playerList, checker);
|
||||
Cell.VisitWorldObjects(target, searcher, SharedConst.InteractionDistance * 2);
|
||||
foreach (var player in playerList)
|
||||
{
|
||||
if (player != target && player.HasAura(GetId())) // && player.GetStandState() == UNIT_STAND_STATE_SIT)
|
||||
{
|
||||
if (caster)
|
||||
{
|
||||
caster.CastSpell(player, SpellIds.RomanticPicnicAchiev, true);
|
||||
caster.CastSpell(target, SpellIds.RomanticPicnicAchiev, true);
|
||||
}
|
||||
foundSomeone = true;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundSomeone && target.HasAura(SpellIds.RomanticPicnicAchiev))
|
||||
target.RemoveAura(SpellIds.RomanticPicnicAchiev);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(OnApply, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.Real));
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(OnPeriodic, 0, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 24750 Trick
|
||||
class spell_hallow_end_trick : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.PirateCostumeMale, SpellIds.PirateCostumeFemale, SpellIds.NinjaCostumeMale, SpellIds.NinjaCostumeFemale,
|
||||
SpellIds.LeperGnomeCostumeMale, SpellIds.LeperGnomeCostumeFemale, SpellIds.SkeletonCostume, SpellIds.GhostCostumeMale, SpellIds.GhostCostumeFemale, SpellIds.TrickBuff);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
Player target = GetHitPlayer();
|
||||
if (target)
|
||||
{
|
||||
Gender gender = target.GetGender();
|
||||
uint spellId = SpellIds.TrickBuff;
|
||||
switch (RandomHelper.URand(0, 5))
|
||||
{
|
||||
case 1:
|
||||
spellId = gender == Gender.Female ? SpellIds.LeperGnomeCostumeFemale : SpellIds.LeperGnomeCostumeMale;
|
||||
break;
|
||||
case 2:
|
||||
spellId = gender == Gender.Female ? SpellIds.PirateCostumeFemale : SpellIds.PirateCostumeMale;
|
||||
break;
|
||||
case 3:
|
||||
spellId = gender == Gender.Female ? SpellIds.GhostCostumeFemale : SpellIds.GhostCostumeMale;
|
||||
break;
|
||||
case 4:
|
||||
spellId = gender == Gender.Female ? SpellIds.NinjaCostumeFemale : SpellIds.NinjaCostumeMale;
|
||||
break;
|
||||
case 5:
|
||||
spellId = SpellIds.SkeletonCostume;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
caster.CastSpell(target, spellId, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 24751 Trick or Treat
|
||||
class spell_hallow_end_trick_or_treat : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Trick, SpellIds.Treat, SpellIds.TrickedOrTreated);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
Player target = GetHitPlayer();
|
||||
if (target)
|
||||
{
|
||||
caster.CastSpell(target, RandomHelper.randChance(50) ? SpellIds.Trick : SpellIds.Treat, true);
|
||||
caster.CastSpell(target, SpellIds.TrickedOrTreated, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_hallow_end_tricky_treat : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.TrickyTreatSpeed, SpellIds.TrickyTreatTrigger, SpellIds.UpsetTummy);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster.HasAura(SpellIds.TrickyTreatTrigger) && caster.GetAuraCount(SpellIds.TrickyTreatSpeed) > 3 && RandomHelper.randChance(33))
|
||||
caster.CastSpell(caster, SpellIds.UpsetTummy, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_hallow_end_wand : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellEntry)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.PirateCostumeMale, SpellIds.PirateCostumeFemale, SpellIds.NinjaCostumeMale, SpellIds.NinjaCostumeFemale,
|
||||
SpellIds.LeperGnomeCostumeMale, SpellIds.LeperGnomeCostumeFemale, SpellIds.GhostCostumeMale, SpellIds.GhostCostumeFemale);
|
||||
}
|
||||
|
||||
void HandleScriptEffect()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
Unit target = GetHitUnit();
|
||||
|
||||
uint spellId = 0;
|
||||
bool female = target.GetGender() == Gender.Female;
|
||||
|
||||
switch (GetSpellInfo().Id)
|
||||
{
|
||||
case SpellIds.HallowedWandLeperGnome:
|
||||
spellId = female ? SpellIds.LeperGnomeCostumeFemale : SpellIds.LeperGnomeCostumeMale;
|
||||
break;
|
||||
case SpellIds.HallowedWandPirate:
|
||||
spellId = female ? SpellIds.PirateCostumeFemale : SpellIds.PirateCostumeMale;
|
||||
break;
|
||||
case SpellIds.HallowedWandGhost:
|
||||
spellId = female ? SpellIds.GhostCostumeFemale : SpellIds.GhostCostumeMale;
|
||||
break;
|
||||
case SpellIds.HallowedWandNinja:
|
||||
spellId = female ? SpellIds.NinjaCostumeFemale : SpellIds.NinjaCostumeMale;
|
||||
break;
|
||||
case SpellIds.HallowedWandRandom:
|
||||
spellId = RandomHelper.RAND(SpellIds.HallowedWandPirate, SpellIds.HallowedWandNinja, SpellIds.HallowedWandLeperGnome, SpellIds.HallowedWandSkeleton, SpellIds.HallowedWandWisp, SpellIds.HallowedWandGhost, SpellIds.HallowedWandBat);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
caster.CastSpell(target, spellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterHit.Add(new HitHandler(HandleScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script("spell_gen_slow_roasted_turkey", SpellIds.WellFedApTrigger)]
|
||||
[Script("spell_gen_cranberry_chutney", SpellIds.WellFedZmTrigger)]
|
||||
[Script("spell_gen_spice_bread_stuffing", SpellIds.WellFedHitTrigger)]
|
||||
[Script("spell_gen_pumpkin_pie", SpellIds.WellFedSpiritTrigger)]
|
||||
[Script("spell_gen_candied_sweet_potato", SpellIds.WellFedHasteTrigger)]
|
||||
class spell_pilgrims_bounty_buff_food : AuraScript
|
||||
{
|
||||
public spell_pilgrims_bounty_buff_food(uint triggeredSpellId) : base()
|
||||
{
|
||||
_triggeredSpellId = triggeredSpellId;
|
||||
_handled = false;
|
||||
}
|
||||
|
||||
void HandleTriggerSpell(AuraEffect aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (_handled)
|
||||
return;
|
||||
|
||||
_handled = true;
|
||||
GetTarget().CastSpell(GetTarget(), _triggeredSpellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleTriggerSpell, 2, AuraType.PeriodicTriggerSpell));
|
||||
}
|
||||
|
||||
uint _triggeredSpellId;
|
||||
|
||||
bool _handled;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_winter_veil_mistletoe : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.CreateMistletoe, SpellIds.CreateHolly, SpellIds.CreateSnowflakes);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Player target = GetHitPlayer();
|
||||
if (target)
|
||||
{
|
||||
uint spellId = RandomHelper.RAND(SpellIds.CreateHolly, SpellIds.CreateMistletoe, SpellIds.CreateSnowflakes);
|
||||
GetCaster().CastSpell(target, spellId, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 26275 - PX-238 Winter Wondervolt TRAP
|
||||
class spell_winter_veil_px_238_winter_wondervolt : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Px238WinterWondervoltTransform1, SpellIds.Px238WinterWondervoltTransform2,
|
||||
SpellIds.Px238WinterWondervoltTransform3, SpellIds.Px238WinterWondervoltTransform4);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
|
||||
uint[] spells =
|
||||
{
|
||||
SpellIds.Px238WinterWondervoltTransform1,
|
||||
SpellIds.Px238WinterWondervoltTransform2,
|
||||
SpellIds.Px238WinterWondervoltTransform3,
|
||||
SpellIds.Px238WinterWondervoltTransform4
|
||||
};
|
||||
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
if (target.HasAura(spells[i]))
|
||||
return;
|
||||
|
||||
target.CastSpell(target, spells[RandomHelper.URand(0, 3)], true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 42924 - Giddyup!
|
||||
class spell_brewfest_giddyup : AuraScript
|
||||
{
|
||||
void OnChange(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
if (!target.HasAura(SpellIds.RentalRacingRam) && !target.HasAura(SpellIds.SwiftWorkRam))
|
||||
{
|
||||
target.RemoveAura(GetId());
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.HasAura(SpellIds.ExhaustedRam))
|
||||
return;
|
||||
|
||||
switch (GetStackAmount())
|
||||
{
|
||||
case 1: // green
|
||||
target.RemoveAura(SpellIds.RamLevelNeutral);
|
||||
target.RemoveAura(SpellIds.RamCanter);
|
||||
target.CastSpell(target, SpellIds.RamTrot, true);
|
||||
break;
|
||||
case 6: // yellow
|
||||
target.RemoveAura(SpellIds.RamTrot);
|
||||
target.RemoveAura(SpellIds.RamGallop);
|
||||
target.CastSpell(target, SpellIds.RamCanter, true);
|
||||
break;
|
||||
case 11: // red
|
||||
target.RemoveAura(SpellIds.RamCanter);
|
||||
target.CastSpell(target, SpellIds.RamGallop, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (GetTargetApplication().GetRemoveMode() == AuraRemoveMode.Default)
|
||||
{
|
||||
target.RemoveAura(SpellIds.RamTrot);
|
||||
target.CastSpell(target, SpellIds.RamLevelNeutral, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPeriodic(AuraEffect aurEff)
|
||||
{
|
||||
GetTarget().RemoveAuraFromStack(GetId());
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(OnChange, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.ChangeAmountMask));
|
||||
OnEffectRemove.Add(new EffectApplyHandler(OnChange, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.ChangeAmountMask));
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(OnPeriodic, 0, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 43310 - Ram Level - Neutral
|
||||
// 42992 - Ram - Trot
|
||||
// 42993 - Ram - Canter
|
||||
// 42994 - Ram - Gallop
|
||||
[Script]
|
||||
class spell_brewfest_ram : AuraScript
|
||||
{
|
||||
void OnPeriodic(AuraEffect aurEff)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
if (target.HasAura(SpellIds.ExhaustedRam))
|
||||
return;
|
||||
|
||||
switch (GetId())
|
||||
{
|
||||
case SpellIds.RamLevelNeutral:
|
||||
{
|
||||
Aura aura = target.GetAura(SpellIds.RamFatigue);
|
||||
if (aura != null)
|
||||
aura.ModStackAmount(-4);
|
||||
}
|
||||
break;
|
||||
case SpellIds.RamTrot: // green
|
||||
{
|
||||
Aura aura = target.GetAura(SpellIds.RamFatigue);
|
||||
if (aura != null)
|
||||
aura.ModStackAmount(-2);
|
||||
if (aurEff.GetTickNumber() == 4)
|
||||
target.CastSpell(target, QuestIds.BrewfestSpeedBunnyGreen, true);
|
||||
}
|
||||
break;
|
||||
case SpellIds.RamCanter:
|
||||
target.CastCustomSpell(SpellIds.RamFatigue, SpellValueMod.AuraStack, 1, target, TriggerCastFlags.FullMask);
|
||||
if (aurEff.GetTickNumber() == 8)
|
||||
target.CastSpell(target, QuestIds.BrewfestSpeedBunnyYellow, true);
|
||||
break;
|
||||
case SpellIds.RamGallop:
|
||||
target.CastCustomSpell(SpellIds.RamFatigue, SpellValueMod.AuraStack, target.HasAura(SpellIds.RamFatigue) ? 4 : 5 /*Hack*/, target, TriggerCastFlags.FullMask);
|
||||
if (aurEff.GetTickNumber() == 8)
|
||||
target.CastSpell(target, QuestIds.BrewfestSpeedBunnyRed, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(OnPeriodic, 1, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 43052 - Ram Fatigue
|
||||
class spell_brewfest_ram_fatigue : AuraScript
|
||||
{
|
||||
void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
|
||||
if (GetStackAmount() == 101)
|
||||
{
|
||||
target.RemoveAura(SpellIds.RamLevelNeutral);
|
||||
target.RemoveAura(SpellIds.RamTrot);
|
||||
target.RemoveAura(SpellIds.RamCanter);
|
||||
target.RemoveAura(SpellIds.RamGallop);
|
||||
target.RemoveAura(SpellIds.Giddyup);
|
||||
|
||||
target.CastSpell(target, SpellIds.ExhaustedRam, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(OnApply, 0, AuraType.Dummy, AuraEffectHandleModes.RealOrReapplyMask));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 43450 - Brewfest - apple trap - friendly DND
|
||||
class spell_brewfest_apple_trap : AuraScript
|
||||
{
|
||||
void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().RemoveAura(SpellIds.RamFatigue);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectApply.Add(new EffectApplyHandler(OnApply, 0, AuraType.ForceReaction, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 43332 - Exhausted Ram
|
||||
class spell_brewfest_exhausted_ram : AuraScript
|
||||
{
|
||||
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
target.CastSpell(target, SpellIds.RamLevelNeutral, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.ModDecreaseSpeed, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 43714 - Brewfest - Relay Race - Intro - Force - Player to throw- DND
|
||||
class spell_brewfest_relay_race_intro_force_player_to_throw : SpellScript
|
||||
{
|
||||
void HandleForceCast(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
// All this spells trigger a spell that requires reagents; if the
|
||||
// triggered spell is cast as "triggered", reagents are not consumed
|
||||
GetHitUnit().CastSpell(null, GetSpellInfo().GetEffect(effIndex).TriggerSpell, TriggerCastFlags.FullMask & ~TriggerCastFlags.IgnorePowerAndReagentCost);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleForceCast, 0, SpellEffectName.ForceCast));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_brewfest_relay_race_turn_in : SpellScript
|
||||
{
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
|
||||
Aura aura = GetHitUnit().GetAura(SpellIds.SwiftWorkRam);
|
||||
if (aura != null)
|
||||
{
|
||||
aura.SetDuration(aura.GetDuration() + 30 * Time.InMilliseconds);
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.RelayRaceTurnIn, TriggerCastFlags.FullMask);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 43876 - Dismount Ram
|
||||
class spell_brewfest_dismount_ram : SpellScript
|
||||
{
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
GetCaster().RemoveAura(SpellIds.RentalRacingRam);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
// 43259 Brewfest - Barker Bunny 1
|
||||
// 43260 Brewfest - Barker Bunny 2
|
||||
// 43261 Brewfest - Barker Bunny 3
|
||||
// 43262 Brewfest - Barker Bunny 4
|
||||
[Script]
|
||||
class spell_brewfest_barker_bunny : AuraScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
return GetUnitOwner().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Player target = GetTarget().ToPlayer();
|
||||
|
||||
uint BroadcastTextId = 0;
|
||||
|
||||
if (target.GetQuestStatus(QuestIds.BarkForDrohnsDistillery) == QuestStatus.Incomplete ||
|
||||
target.GetQuestStatus(QuestIds.BarkForDrohnsDistillery) == QuestStatus.Complete)
|
||||
BroadcastTextId = RandomHelper.RAND(TextIds.DrohnDistillery1, TextIds.DrohnDistillery2, TextIds.DrohnDistillery3, TextIds.DrohnDistillery4);
|
||||
|
||||
if (target.GetQuestStatus(QuestIds.BarkForTchalisVoodooBrewery) == QuestStatus.Incomplete ||
|
||||
target.GetQuestStatus(QuestIds.BarkForTchalisVoodooBrewery) == QuestStatus.Complete)
|
||||
BroadcastTextId = RandomHelper.RAND(TextIds.TChalisVoodoo1, TextIds.TChalisVoodoo2, TextIds.TChalisVoodoo3, TextIds.TChalisVoodoo4);
|
||||
|
||||
if (target.GetQuestStatus(QuestIds.BarkBarleybrew) == QuestStatus.Incomplete ||
|
||||
target.GetQuestStatus(QuestIds.BarkBarleybrew) == QuestStatus.Complete)
|
||||
BroadcastTextId = RandomHelper.RAND(TextIds.Barleybrew1, TextIds.Barleybrew2, TextIds.Barleybrew3, TextIds.Barleybrew4);
|
||||
|
||||
if (target.GetQuestStatus(QuestIds.BarkForThunderbrews) == QuestStatus.Incomplete ||
|
||||
target.GetQuestStatus(QuestIds.BarkForThunderbrews) == QuestStatus.Complete)
|
||||
BroadcastTextId = RandomHelper.RAND(TextIds.Thunderbrews1, TextIds.Thunderbrews2, TextIds.Thunderbrews3, TextIds.Thunderbrews4);
|
||||
|
||||
if (BroadcastTextId != 0)
|
||||
target.Talk(BroadcastTextId, ChatMsg.Say, WorldConfig.GetFloatValue(WorldCfg.ListenRangeSay), target);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectApply.Add(new EffectApplyHandler(OnApply, 1, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 45724 - Braziers Hit!
|
||||
class spell_midsummer_braziers_hit : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.TorchTossingTraining, SpellIds.TorchTossingPractice);
|
||||
}
|
||||
|
||||
void HandleEffectApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
Player player = GetTarget().ToPlayer();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
if ((player.HasAura(SpellIds.TorchTossingTraining) && GetStackAmount() == 8) || (player.HasAura(SpellIds.TorchTossingPractice) && GetStackAmount() == 20))
|
||||
{
|
||||
if (player.GetTeam() == Team.Alliance)
|
||||
player.CastSpell(player, SpellIds.TorchTossingTrainingSuccessAlliance, true);
|
||||
else if (player.GetTeam() == Team.Horde)
|
||||
player.CastSpell(player, SpellIds.TorchTossingTrainingSuccessHorde, true);
|
||||
Remove();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(HandleEffectApply, 0, AuraType.Dummy, AuraEffectHandleModes.Reapply));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_gen_ribbon_pole_dancer_check : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.HasFullMidsummerSet, SpellIds.RibbonDance, SpellIds.BurningHotPoleDance);
|
||||
}
|
||||
|
||||
void PeriodicTick(AuraEffect aurEff)
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
|
||||
// check if aura needs to be removed
|
||||
if (!target.FindNearestGameObject(GameobjectIds.RibbonPole, 8.0f) || !target.HasUnitState(UnitState.Casting))
|
||||
{
|
||||
target.InterruptNonMeleeSpells(false);
|
||||
target.RemoveAurasDueToSpell(GetId());
|
||||
target.RemoveAura(SpellIds.RibbonDanceCosmetic);
|
||||
return;
|
||||
}
|
||||
|
||||
// set xp buff duration
|
||||
Aura aur = target.GetAura(SpellIds.RibbonDance);
|
||||
if (aur != null)
|
||||
{
|
||||
aur.SetMaxDuration(Math.Min(3600000, aur.GetMaxDuration() + 180000));
|
||||
aur.RefreshDuration();
|
||||
|
||||
// reward achievement criteria
|
||||
if (aur.GetMaxDuration() == 3600000 && target.HasAura(SpellIds.HasFullMidsummerSet))
|
||||
target.CastSpell(target, SpellIds.BurningHotPoleDance, true);
|
||||
}
|
||||
else
|
||||
target.AddAura(SpellIds.RibbonDance, target);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(PeriodicTick, 0, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,726 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Spells.Hunter
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint AspectCheetahSlow = 186258;
|
||||
public const uint BestialWrath = 19574;
|
||||
public const uint ChimeraShotHeal = 53353;
|
||||
public const uint Exhilaration = 109304;
|
||||
public const uint ExhilarationPet = 128594;
|
||||
public const uint ExhilarationR2 = 231546;
|
||||
public const uint Fire = 82926;
|
||||
public const uint GenericEnergizeFocus = 91954;
|
||||
public const uint ImprovedMendPet = 24406;
|
||||
public const uint LockAndLoad = 56453;
|
||||
public const uint Lonewolf = 155228;
|
||||
public const uint MastersCallTriggered = 62305;
|
||||
public const uint MisdirectionProc = 35079;
|
||||
public const uint PetLastStandTriggered = 53479;
|
||||
public const uint PetHeartOfThePhoenix = 55709;
|
||||
public const uint PetHeartOfThePhoenixTriggered = 54114;
|
||||
public const uint PetHeartOfThePhoenixDebuff = 55711;
|
||||
public const uint PetCarrionFeederTriggered = 54045;
|
||||
public const uint Readiness = 23989;
|
||||
public const uint SerpentSting = 1978;
|
||||
public const uint SniperTrainingR1 = 53302;
|
||||
public const uint SniperTrainingBuffR1 = 64418;
|
||||
public const uint SteadyShotFocus = 77443;
|
||||
public const uint T94PGreatness = 68130;
|
||||
public const uint DraeneiGiftOfTheNaaru = 59543;
|
||||
public const uint RoarOfSacrificeTriggered = 67481;
|
||||
}
|
||||
|
||||
[Script] // 186257 - Aspect of the Cheetah
|
||||
class spell_hun_aspect_cheetah : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.AspectCheetahSlow);
|
||||
}
|
||||
|
||||
void HandleOnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
if (GetTargetApplication().GetRemoveMode() == AuraRemoveMode.Expire)
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.AspectCheetahSlow, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(HandleOnRemove, 0, AuraType.ModIncreaseSpeed, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
// 53209 - Chimera Shot
|
||||
[Script]
|
||||
class spell_hun_chimera_shot : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ChimeraShotHeal, SpellIds.SerpentSting);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void HandleScriptEffect(uint effIndex)
|
||||
{
|
||||
GetCaster().CastSpell(GetCaster(), SpellIds.ChimeraShotHeal, true);
|
||||
Aura aur = GetHitUnit().GetAura(SpellIds.SerpentSting, GetCaster().GetGUID());
|
||||
if (aur != null)
|
||||
aur.SetDuration(aur.GetSpellInfo().GetMaxDuration(), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
// 77767 - Cobra Shot
|
||||
[Script]
|
||||
class spell_hun_cobra_shot : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.GenericEnergizeFocus, SpellIds.SerpentSting);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void HandleScriptEffect(uint effIndex)
|
||||
{
|
||||
GetCaster().CastSpell(GetCaster(), SpellIds.GenericEnergizeFocus, true);
|
||||
Aura aur = GetHitUnit().GetAura(SpellIds.SerpentSting, GetCaster().GetGUID());
|
||||
if (aur != null)
|
||||
{
|
||||
int newDuration = aur.GetDuration() + GetEffectValue() * Time.InMilliseconds;
|
||||
aur.SetDuration(Math.Min(newDuration, aur.GetMaxDuration()), true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 1, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
// 781 - Disengage
|
||||
[Script]
|
||||
class spell_hun_disengage : SpellScript
|
||||
{
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster.IsTypeId(TypeId.Player) && !caster.IsInCombat())
|
||||
return SpellCastResult.CantDoThatRightNow;
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 109304 - Exhilaration
|
||||
class spell_hun_exhilaration : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ExhilarationR2, SpellIds.Lonewolf);
|
||||
}
|
||||
|
||||
void HandleOnHit()
|
||||
{
|
||||
if (GetCaster().HasAura(SpellIds.ExhilarationR2) && !GetCaster().HasAura(SpellIds.Lonewolf))
|
||||
GetCaster().CastSpell((Unit)null, SpellIds.ExhilarationPet, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnHit.Add(new HitHandler(HandleOnHit));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 212658 - Hunting Party
|
||||
class spell_hun_hunting_party : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Exhilaration, SpellIds.ExhilarationPet);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.Exhilaration, -TimeSpan.FromSeconds(aurEff.GetAmount()));
|
||||
GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.ExhilarationPet, -TimeSpan.FromSeconds(aurEff.GetAmount()));
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// -19572 - Improved Mend Pet
|
||||
[Script]
|
||||
class spell_hun_improved_mend_pet : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ImprovedMendPet);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
return RandomHelper.randChance(GetEffect(0).GetAmount());
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.ImprovedMendPet, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 53478 - Last Stand Pet
|
||||
[Script]
|
||||
class spell_hun_last_stand_pet : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.PetLastStandTriggered);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
int healthModSpellBasePoints0 = (int)caster.CountPctFromMaxHealth(30);
|
||||
caster.CastCustomSpell(caster, SpellIds.PetLastStandTriggered, healthModSpellBasePoints0, 0, 0, true, null);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 53271 - Masters Call
|
||||
[Script]
|
||||
class spell_hun_masters_call : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.MastersCallTriggered, (uint)spellInfo.GetEffect(0).CalcValue());
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit ally = GetHitUnit();
|
||||
if (ally)
|
||||
{
|
||||
Player caster = GetCaster().ToPlayer();
|
||||
if (caster)
|
||||
{
|
||||
Pet target = caster.GetPet();
|
||||
if (target)
|
||||
{
|
||||
TriggerCastFlags castMask = (TriggerCastFlags.FullMask & ~TriggerCastFlags.IgnoreCasterAurastate);
|
||||
target.CastSpell(ally, (uint)GetEffectValue(), castMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleScriptEffect(uint effIndex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
{
|
||||
// Cannot be processed while pet is dead
|
||||
TriggerCastFlags castMask = (TriggerCastFlags.FullMask & ~TriggerCastFlags.IgnoreCasterAurastate);
|
||||
target.CastSpell(target, SpellIds.MastersCallTriggered, castMask);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 1, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
// 34477 - Misdirection
|
||||
[Script]
|
||||
class spell_hun_misdirection : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.MisdirectionProc);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Default || !GetTarget().HasAura(SpellIds.MisdirectionProc))
|
||||
GetTarget().ResetRedirectThreat();
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
return GetTarget().GetRedirectThreatTarget();
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.MisdirectionProc, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 1, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 1, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 35079 - Misdirection (Proc)
|
||||
[Script]
|
||||
class spell_hun_misdirection_proc : AuraScript
|
||||
{
|
||||
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().ResetRedirectThreat();
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
// 54044 - Pet Carrion Feeder
|
||||
[Script]
|
||||
class spell_hun_pet_carrion_feeder : SpellScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
if (!GetCaster().IsPet())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.PetCarrionFeederTriggered);
|
||||
}
|
||||
|
||||
SpellCastResult CheckIfCorpseNear()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
float max_range = GetSpellInfo().GetMaxRange(false);
|
||||
|
||||
// search for nearby enemy corpse in range
|
||||
var check = new AnyDeadUnitSpellTargetInRangeCheck<WorldObject>(caster, max_range, GetSpellInfo(), SpellTargetCheckTypes.Enemy);
|
||||
var searcher = new WorldObjectSearcher(caster, check);
|
||||
Cell.VisitWorldObjects(caster, searcher, max_range);
|
||||
if (!searcher.GetTarget())
|
||||
Cell.VisitGridObjects(caster, searcher, max_range);
|
||||
if (!searcher.GetTarget())
|
||||
return SpellCastResult.NoEdibleCorpses;
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
caster.CastSpell(caster, SpellIds.PetCarrionFeederTriggered, false);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHit.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckIfCorpseNear));
|
||||
}
|
||||
}
|
||||
|
||||
// 55709 - Pet Heart of the Phoenix
|
||||
[Script]
|
||||
class spell_hun_pet_heart_of_the_phoenix : SpellScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
if (!GetCaster().IsPet())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.PetHeartOfThePhoenixTriggered, SpellIds.PetHeartOfThePhoenixDebuff);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
Unit owner = caster.GetOwner();
|
||||
if (owner)
|
||||
{
|
||||
if (!caster.HasAura(SpellIds.PetHeartOfThePhoenixDebuff))
|
||||
{
|
||||
owner.CastCustomSpell(SpellIds.PetHeartOfThePhoenixTriggered, SpellValueMod.BasePoint0, 100, caster, true);
|
||||
caster.CastSpell(caster, SpellIds.PetHeartOfThePhoenixDebuff, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
// 23989 - Readiness
|
||||
[Script]
|
||||
class spell_hun_readiness : SpellScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
// immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath
|
||||
GetCaster().GetSpellHistory().ResetCooldowns(p =>
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(p.Key);
|
||||
|
||||
///! If spellId in cooldown map isn't valid, the above will return a null pointer.
|
||||
if (spellInfo.SpellFamilyName == SpellFamilyNames.Hunter &&
|
||||
spellInfo.Id != SpellIds.Readiness &&
|
||||
spellInfo.Id != SpellIds.BestialWrath &&
|
||||
spellInfo.Id != SpellIds.DraeneiGiftOfTheNaaru &&
|
||||
spellInfo.GetRecoveryTime() > 0)
|
||||
return true;
|
||||
return false;
|
||||
}, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 82925 - Ready, Set, Aim...
|
||||
[Script]
|
||||
class spell_hun_ready_set_aim : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Fire);
|
||||
}
|
||||
|
||||
void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
if (GetStackAmount() == 5)
|
||||
{
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.Fire, true, null, aurEff);
|
||||
GetTarget().RemoveAura(GetId());
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(OnApply, 0, AuraType.Dummy, AuraEffectHandleModes.RealOrReapplyMask));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 53480 - Roar of Sacrifice
|
||||
class spell_hun_roar_of_sacrifice : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.RoarOfSacrificeTriggered);
|
||||
}
|
||||
|
||||
bool CheckProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
DamageInfo damageInfo = eventInfo.GetDamageInfo();
|
||||
if (damageInfo == null || !Convert.ToBoolean((int)damageInfo.GetSchoolMask() & aurEff.GetMiscValue()))
|
||||
return false;
|
||||
|
||||
if (!GetCaster())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
int damage = (int)MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetDamage(), aurEff.GetAmount());
|
||||
eventInfo.GetActor().CastCustomSpell(SpellIds.RoarOfSacrificeTriggered, SpellValueMod.BasePoint0, damage, GetCaster(), TriggerCastFlags.FullMask, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckEffectProc.Add(new CheckEffectProcHandler(CheckProc, 1, AuraType.Dummy));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 1, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 37506 - Scatter Shot
|
||||
[Script]
|
||||
class spell_hun_scatter_shot : SpellScript
|
||||
{
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Player caster = GetCaster().ToPlayer();
|
||||
// break Auto Shot and autohit
|
||||
caster.InterruptSpell(CurrentSpellTypes.AutoRepeat);
|
||||
caster.AttackStop();
|
||||
caster.SendAttackSwingCancelAttack();
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// -53302 - Sniper Training
|
||||
[Script]
|
||||
class spell_hun_sniper_training : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SniperTrainingR1, SpellIds.SniperTrainingBuffR1);
|
||||
}
|
||||
|
||||
void HandlePeriodic(AuraEffect aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (aurEff.GetAmount() <= 0)
|
||||
{
|
||||
uint spellId = SpellIds.SniperTrainingBuffR1 + GetId() - SpellIds.SniperTrainingR1;
|
||||
Unit target = GetTarget();
|
||||
target.CastSpell(target, spellId, true, null, aurEff);
|
||||
Player playerTarget = GetUnitOwner().ToPlayer();
|
||||
if (playerTarget)
|
||||
{
|
||||
int baseAmount = aurEff.GetBaseAmount();
|
||||
int amount = playerTarget.CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff.GetEffIndex(), baseAmount);
|
||||
GetEffect(0).SetAmount(amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleUpdatePeriodic(AuraEffect aurEff)
|
||||
{
|
||||
Player playerTarget = GetUnitOwner().ToPlayer();
|
||||
if (playerTarget)
|
||||
{
|
||||
int baseAmount = aurEff.GetBaseAmount();
|
||||
int amount = playerTarget.isMoving() ?
|
||||
playerTarget.CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff.GetEffIndex(), baseAmount) :
|
||||
aurEff.GetAmount() - 1;
|
||||
aurEff.SetAmount(amount);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodic, 0, AuraType.PeriodicTriggerSpell));
|
||||
OnEffectUpdatePeriodic.Add(new EffectUpdatePeriodicHandler(HandleUpdatePeriodic, 0, AuraType.PeriodicTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
// 56641 - Steady Shot
|
||||
[Script]
|
||||
class spell_hun_steady_shot : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SteadyShotFocus);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void HandleOnHit()
|
||||
{
|
||||
GetCaster().CastSpell(GetCaster(), SpellIds.SteadyShotFocus, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnHit.Add(new HitHandler(HandleOnHit));
|
||||
}
|
||||
}
|
||||
|
||||
// 1515 - Tame Beast
|
||||
[Script]
|
||||
class spell_hun_tame_beast : SpellScript
|
||||
{
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (!caster.IsTypeId(TypeId.Player))
|
||||
return SpellCastResult.DontReport;
|
||||
|
||||
if (!GetExplTargetUnit())
|
||||
return SpellCastResult.BadImplicitTargets;
|
||||
|
||||
Creature target = GetExplTargetUnit().ToCreature();
|
||||
if (target)
|
||||
{
|
||||
if (target.getLevel() > caster.getLevel())
|
||||
return SpellCastResult.Highlevel;
|
||||
|
||||
// use SMSG_PET_TAME_FAILURE?
|
||||
if (!target.GetCreatureTemplate().IsTameable(caster.ToPlayer().CanTameExoticPets()))
|
||||
return SpellCastResult.BadTargets;
|
||||
|
||||
if (!caster.GetPetGUID().IsEmpty())
|
||||
return SpellCastResult.AlreadyHaveSummon;
|
||||
|
||||
if (!caster.GetCharmGUID().IsEmpty())
|
||||
return SpellCastResult.AlreadyHaveCharm;
|
||||
}
|
||||
else
|
||||
return SpellCastResult.BadImplicitTargets;
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
}
|
||||
}
|
||||
|
||||
// 53434 - Call of the Wild
|
||||
[Script]
|
||||
class spell_hun_target_only_pet_and_owner : SpellScript
|
||||
{
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.Clear();
|
||||
targets.Add(GetCaster());
|
||||
Unit owner = GetCaster().GetOwner();
|
||||
if (owner)
|
||||
targets.Add(owner);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitCasterAreaParty));
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 1, Targets.UnitCasterAreaParty));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 67151 - Item - Hunter T9 4P Bonus (Steady Shot)
|
||||
class spell_hun_t9_4p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.T94PGreatness);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
if (eventInfo.GetActor().IsTypeId(TypeId.Player) && eventInfo.GetActor().ToPlayer().GetPet())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit caster = eventInfo.GetActor();
|
||||
|
||||
caster.CastSpell(caster.ToPlayer().GetPet(), SpellIds.T94PGreatness, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
// -56333 - T.N.T.
|
||||
[Script]
|
||||
class spell_hun_tnt : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LockAndLoad);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
return RandomHelper.randChance(GetEffect(0).GetAmount());
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.LockAndLoad, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,629 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Groups;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Spells.Mage
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint BlazingBarrierTrigger = 235314;
|
||||
public const uint Cauterized = 87024;
|
||||
public const uint CauterizeDot = 87023;
|
||||
public const uint ConeOfCold = 120;
|
||||
public const uint ConeOfColdSlow = 212792;
|
||||
public const uint ConjureRefreshment = 116136;
|
||||
public const uint ConjureRefreshmentTable = 167145;
|
||||
public const uint DradonhawkForm = 32818;
|
||||
public const uint FingersOfFrost = 44544;
|
||||
public const uint FrostNova = 122;
|
||||
public const uint GiraffeForm = 32816;
|
||||
public const uint IceBarrier = 11426;
|
||||
public const uint IceBlock = 45438;
|
||||
public const uint Ignite = 12654;
|
||||
public const uint LivingBombExplosion = 44461;
|
||||
public const uint LivingBombPeriodic = 217694;
|
||||
public const uint ManaSurge = 37445;
|
||||
public const uint RingOfFrostDummy = 91264;
|
||||
public const uint RingOfFrostFreeze = 82691;
|
||||
public const uint RingOfFrostSummon = 113724;
|
||||
public const uint SerpentForm = 32817;
|
||||
public const uint SheepForm = 32820;
|
||||
public const uint SquirrelForm = 32813;
|
||||
public const uint TemporalDisplacement = 80354;
|
||||
public const uint WorgenForm = 32819;
|
||||
public const uint Chilled = 205708;
|
||||
|
||||
//Misc
|
||||
public const uint HunterInsanity = 95809;
|
||||
public const uint ShamanExhaustion = 57723;
|
||||
public const uint ShamanSated = 57724;
|
||||
public const uint PetNetherwindsFatigued = 160455;
|
||||
}
|
||||
|
||||
[Script] // 235313 - Blazing Barrier
|
||||
class spell_mage_blazing_barrier : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.BlazingBarrierTrigger);
|
||||
}
|
||||
|
||||
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
canBeRecalculated = false;
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
amount = (int)(caster.SpellBaseHealingBonusDone(GetSpellInfo().GetSchoolMask()) * 7.0f);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit caster = eventInfo.GetDamageInfo().GetVictim();
|
||||
Unit target = eventInfo.GetDamageInfo().GetAttacker();
|
||||
|
||||
if (caster && target)
|
||||
caster.CastSpell(target, SpellIds.BlazingBarrierTrigger, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.SchoolAbsorb));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 1, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 198063 - Burning Determination
|
||||
class spell_mage_burning_determination : AuraScript
|
||||
{
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
SpellInfo spellInfo = eventInfo.GetSpellInfo();
|
||||
if (spellInfo != null)
|
||||
if (spellInfo.GetAllEffectsMechanicMask().HasAnyFlag(((1u << (int)Mechanics.Interrupt) | (1 << (int)Mechanics.Silence))))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 86949 - Cauterize
|
||||
class spell_mage_cauterize : SpellScript
|
||||
{
|
||||
void SuppressSpeedBuff(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectLaunch.Add(new EffectHandler(SuppressSpeedBuff, 2, SpellEffectName.TriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_mage_cauterize_AuraScript : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return spellInfo.GetEffect(2) != null && ValidateSpellInfo(SpellIds.CauterizeDot, SpellIds.Cauterized, spellInfo.GetEffect(2).TriggerSpell);
|
||||
}
|
||||
|
||||
void HandleAbsorb(AuraEffect aurEff, DamageInfo dmgInfo, ref uint absorbAmount)
|
||||
{
|
||||
AuraEffect effect1 = GetEffect(1);
|
||||
if (effect1 == null || !GetTargetApplication().HasEffect(1) ||
|
||||
dmgInfo.GetDamage() < GetTarget().GetHealth() ||
|
||||
dmgInfo.GetDamage() > GetTarget().GetMaxHealth() * 2 ||
|
||||
GetTarget().HasAura(SpellIds.Cauterized))
|
||||
{
|
||||
PreventDefaultAction();
|
||||
return;
|
||||
}
|
||||
|
||||
GetTarget().SetHealth(GetTarget().CountPctFromMaxHealth(effect1.GetAmount()));
|
||||
GetTarget().CastSpell(GetTarget(), GetAura().GetSpellEffectInfo(2).TriggerSpell, TriggerCastFlags.FullMask);
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.CauterizeDot, TriggerCastFlags.FullMask);
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.Cauterized, TriggerCastFlags.FullMask);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectAbsorb.Add(new EffectAbsorbHandler(HandleAbsorb, 0));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 235219 - Cold Snap
|
||||
class spell_mage_cold_snap : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ConeOfCold, SpellIds.FrostNova, SpellIds.IceBarrier, SpellIds.IceBlock);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
GetCaster().GetSpellHistory().ResetCooldowns(p =>
|
||||
{
|
||||
switch (p.Key)
|
||||
{
|
||||
case SpellIds.ConeOfCold:
|
||||
case SpellIds.FrostNova:
|
||||
case SpellIds.IceBarrier:
|
||||
case SpellIds.IceBlock:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHit.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.ScriptEffect));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 120 - Cone of Cold
|
||||
class spell_mage_cone_of_cold : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ConeOfColdSlow);
|
||||
}
|
||||
|
||||
void HandleSlow(uint effIndex)
|
||||
{
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.ConeOfColdSlow, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleSlow, 0, SpellEffectName.SchoolDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 190336 - Conjure Refreshment
|
||||
class spell_mage_conjure_refreshment : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ConjureRefreshment, SpellIds.ConjureRefreshmentTable);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Player caster = GetCaster().ToPlayer();
|
||||
if (caster)
|
||||
{
|
||||
Group group = caster.GetGroup();
|
||||
if (group)
|
||||
caster.CastSpell(caster, SpellIds.ConjureRefreshmentTable, true);
|
||||
else
|
||||
caster.CastSpell(caster, SpellIds.ConjureRefreshment, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 11426 - Ice Barrier
|
||||
class spell_mage_ice_barrier : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellEntry)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Chilled);
|
||||
}
|
||||
|
||||
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
canBeRecalculated = false;
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
amount += (int)(caster.SpellBaseHealingBonusDone(GetSpellInfo().GetSchoolMask()) * 10.0f);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
Unit caster = eventInfo.GetDamageInfo().GetVictim();
|
||||
Unit target = eventInfo.GetDamageInfo().GetAttacker();
|
||||
|
||||
if (caster && target)
|
||||
caster.CastSpell(target, SpellIds.Chilled, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.SchoolAbsorb));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.SchoolAbsorb));
|
||||
}
|
||||
}
|
||||
|
||||
// 11119 - Ignite
|
||||
[Script]
|
||||
class spell_mage_ignite : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Ignite);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
return eventInfo.GetProcTarget();
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
SpellInfo igniteDot = Global.SpellMgr.GetSpellInfo(SpellIds.Ignite);
|
||||
int pct = aurEff.GetAmount();
|
||||
|
||||
int amount = (int)(MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetDamage(), pct) / igniteDot.GetMaxTicks(Difficulty.None));
|
||||
amount += (int)eventInfo.GetProcTarget().GetRemainingPeriodicAmount(eventInfo.GetActor().GetGUID(), SpellIds.Ignite, AuraType.PeriodicDamage);
|
||||
GetTarget().CastCustomSpell(SpellIds.Ignite, SpellValueMod.BasePoint0, amount, eventInfo.GetProcTarget(), true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 37447 - Improved Mana Gems
|
||||
[Script] // 61062 - Improved Mana Gems
|
||||
class spell_mage_imp_mana_gems : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ManaSurge);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
eventInfo.GetActor().CastSpell((Unit)null, SpellIds.ManaSurge, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 1, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 44457 - Living Bomb
|
||||
class spell_mage_living_bomb : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LivingBombPeriodic);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
GetCaster().CastCustomSpell(SpellIds.LivingBombPeriodic, SpellValueMod.BasePoint2, 1, GetHitUnit(), TriggerCastFlags.FullMask);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 44461 - Living Bomb
|
||||
class spell_mage_living_bomb_explosion : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return spellInfo.NeedsExplicitUnitTarget() && ValidateSpellInfo(SpellIds.LivingBombPeriodic);
|
||||
}
|
||||
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.Remove(GetExplTargetWorldObject());
|
||||
}
|
||||
|
||||
void HandleSpread(uint effIndex)
|
||||
{
|
||||
if (GetSpellValue().EffectBasePoints[0] > 0)
|
||||
GetCaster().CastCustomSpell(SpellIds.LivingBombPeriodic, SpellValueMod.BasePoint2, 0, GetHitUnit(), TriggerCastFlags.FullMask);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 1, Targets.UnitDestAreaEnemy));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleSpread, 1, SpellEffectName.SchoolDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 217694 - Living Bomb
|
||||
class spell_mage_living_bomb_periodic : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LivingBombExplosion);
|
||||
}
|
||||
|
||||
void AfterRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Expire)
|
||||
return;
|
||||
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
caster.CastCustomSpell(SpellIds.LivingBombExplosion, SpellValueMod.BasePoint0, aurEff.GetAmount(), GetTarget(), TriggerCastFlags.FullMask);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 2, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
// @todo move out of here and rename - not a mage spell
|
||||
[Script] // 32826 - Polymorph (Visual)
|
||||
class spell_mage_polymorph_visual : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(PolymorhForms);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit target = GetCaster().FindNearestCreature(NPC_AUROSALIA, 30.0f);
|
||||
if (target)
|
||||
if (target.IsTypeId(TypeId.Unit))
|
||||
target.CastSpell(target, PolymorhForms[RandomHelper.IRand(0, 5)], true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
// add dummy effect spell handler to Polymorph visual
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
|
||||
const uint NPC_AUROSALIA = 18744;
|
||||
uint[] PolymorhForms =
|
||||
{
|
||||
SpellIds.SquirrelForm,
|
||||
SpellIds.GiraffeForm,
|
||||
SpellIds.SerpentForm,
|
||||
SpellIds.DradonhawkForm,
|
||||
SpellIds.WorgenForm,
|
||||
SpellIds.SheepForm
|
||||
};
|
||||
}
|
||||
|
||||
[Script] // 235450 - Prismatic Barrier
|
||||
class spell_mage_prismatic_barrier : AuraScript
|
||||
{
|
||||
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
|
||||
{
|
||||
canBeRecalculated = false;
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
amount += (int)(caster.SpellBaseHealingBonusDone(GetSpellInfo().GetSchoolMask()) * 7.0f);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.SchoolAbsorb));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 136511 - Ring of Frost
|
||||
class spell_mage_ring_of_frost : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.RingOfFrostSummon, SpellIds.RingOfFrostFreeze);
|
||||
}
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect aurEff)
|
||||
{
|
||||
TempSummon ringOfFrost = GetRingOfFrostMinion();
|
||||
if (ringOfFrost)
|
||||
GetTarget().CastSpell(ringOfFrost.GetPositionX(), ringOfFrost.GetPositionY(), ringOfFrost.GetPositionZ(), SpellIds.RingOfFrostFreeze, true);
|
||||
}
|
||||
|
||||
void Apply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
List<TempSummon> minions = new List<TempSummon>();
|
||||
GetTarget().GetAllMinionsByEntry(minions, (uint)Global.SpellMgr.GetSpellInfo(SpellIds.RingOfFrostSummon).GetEffect(0).MiscValue);
|
||||
|
||||
// Get the last summoned RoF, save it and despawn older ones
|
||||
foreach (var summon in minions)
|
||||
{
|
||||
TempSummon ringOfFrost = GetRingOfFrostMinion();
|
||||
if (ringOfFrost)
|
||||
{
|
||||
if (summon.GetTimer() > ringOfFrost.GetTimer())
|
||||
{
|
||||
ringOfFrost.DespawnOrUnsummon();
|
||||
_ringOfFrostGUID = summon.GetGUID();
|
||||
}
|
||||
else
|
||||
summon.DespawnOrUnsummon();
|
||||
}
|
||||
else
|
||||
_ringOfFrostGUID = summon.GetGUID();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleEffectPeriodic, 0, AuraType.ProcTriggerSpell));
|
||||
OnEffectApply.Add(new EffectApplyHandler(Apply, 0, AuraType.ProcTriggerSpell, AuraEffectHandleModes.RealOrReapplyMask));
|
||||
}
|
||||
|
||||
TempSummon GetRingOfFrostMinion()
|
||||
{
|
||||
Creature creature = ObjectAccessor.GetCreature(GetOwner(), _ringOfFrostGUID);
|
||||
if (creature)
|
||||
return creature.ToTempSummon();
|
||||
return null;
|
||||
}
|
||||
|
||||
ObjectGuid _ringOfFrostGUID;
|
||||
}
|
||||
|
||||
[Script] // 82691 - Ring of Frost (freeze efect)
|
||||
class spell_mage_ring_of_frost_freeze : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.RingOfFrostSummon, SpellIds.RingOfFrostFreeze);
|
||||
}
|
||||
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
WorldLocation dest = GetExplTargetDest();
|
||||
float outRadius = Global.SpellMgr.GetSpellInfo(SpellIds.RingOfFrostSummon).GetEffect(0).CalcRadius();
|
||||
float inRadius = 6.5f;
|
||||
|
||||
targets.RemoveAll(target =>
|
||||
{
|
||||
Unit unit = target.ToUnit();
|
||||
if (!unit)
|
||||
return true;
|
||||
|
||||
return unit.HasAura(SpellIds.RingOfFrostDummy) || unit.HasAura(SpellIds.RingOfFrostFreeze) || unit.GetExactDist(GetExplTargetDest()) > outRadius || unit.GetExactDist(GetExplTargetDest()) < inRadius;
|
||||
});
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaEnemy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class spell_mage_ring_of_frost_freeze_AuraScript : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.RingOfFrostDummy);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Expire)
|
||||
if (GetCaster())
|
||||
GetCaster().CastSpell(GetTarget(), SpellIds.RingOfFrostDummy, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.ModStun, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 80353 - Time Warp
|
||||
class spell_mage_time_warp : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.TemporalDisplacement, SpellIds.HunterInsanity, SpellIds.ShamanExhaustion, SpellIds.ShamanSated, SpellIds.PetNetherwindsFatigued);
|
||||
}
|
||||
|
||||
void RemoveInvalidTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.TemporalDisplacement));
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.HunterInsanity));
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.ShamanExhaustion));
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.ShamanSated));
|
||||
}
|
||||
|
||||
void ApplyDebuff()
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
target.CastSpell(target, SpellIds.TemporalDisplacement, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(RemoveInvalidTargets, SpellConst.EffectAll, Targets.UnitCasterAreaRaid));
|
||||
AfterHit.Add(new HitHandler(ApplyDebuff));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] //228597 - Frostbolt 84721 - Frozen Orb 190357 - Blizzard
|
||||
class spell_mage_trigger_chilled : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Chilled);
|
||||
}
|
||||
|
||||
void HandleChilled()
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
GetCaster().CastSpell(target, SpellIds.Chilled, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnHit.Add(new HitHandler(HandleChilled));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 33395 Water Elemental's Freeze
|
||||
class spell_mage_water_elemental_freeze : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.FingersOfFrost);
|
||||
}
|
||||
|
||||
void HandleImprovedFreeze()
|
||||
{
|
||||
Unit owner = GetCaster().GetOwner();
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
owner.CastSpell(owner, SpellIds.FingersOfFrost, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterHit.Add(new HitHandler(HandleImprovedFreeze));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
|
||||
namespace Scripts.Spells.Monk
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint CracklingJadeLightningChannel = 117952;
|
||||
public const uint CracklingJadeLightningChiProc = 123333;
|
||||
public const uint CracklingJadeLightningKnockback = 117962;
|
||||
public const uint CracklingJadeLightningKnockbackCd = 117953;
|
||||
public const uint ProvokeSingleTarget = 116189;
|
||||
public const uint ProvokeAoe = 118635;
|
||||
public const uint SoothingMist = 115175;
|
||||
public const uint StanceOfTheSpiritedCrane = 154436;
|
||||
public const uint SurgingMistHeal = 116995;
|
||||
}
|
||||
|
||||
[Script] // 117952 - Crackling Jade Lightning
|
||||
class spell_monk_crackling_jade_lightning : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.StanceOfTheSpiritedCrane, SpellIds.CracklingJadeLightningChiProc);
|
||||
}
|
||||
|
||||
void OnTick(AuraEffect aurEff)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
if (caster.HasAura(SpellIds.StanceOfTheSpiritedCrane))
|
||||
caster.CastSpell(caster, SpellIds.CracklingJadeLightningChiProc, TriggerCastFlags.FullMask);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(OnTick, 0, AuraType.PeriodicDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 117959 - Crackling Jade Lightning
|
||||
class spell_monk_crackling_jade_lightning_knockback_proc_aura : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.CracklingJadeLightningKnockback, SpellIds.CracklingJadeLightningKnockbackCd);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
if (GetTarget().HasAura(SpellIds.CracklingJadeLightningKnockbackCd))
|
||||
return false;
|
||||
|
||||
if (eventInfo.GetActor().HasAura(SpellIds.CracklingJadeLightningChannel, GetTarget().GetGUID()))
|
||||
return false;
|
||||
|
||||
Spell currentChanneledSpell = GetTarget().GetCurrentSpell(CurrentSpellTypes.Channeled);
|
||||
if (!currentChanneledSpell || currentChanneledSpell.GetSpellInfo().Id != SpellIds.CracklingJadeLightningChannel)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
GetTarget().CastSpell(eventInfo.GetActor(), SpellIds.CracklingJadeLightningKnockback, TriggerCastFlags.FullMask);
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.CracklingJadeLightningKnockbackCd, TriggerCastFlags.FullMask);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 115546 - Provoke
|
||||
class spell_monk_provoke : SpellScript
|
||||
{
|
||||
const uint BlackOxStatusEntry = 61146;
|
||||
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
if (!spellInfo.GetExplicitTargetMask().HasAnyFlag(SpellCastTargetFlags.UnitMask)) // ensure GetExplTargetUnit() will return something meaningful during CheckCast
|
||||
return false;
|
||||
return ValidateSpellInfo(SpellIds.ProvokeSingleTarget, SpellIds.ProvokeAoe);
|
||||
}
|
||||
|
||||
SpellCastResult CheckExplicitTarget()
|
||||
{
|
||||
if (GetExplTargetUnit().GetEntry() != BlackOxStatusEntry)
|
||||
{
|
||||
SpellInfo singleTarget = Global.SpellMgr.GetSpellInfo(SpellIds.ProvokeSingleTarget);
|
||||
SpellCastResult singleTargetExplicitResult = singleTarget.CheckExplicitTarget(GetCaster(), GetExplTargetUnit());
|
||||
if (singleTargetExplicitResult != SpellCastResult.SpellCastOk)
|
||||
return singleTargetExplicitResult;
|
||||
}
|
||||
else if (GetExplTargetUnit().GetOwnerGUID() != GetCaster().GetGUID())
|
||||
return SpellCastResult.BadTargets;
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (GetHitUnit().GetEntry() != BlackOxStatusEntry)
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.ProvokeSingleTarget, true);
|
||||
else
|
||||
GetCaster().CastSpell(GetHitUnit(), SpellIds.ProvokeAoe, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckExplicitTarget));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,848 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Scripts.Spells.Paladin
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint AvengersShield = 31935;
|
||||
public const uint AuraMasteryImmune = 64364;
|
||||
public const uint BeaconOfLight = 53563;
|
||||
public const uint BeaconOfLightHeal = 53652;
|
||||
public const uint BlessingOfLowerCityDruid = 37878;
|
||||
public const uint BlessingOfLowerCityPaladin = 37879;
|
||||
public const uint BlessingOfLowerCityPriest = 37880;
|
||||
public const uint BlessingOfLowerCityShaman = 37881;
|
||||
public const uint ConcentractionAura = 19746;
|
||||
public const uint DivinePurposeProc = 90174;
|
||||
public const uint DivineSteedHuman = 221883;
|
||||
public const uint DivineSteedDraenei = 221887;
|
||||
public const uint DivineSteedBloodelf = 221886;
|
||||
public const uint DivineSteedTauren = 221885;
|
||||
public const uint DivineStormDamage = 224239;
|
||||
public const uint EnduringLight = 40471;
|
||||
public const uint EnduringJudgement = 40472;
|
||||
public const uint EyeForAnEyeRank1 = 9799;
|
||||
public const uint EyeForAnEyeDamage = 25997;
|
||||
public const uint Forbearance = 25771;
|
||||
public const uint HandOfSacrifice = 6940;
|
||||
public const uint HolyMending = 64891;
|
||||
public const uint HolyPowerArmor = 28790;
|
||||
public const uint HolyPowerAttackPower = 28791;
|
||||
public const uint HolyPowerSpellPower = 28793;
|
||||
public const uint HolyPowerMp5 = 28795;
|
||||
public const uint HolyShockR1 = 20473;
|
||||
public const uint HolyShockR1Damage = 25912;
|
||||
public const uint HolyShockR1Healing = 25914;
|
||||
public const uint ImmuneShieldMarker = 61988;
|
||||
public const uint ItemHealingTrance = 37706;
|
||||
public const uint JudgementDamage = 54158;
|
||||
public const uint RighteousDefenseTaunt = 31790;
|
||||
public const uint SealOfCommand = 105361;
|
||||
public const uint SealOfRighteousness = 25742;
|
||||
}
|
||||
|
||||
// 31821 - Aura Mastery
|
||||
[Script]
|
||||
class spell_pal_aura_mastery : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.AuraMasteryImmune);
|
||||
}
|
||||
|
||||
void HandleEffectApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.AuraMasteryImmune, true);
|
||||
}
|
||||
|
||||
void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().RemoveOwnedAura(SpellIds.AuraMasteryImmune, GetCasterGUID());
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(HandleEffectApply, 0, AuraType.AddPctModifier, AuraEffectHandleModes.Real));
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.AddPctModifier, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
|
||||
// 64364 - Aura Mastery Immune
|
||||
[Script]
|
||||
class spell_pal_aura_mastery_immune : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ConcentractionAura);
|
||||
}
|
||||
|
||||
bool CheckAreaTarget(Unit target)
|
||||
{
|
||||
return target.HasAura(SpellIds.ConcentractionAura, GetCasterGUID());
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckAreaTarget.Add(new CheckAreaTargetHandler(CheckAreaTarget));
|
||||
}
|
||||
}
|
||||
|
||||
// 37877 - Blessing of Faith
|
||||
[Script]
|
||||
class spell_pal_blessing_of_faith : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.BlessingOfLowerCityDruid, SpellIds.BlessingOfLowerCityPaladin, SpellIds.BlessingOfLowerCityPriest, SpellIds.BlessingOfLowerCityShaman);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit unitTarget = GetHitUnit();
|
||||
if (unitTarget)
|
||||
{
|
||||
uint spell_id = 0;
|
||||
switch (unitTarget.GetClass())
|
||||
{
|
||||
case Class.Druid:
|
||||
spell_id = SpellIds.BlessingOfLowerCityDruid;
|
||||
break;
|
||||
case Class.Paladin:
|
||||
spell_id = SpellIds.BlessingOfLowerCityPaladin;
|
||||
break;
|
||||
case Class.Priest:
|
||||
spell_id = SpellIds.BlessingOfLowerCityPriest;
|
||||
break;
|
||||
case Class.Shaman:
|
||||
spell_id = SpellIds.BlessingOfLowerCityShaman;
|
||||
break;
|
||||
default:
|
||||
return; // ignore for non-healing classes
|
||||
}
|
||||
Unit caster = GetCaster();
|
||||
caster.CastSpell(caster, spell_id, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 190784 - Divine Steed
|
||||
class spell_pal_divine_steed : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.DivineSteedHuman, SpellIds.DivineSteedDraenei, SpellIds.DivineSteedBloodelf, SpellIds.DivineSteedTauren);
|
||||
}
|
||||
|
||||
void HandleOnCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
|
||||
uint spellId = SpellIds.DivineSteedHuman;
|
||||
switch (caster.GetRace())
|
||||
{
|
||||
case Race.Draenei:
|
||||
spellId = SpellIds.DivineSteedDraenei;
|
||||
break;
|
||||
case Race.BloodElf:
|
||||
spellId = SpellIds.DivineSteedBloodelf;
|
||||
break;
|
||||
case Race.Tauren:
|
||||
spellId = SpellIds.DivineSteedTauren;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
caster.CastSpell(caster, spellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCast.Add(new CastHandler(HandleOnCast));
|
||||
}
|
||||
}
|
||||
|
||||
// 224239 - Divine Storm
|
||||
[Script]
|
||||
class spell_pal_divine_storm : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.DivineStormDamage);
|
||||
}
|
||||
|
||||
void HandleOnCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
caster.SendPlaySpellVisualKit(73892, 0, 0);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
Unit target = GetHitUnit();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
caster.CastSpell(target, SpellIds.DivineStormDamage, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCast.Add(new CastHandler(HandleOnCast));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 33695 - Exorcism and Holy Wrath Damage
|
||||
[Script]
|
||||
class spell_pal_exorcism_and_holy_wrath_damage : AuraScript
|
||||
{
|
||||
void HandleEffectCalcSpellMod(AuraEffect aurEff, ref SpellModifier spellMod)
|
||||
{
|
||||
if (spellMod == null)
|
||||
{
|
||||
spellMod = new SpellModifier(aurEff.GetBase());
|
||||
spellMod.op = SpellModOp.Damage;
|
||||
spellMod.type = SpellModType.Flat;
|
||||
spellMod.spellId = GetId();
|
||||
spellMod.mask[1] = 0x200002;
|
||||
}
|
||||
|
||||
spellMod.value = aurEff.GetAmount();
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoEffectCalcSpellMod.Add(new EffectCalcSpellModHandler(HandleEffectCalcSpellMod, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// -9799 - Eye for an Eye
|
||||
[Script]
|
||||
class spell_pal_eye_for_an_eye : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.EyeForAnEyeDamage);
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
DamageInfo damageInfo = eventInfo.GetDamageInfo();
|
||||
if (damageInfo == null || damageInfo.GetDamage() == 0)
|
||||
return;
|
||||
|
||||
int damage = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount());
|
||||
GetTarget().CastCustomSpell(SpellIds.EyeForAnEyeDamage, SpellValueMod.BasePoint0, damage, eventInfo.GetProcTarget(), true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, m_scriptSpellId == SpellIds.EyeForAnEyeRank1 ? AuraType.Dummy : AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
// -75806 - Grand Crusader
|
||||
[Script]
|
||||
class spell_pal_grand_crusader : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.AvengersShield);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
return GetTarget().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
GetTarget().GetSpellHistory().ResetCooldown(SpellIds.AvengersShield, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
// 54968 - Glyph of Holy Light
|
||||
[Script]
|
||||
class spell_pal_glyph_of_holy_light : SpellScript
|
||||
{
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
uint maxTargets = GetSpellInfo().MaxAffectedTargets;
|
||||
|
||||
if (targets.Count > maxTargets)
|
||||
{
|
||||
targets.Sort(new HealthPctOrderPred());
|
||||
targets.Resize(maxTargets);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaAlly));
|
||||
}
|
||||
}
|
||||
|
||||
// 6940 - Hand of Sacrifice
|
||||
[Script]
|
||||
class spell_pal_hand_of_sacrifice : AuraScript
|
||||
{
|
||||
int remainingAmount;
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
{
|
||||
remainingAmount = (int)caster.GetMaxHealth();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Split(AuraEffect aurEff, DamageInfo dmgInfo, uint splitAmount)
|
||||
{
|
||||
remainingAmount -= (int)splitAmount;
|
||||
|
||||
if (remainingAmount <= 0)
|
||||
{
|
||||
GetTarget().RemoveAura(SpellIds.HandOfSacrifice);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectSplit.Add(new EffectSplitHandler(Split, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// 20473 - Holy Shock
|
||||
[Script]
|
||||
class spell_pal_holy_shock : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
SpellInfo firstRankSpellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.HolyShockR1);
|
||||
if (firstRankSpellInfo == null)
|
||||
return false;
|
||||
|
||||
// can't use other spell than holy shock due to spell_ranks dependency
|
||||
if (!spellInfo.IsRankOf(firstRankSpellInfo))
|
||||
return false;
|
||||
|
||||
byte rank = spellInfo.GetRank();
|
||||
if (Global.SpellMgr.GetSpellWithRank(SpellIds.HolyShockR1Damage, rank, true) == 0 || Global.SpellMgr.GetSpellWithRank(SpellIds.HolyShockR1Healing, rank, true) == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
Unit unitTarget = GetHitUnit();
|
||||
if (unitTarget)
|
||||
{
|
||||
byte rank = GetSpellInfo().GetRank();
|
||||
if (caster.IsFriendlyTo(unitTarget))
|
||||
caster.CastSpell(unitTarget, Global.SpellMgr.GetSpellWithRank(SpellIds.HolyShockR1Healing, rank), true);
|
||||
else
|
||||
caster.CastSpell(unitTarget, Global.SpellMgr.GetSpellWithRank(SpellIds.HolyShockR1Damage, rank), true);
|
||||
}
|
||||
}
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
Unit target = GetExplTargetUnit();
|
||||
if (target)
|
||||
{
|
||||
if (!caster.IsFriendlyTo(target))
|
||||
{
|
||||
if (!caster.IsValidAttackTarget(target))
|
||||
return SpellCastResult.BadTargets;
|
||||
|
||||
if (!caster.isInFront(target))
|
||||
return SpellCastResult.NotInfront;
|
||||
}
|
||||
}
|
||||
else
|
||||
return SpellCastResult.BadTargets;
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 37705 - Healing Discount
|
||||
[Script]
|
||||
class spell_pal_item_healing_discount : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ItemHealingTrance);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.ItemHealingTrance, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 40470 - Paladin Tier 6 Trinket
|
||||
class spell_pal_item_t6_trinket : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.EnduringLight, SpellIds.EnduringJudgement);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
SpellInfo spellInfo = eventInfo.GetSpellInfo();
|
||||
if (spellInfo == null)
|
||||
return;
|
||||
|
||||
uint spellId;
|
||||
int chance;
|
||||
|
||||
// Holy Light & Flash of Light
|
||||
if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0xC0000000))
|
||||
{
|
||||
spellId = SpellIds.EnduringLight;
|
||||
chance = 15;
|
||||
}
|
||||
// Judgements
|
||||
else if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00800000u))
|
||||
{
|
||||
spellId = SpellIds.EnduringJudgement;
|
||||
chance = 50;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if (RandomHelper.randChance(chance))
|
||||
eventInfo.GetActor().CastSpell(eventInfo.GetProcTarget(), spellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 20271 - Judgement
|
||||
// Updated 4.3.4
|
||||
[Script]
|
||||
class spell_pal_judgement : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.JudgementDamage);
|
||||
}
|
||||
|
||||
void HandleScriptEffect(uint effIndex)
|
||||
{
|
||||
uint spellId = SpellIds.JudgementDamage;
|
||||
|
||||
// some seals have SPELL_AURA_DUMMY in EFFECT_2
|
||||
var auras = GetCaster().GetAuraEffectsByType(AuraType.Dummy);
|
||||
foreach (var eff in auras)
|
||||
{
|
||||
if (eff.GetSpellInfo().GetSpellSpecific() == SpellSpecificType.Seal && eff.GetEffIndex() == 2)
|
||||
{
|
||||
if (Global.SpellMgr.HasSpellInfo((uint)eff.GetAmount()))
|
||||
{
|
||||
spellId = (uint)eff.GetAmount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetCaster().CastSpell(GetHitUnit(), spellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 633 - Lay on Hands
|
||||
[Script]
|
||||
class spell_pal_lay_on_hands : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spell)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Forbearance, SpellIds.ImmuneShieldMarker);
|
||||
}
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
Unit target = GetExplTargetUnit();
|
||||
if (target)
|
||||
{
|
||||
if (caster == target)
|
||||
{
|
||||
if (target.HasAura(SpellIds.Forbearance) || target.HasAura(SpellIds.ImmuneShieldMarker))
|
||||
return SpellCastResult.TargetAurastate;
|
||||
}
|
||||
}
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
void HandleScript()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster == GetHitUnit())
|
||||
{
|
||||
caster.CastSpell(caster, SpellIds.Forbearance, true);
|
||||
caster.CastSpell(caster, SpellIds.ImmuneShieldMarker, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
AfterHit.Add(new HitHandler(HandleScript));
|
||||
}
|
||||
}
|
||||
|
||||
// 53651 - Beacon of Light
|
||||
[Script]
|
||||
class spell_pal_light_s_beacon : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.BeaconOfLight, SpellIds.BeaconOfLightHeal);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
if (!eventInfo.GetActionTarget())
|
||||
return false;
|
||||
if (eventInfo.GetActionTarget().HasAura(SpellIds.BeaconOfLight, eventInfo.GetActor().GetGUID()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
HealInfo healInfo = eventInfo.GetHealInfo();
|
||||
if (healInfo == null || healInfo.GetHeal() == 0)
|
||||
return;
|
||||
|
||||
uint heal = MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount());
|
||||
|
||||
var auras = GetCaster().GetSingleCastAuras();
|
||||
foreach (var eff in auras)
|
||||
{
|
||||
if (eff.GetId() == SpellIds.BeaconOfLight)
|
||||
{
|
||||
List<AuraApplication> applications = eff.GetApplicationList();
|
||||
if (!applications.Empty())
|
||||
eventInfo.GetActor().CastCustomSpell(SpellIds.BeaconOfLightHeal, SpellValueMod.BasePoint0, (int)heal, applications.First().GetTarget(), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
// 31789 - Righteous Defense
|
||||
[Script]
|
||||
class spell_pal_righteous_defense : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.RighteousDefenseTaunt);
|
||||
}
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (!caster.IsTypeId(TypeId.Player))
|
||||
return SpellCastResult.DontReport;
|
||||
|
||||
Unit target = GetExplTargetUnit();
|
||||
if (target)
|
||||
{
|
||||
if (!target.IsFriendlyTo(caster) || target.getAttackers().Empty())
|
||||
return SpellCastResult.BadTargets;
|
||||
}
|
||||
else
|
||||
return SpellCastResult.BadTargets;
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
void HandleTriggerSpellLaunch(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
}
|
||||
|
||||
void HandleTriggerSpellHit(uint effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
GetCaster().CastSpell(target, SpellIds.RighteousDefenseTaunt, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
//! WORKAROUND
|
||||
//! target select will be executed in hitphase of effect 0
|
||||
//! so we must handle trigger spell also in hit phase (default execution in launch phase)
|
||||
//! see issue #3718
|
||||
OnEffectLaunchTarget.Add(new EffectHandler(HandleTriggerSpellLaunch, 1, SpellEffectName.TriggerSpell));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleTriggerSpellHit, 1, SpellEffectName.TriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
// 85285 - Sacred Shield
|
||||
[Script]
|
||||
class spell_pal_sacred_shield : SpellScript
|
||||
{
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (!caster.IsTypeId(TypeId.Player))
|
||||
return SpellCastResult.DontReport;
|
||||
|
||||
if (!caster.HealthBelowPct(30))
|
||||
return SpellCastResult.CantDoThatRightNow;
|
||||
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnCheckCast.Add(new CheckCastHandler(CheckCast));
|
||||
}
|
||||
};
|
||||
|
||||
// 85256 - Templar's Verdict
|
||||
// Updated 4.3.4
|
||||
[Script]
|
||||
class spell_pal_templar_s_verdict : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellEntry)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.DivinePurposeProc);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
if (!GetCaster().IsTypeId(TypeId.Player))
|
||||
return false;
|
||||
|
||||
if (GetCaster().ToPlayer().GetClass() != Class.Paladin)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChangeDamage(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
float damage = GetHitDamage();
|
||||
|
||||
if (caster.HasAura(SpellIds.DivinePurposeProc))
|
||||
damage *= 7.5f; // 7.5*30% = 225%
|
||||
else
|
||||
{
|
||||
switch (caster.GetPower(PowerType.HolyPower))
|
||||
{
|
||||
case 0: // 1 Holy Power
|
||||
//damage = damage;
|
||||
break;
|
||||
case 1: // 2 Holy Power
|
||||
damage *= 3; // 3*30 = 90%
|
||||
break;
|
||||
case 2: // 3 Holy Power
|
||||
damage *= 7.5f; // 7.5*30% = 225%
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetHitDamage((int)damage);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(ChangeDamage, 0, SpellEffectName.WeaponPercentDamage));
|
||||
}
|
||||
}
|
||||
|
||||
// 20154, 21084 - Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage)
|
||||
[Script]
|
||||
class spell_pal_seal_of_righteousness : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.SealOfCommand);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
return eventInfo.GetProcTarget();
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
float ap = GetTarget().GetTotalAttackPowerValue(WeaponAttackType.BaseAttack);
|
||||
int holy = GetTarget().SpellBaseDamageBonusDone(SpellSchoolMask.Holy);
|
||||
holy += eventInfo.GetProcTarget().SpellBaseDamageBonusTaken(SpellSchoolMask.Holy);
|
||||
int bp = (int)((ap * 0.022f + 0.044f * holy) * GetTarget().GetBaseAttackTime(WeaponAttackType.BaseAttack) / 1000);
|
||||
GetTarget().CastCustomSpell(SpellIds.SealOfCommand, SpellValueMod.BasePoint0, bp, eventInfo.GetProcTarget(), true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 28789 - Holy Power
|
||||
class spell_pal_t3_6p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.HolyPowerArmor, SpellIds.HolyPowerAttackPower, SpellIds.HolyPowerSpellPower, SpellIds.HolyPowerMp5);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
uint spellId;
|
||||
Unit caster = eventInfo.GetActor();
|
||||
Unit target = eventInfo.GetProcTarget();
|
||||
|
||||
switch (target.GetClass())
|
||||
{
|
||||
case Class.Paladin:
|
||||
case Class.Priest:
|
||||
case Class.Shaman:
|
||||
case Class.Druid:
|
||||
spellId = SpellIds.HolyPowerMp5;
|
||||
break;
|
||||
case Class.Mage:
|
||||
case Class.Warlock:
|
||||
spellId = SpellIds.HolyPowerSpellPower;
|
||||
break;
|
||||
case Class.Hunter:
|
||||
case Class.Rogue:
|
||||
spellId = SpellIds.HolyPowerAttackPower;
|
||||
break;
|
||||
case Class.Warrior:
|
||||
spellId = SpellIds.HolyPowerArmor;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
caster.CastSpell(target, spellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 64890 Item - Paladin T8 Holy 2P Bonus
|
||||
class spell_pal_t8_2p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.HolyMending);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
HealInfo healInfo = eventInfo.GetHealInfo();
|
||||
if (healInfo == null || healInfo.GetHeal() == 0)
|
||||
return;
|
||||
|
||||
Unit caster = eventInfo.GetActor();
|
||||
Unit target = eventInfo.GetProcTarget();
|
||||
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.HolyMending);
|
||||
int amount = (int)MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount());
|
||||
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
|
||||
// Add remaining ticks to damage done
|
||||
amount += (int)target.GetRemainingPeriodicAmount(caster.GetGUID(), SpellIds.HolyMending, AuraType.PeriodicHeal);
|
||||
|
||||
caster.CastCustomSpell(SpellIds.HolyMending, SpellValueMod.BasePoint0, amount, target, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Spells.Rogue
|
||||
{
|
||||
public struct SpellIds
|
||||
{
|
||||
public const uint BladeFlurryExtraAttack = 22482;
|
||||
public const uint CheatDeathCooldown = 31231;
|
||||
public const uint GlyphOfPreparation = 56819;
|
||||
public const uint KillingSpree = 51690;
|
||||
public const uint KillingSpreeTeleport = 57840;
|
||||
public const uint KillingSpreeWeaponDmg = 57841;
|
||||
public const uint KillingSpreeDmgBuff = 61851;
|
||||
public const uint PreyOnTheWeak = 58670;
|
||||
public const uint ShivTriggered = 5940;
|
||||
public const uint TricksOfTheTradeDmgBoost = 57933;
|
||||
public const uint TricksOfTheTradeProc = 59628;
|
||||
public const uint SerratedBladesR1 = 14171;
|
||||
public const uint Rupture = 1943;
|
||||
public const uint HonorAmongThievesEnergize = 51699;
|
||||
public const uint T52pSetBonus = 37169;
|
||||
}
|
||||
|
||||
[Script] // 51690 - Killing Spree
|
||||
class spell_rog_killing_spree : SpellScript
|
||||
{
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
if (targets.Empty() || GetCaster().GetVehicleBase())
|
||||
FinishCast(SpellCastResult.OutOfRange);
|
||||
}
|
||||
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Aura aura = GetCaster().GetAura(SpellIds.KillingSpree);
|
||||
if (aura != null)
|
||||
{
|
||||
var script = aura.GetScript<spell_rog_killing_spree_AuraScript>(nameof(spell_rog_killing_spree_AuraScript));
|
||||
if (script != null)
|
||||
script.AddTarget(GetHitUnit());
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 1, Targets.UnitDestAreaEnemy));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 1, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
public class spell_rog_killing_spree_AuraScript : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.KillingSpreeTeleport, SpellIds.KillingSpreeWeaponDmg, SpellIds.KillingSpreeDmgBuff);
|
||||
}
|
||||
|
||||
void HandleApply(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.KillingSpreeDmgBuff, true);
|
||||
}
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect aurEff)
|
||||
{
|
||||
while (!_targets.Empty())
|
||||
{
|
||||
ObjectGuid guid = _targets.SelectRandom();
|
||||
Unit target = Global.ObjAccessor.GetUnit(GetTarget(), guid);
|
||||
if (target)
|
||||
{
|
||||
GetTarget().CastSpell(target, SpellIds.KillingSpreeTeleport, true);
|
||||
GetTarget().CastSpell(target, SpellIds.KillingSpreeWeaponDmg, true);
|
||||
break;
|
||||
}
|
||||
else
|
||||
_targets.Remove(guid);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
GetTarget().RemoveAurasDueToSpell(SpellIds.KillingSpreeDmgBuff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectApply.Add(new EffectApplyHandler(HandleApply, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleEffectPeriodic, 0, AuraType.PeriodicDummy));
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(HandleRemove, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.Real));
|
||||
}
|
||||
|
||||
public void AddTarget(Unit target)
|
||||
{
|
||||
_targets.Add(target.GetGUID());
|
||||
}
|
||||
|
||||
List<ObjectGuid> _targets = new List<ObjectGuid>();
|
||||
}
|
||||
|
||||
[Script] // 2098 - Eviscerate
|
||||
class spell_rog_eviscerate : SpellScript
|
||||
{
|
||||
void CalculateDamage(uint effIndex)
|
||||
{
|
||||
int damagePerCombo = (int)(GetCaster().GetTotalAttackPowerValue(WeaponAttackType.BaseAttack) * 0.559f);
|
||||
AuraEffect t5 = GetCaster().GetAuraEffect(SpellIds.T52pSetBonus, 0);
|
||||
if (t5 != null)
|
||||
damagePerCombo += t5.GetAmount();
|
||||
|
||||
SetEffectValue(GetEffectValue() + damagePerCombo * GetCaster().GetPower(PowerType.ComboPoints));
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectLaunchTarget.Add(new EffectHandler(CalculateDamage, 0, SpellEffectName.SchoolDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 32645 - Envenom
|
||||
class spell_rog_envenom : SpellScript
|
||||
{
|
||||
void CalculateDamage(uint effIndex)
|
||||
{
|
||||
int damagePerCombo = (int)(GetCaster().GetTotalAttackPowerValue(WeaponAttackType.BaseAttack) * 0.417f);
|
||||
AuraEffect t5 = GetCaster().GetAuraEffect(SpellIds.T52pSetBonus, 0);
|
||||
if (t5 != null)
|
||||
damagePerCombo += t5.GetAmount();
|
||||
|
||||
SetEffectValue(GetEffectValue() + damagePerCombo * GetCaster().GetPower(PowerType.ComboPoints));
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectLaunchTarget.Add(new EffectHandler(CalculateDamage, 0, SpellEffectName.SchoolDamage));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,895 @@
|
||||
/*
|
||||
* 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 Framework.Dynamic;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.Spells.Shaman
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint AncestralGuidance = 108281;
|
||||
public const uint AncestralGuidanceHeal = 114911;
|
||||
public const uint ChainedHeal = 70809;
|
||||
public const uint CrashLightningCleave = 187878;
|
||||
public const uint EarthShieldHeal = 204290;
|
||||
public const uint EarthenRagePassive = 170374;
|
||||
public const uint EarthenRagePeriodic = 170377;
|
||||
public const uint EarthenRageDamage = 170379;
|
||||
public const uint Electrified = 64930;
|
||||
public const uint ElementalBlastCrit = 118522;
|
||||
public const uint ElementalBlastHaste = 173183;
|
||||
public const uint ElementalBlastMastery = 173184;
|
||||
public const uint ElementalMastery = 16166;
|
||||
public const uint EnergySurge = 40465;
|
||||
public const uint Exhaustion = 57723;
|
||||
public const uint FireNovaTriggered = 8349;
|
||||
public const uint FlameShock = 8050;
|
||||
public const uint FlameShockMaelstrom = 188389;
|
||||
public const uint FlametongueAttack = 10444;
|
||||
public const uint GatheringStorms = 198299;
|
||||
public const uint GatheringStormsBuff = 198300;
|
||||
public const uint HighTide = 157154;
|
||||
public const uint ItemLightningShield = 23552;
|
||||
public const uint ItemLightningShieldDamage = 27635;
|
||||
public const uint ItemManaSurge = 23571;
|
||||
public const uint LavaBurst = 51505;
|
||||
public const uint LavaBurstBonusDamage = 71824;
|
||||
public const uint LavaLashSpreadFlameShock = 105792;
|
||||
public const uint LavaSurge = 77762;
|
||||
public const uint PathOfFlamesSpread = 210621;
|
||||
public const uint PathOfFlamesTalent = 201909;
|
||||
public const uint PowerSurge = 40466;
|
||||
public const uint Sated = 57724;
|
||||
public const uint TidalWaves = 53390;
|
||||
public const uint TotemicPowerMp5 = 28824;
|
||||
public const uint TotemicPowerSpellPower = 28825;
|
||||
public const uint TotemicPowerAttackPower = 28826;
|
||||
public const uint TotemicPowerArmor = 28827;
|
||||
public const uint WindfuryAttack = 25504;
|
||||
|
||||
//Misc
|
||||
public const uint HunterInsanity = 95809;
|
||||
public const uint MageTemporalDisplacement = 80354;
|
||||
public const uint PetNetherwindsFatigued = 160455;
|
||||
}
|
||||
|
||||
[Script] // 108281 - Ancestral Guidance
|
||||
class spell_sha_ancestral_guidance : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.AncestralGuidanceHeal);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
if (eventInfo.GetHealInfo().GetSpellInfo().Id == SpellIds.AncestralGuidanceHeal)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
int bp0 = MathFunctions.CalculatePct((int)eventInfo.GetDamageInfo().GetDamage(), aurEff.GetAmount());
|
||||
if (bp0 != 0)
|
||||
eventInfo.GetActor().CastCustomSpell(SpellIds.AncestralGuidanceHeal, SpellValueMod.BasePoint0, bp0, eventInfo.GetActor(), true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 114911 - Ancestral Guidance Heal
|
||||
class spell_sha_ancestral_guidance_heal : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.AncestralGuidance);
|
||||
}
|
||||
|
||||
void ResizeTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.Resize(3);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(ResizeTargets, 0, Targets.UnitDestAreaAlly));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 2825 - Bloodlust
|
||||
class spell_sha_bloodlust : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Sated, SpellIds.HunterInsanity, SpellIds.MageTemporalDisplacement, SpellIds.PetNetherwindsFatigued);
|
||||
}
|
||||
|
||||
void RemoveInvalidTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.Sated));
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.HunterInsanity));
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.MageTemporalDisplacement));
|
||||
}
|
||||
|
||||
void ApplyDebuff()
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
target.CastSpell(target, SpellIds.Sated, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(RemoveInvalidTargets, 0, Targets.UnitCasterAreaRaid));
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(RemoveInvalidTargets, 1, Targets.UnitCasterAreaRaid));
|
||||
AfterHit.Add(new HitHandler(ApplyDebuff));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 187874 - Crash Lightning
|
||||
class spell_sha_crash_lightning : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.CrashLightningCleave);
|
||||
}
|
||||
|
||||
void CountTargets(List<WorldObject> targets)
|
||||
{
|
||||
_targetsHit = targets.Count;
|
||||
}
|
||||
|
||||
void TriggerCleaveBuff()
|
||||
{
|
||||
if (_targetsHit >= 2)
|
||||
GetCaster().CastSpell(GetCaster(), SpellIds.CrashLightningCleave, true);
|
||||
|
||||
AuraEffect gatheringStorms = GetCaster().GetAuraEffect(SpellIds.GatheringStorms, 0);
|
||||
if (gatheringStorms != null)
|
||||
GetCaster().CastCustomSpell(SpellIds.GatheringStormsBuff, SpellValueMod.BasePoint0, (int)(gatheringStorms.GetAmount() * _targetsHit), GetCaster(), true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(CountTargets, 0, Targets.UnitConeEnemy104));
|
||||
AfterCast.Add(new CastHandler(TriggerCleaveBuff));
|
||||
}
|
||||
|
||||
int _targetsHit = 0;
|
||||
}
|
||||
|
||||
[Script] // 204288 - Earth Shield
|
||||
class spell_sha_earth_shield : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.EarthShieldHeal);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
if (eventInfo.GetDamageInfo() == null || !HasEffect(1) || eventInfo.GetDamageInfo().GetDamage() < GetTarget().CountPctFromMaxHealth(GetEffect(1).GetAmount()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.EarthShieldHeal, true, null, aurEff, GetCasterGUID());
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 1, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 170374 - Earthen Rage (Passive)
|
||||
public class spell_sha_earthen_rage_passive : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.EarthenRagePeriodic, SpellIds.EarthenRageDamage);
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
_procTargetGuid = eventInfo.GetProcTarget().GetGUID();
|
||||
eventInfo.GetActor().CastSpell(eventInfo.GetActor(), SpellIds.EarthenRagePeriodic, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy));
|
||||
}
|
||||
|
||||
public ObjectGuid GetProcTargetGuid()
|
||||
{
|
||||
return _procTargetGuid;
|
||||
}
|
||||
|
||||
ObjectGuid _procTargetGuid;
|
||||
}
|
||||
|
||||
[Script] // 170377 - Earthen Rage (Proc Aura)
|
||||
class spell_sha_earthen_rage_proc_aura : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.EarthenRagePassive, SpellIds.EarthenRageDamage);
|
||||
}
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Aura aura = GetCaster().GetAura(SpellIds.EarthenRagePassive);
|
||||
if (aura != null)
|
||||
{
|
||||
var earthen_rage_script = aura.GetScript<spell_sha_earthen_rage_passive>("spell_sha_earthen_rage_passive");
|
||||
if (earthen_rage_script != null)
|
||||
{
|
||||
Unit procTarget = Global.ObjAccessor.GetUnit(GetCaster(), earthen_rage_script.GetProcTargetGuid());
|
||||
if (procTarget)
|
||||
GetTarget().CastSpell(procTarget, SpellIds.EarthenRageDamage, true);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleEffectPeriodic, 0, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 117014 - Elemental Blast
|
||||
class spell_sha_elemental_blast : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ElementalBlastCrit, SpellIds.ElementalBlastHaste, SpellIds.ElementalBlastMastery);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void TriggerBuff()
|
||||
{
|
||||
Player caster = GetCaster().ToPlayer();
|
||||
uint spellId = RandomHelper.RAND(SpellIds.ElementalBlastCrit, SpellIds.ElementalBlastHaste, SpellIds.ElementalBlastMastery);
|
||||
|
||||
caster.CastSpell(caster, spellId, TriggerCastFlags.FullMask);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterCast.Add(new CastHandler(TriggerBuff));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 1535 Fire Nova
|
||||
class spell_sha_fire_nova : SpellScript
|
||||
{
|
||||
void HandleDummy(uint effIndex)
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
if (target.HasAura(SpellIds.FlameShock))
|
||||
GetCaster().CastSpell(target, SpellIds.FireNovaTriggered, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 194084 - Flametongue
|
||||
class spell_sha_flametongue : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.FlametongueAttack);
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
Unit attacker = eventInfo.GetActor();
|
||||
int damage = (int)(attacker.GetTotalAttackPowerValue(WeaponAttackType.BaseAttack) * 0.12f / 2600 * attacker.GetBaseAttackTime(WeaponAttackType.BaseAttack));
|
||||
attacker.CastCustomSpell(SpellIds.FlametongueAttack, SpellValueMod.BasePoint0, damage, eventInfo.GetActionTarget(), TriggerCastFlags.FullMask, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 52042 - Healing Stream Totem
|
||||
class spell_sha_healing_stream_totem_heal : SpellScript
|
||||
{
|
||||
void SelectTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.RemoveAll(target =>
|
||||
{
|
||||
return !target.ToUnit() || target.ToUnit().IsFullHealth();
|
||||
});
|
||||
|
||||
targets.RandomResize(1);
|
||||
|
||||
if (targets.Empty())
|
||||
targets.Add(GetOriginalCaster());
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(SelectTargets, 0, Targets.UnitDestAreaAlly));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 32182 - Heroism
|
||||
class spell_sha_heroism : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Exhaustion, SpellIds.HunterInsanity, SpellIds.MageTemporalDisplacement, SpellIds.PetNetherwindsFatigued);
|
||||
}
|
||||
|
||||
void RemoveInvalidTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.Exhaustion));
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.HunterInsanity));
|
||||
targets.RemoveAll(new UnitAuraCheck<WorldObject>(true, SpellIds.MageTemporalDisplacement));
|
||||
}
|
||||
|
||||
void ApplyDebuff()
|
||||
{
|
||||
Unit target = GetHitUnit();
|
||||
if (target)
|
||||
target.CastSpell(target, SpellIds.Exhaustion, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(RemoveInvalidTargets, 0, Targets.UnitCasterAreaRaid));
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(RemoveInvalidTargets, 1, Targets.UnitCasterAreaRaid));
|
||||
AfterHit.Add(new HitHandler(ApplyDebuff));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 23551 - Lightning Shield T2 Bonus
|
||||
class spell_sha_item_lightning_shield : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ItemLightningShield);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastSpell(eventInfo.GetProcTarget(), SpellIds.ItemLightningShield, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 23552 - Lightning Shield T2 Bonus
|
||||
class spell_sha_item_lightning_shield_trigger : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ItemLightningShieldDamage);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.ItemLightningShieldDamage, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 23572 - Mana Surge
|
||||
class spell_sha_item_mana_surge : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ItemManaSurge);
|
||||
}
|
||||
|
||||
bool CheckProc(ProcEventInfo eventInfo)
|
||||
{
|
||||
return eventInfo.GetProcSpell() != null;
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
var costs = eventInfo.GetProcSpell().GetPowerCost();
|
||||
var m = costs.Find(cost => cost.Power == PowerType.Mana);
|
||||
if (m != null)
|
||||
{
|
||||
int mana = MathFunctions.CalculatePct(m.Amount, 35);
|
||||
if (mana > 0)
|
||||
GetTarget().CastCustomSpell(SpellIds.ItemManaSurge, SpellValueMod.BasePoint0, mana, GetTarget(), true, null, aurEff);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
DoCheckProc.Add(new CheckProcHandler(CheckProc));
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 40463 - Shaman Tier 6 Trinket
|
||||
class spell_sha_item_t6_trinket : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.EnergySurge, SpellIds.PowerSurge);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
SpellInfo spellInfo = eventInfo.GetSpellInfo();
|
||||
if (spellInfo == null)
|
||||
return;
|
||||
|
||||
uint spellId;
|
||||
int chance;
|
||||
|
||||
// Lesser Healing Wave
|
||||
if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00000080u))
|
||||
{
|
||||
spellId = SpellIds.EnergySurge;
|
||||
chance = 10;
|
||||
}
|
||||
// Lightning Bolt
|
||||
else if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00000001u))
|
||||
{
|
||||
spellId = SpellIds.EnergySurge;
|
||||
chance = 15;
|
||||
}
|
||||
// Stormstrike
|
||||
else if (spellInfo.SpellFamilyFlags[1].HasAnyFlag(0x00000010u))
|
||||
{
|
||||
spellId = SpellIds.PowerSurge;
|
||||
chance = 50;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if (RandomHelper.randChance(chance))
|
||||
eventInfo.GetActor().CastSpell((Unit)null, spellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 70811 - Item - Shaman T10 Elemental 2P Bonus
|
||||
class spell_sha_item_t10_elemental_2p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ElementalMastery);
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Player target = GetTarget().ToPlayer();
|
||||
if (target)
|
||||
target.GetSpellHistory().ModifyCooldown(SpellIds.ElementalMastery, -aurEff.GetAmount());
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 189063 - Lightning Vortex (proc 185881 Item - Shaman T18 Elemental 4P Bonus)
|
||||
class spell_sha_item_t18_elemental_4p_bonus : AuraScript
|
||||
{
|
||||
void DiminishHaste(AuraEffect aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
AuraEffect hasteBuff = GetEffect(0);
|
||||
if (hasteBuff != null)
|
||||
hasteBuff.ChangeAmount(hasteBuff.GetAmount() - aurEff.GetAmount());
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(DiminishHaste, 1, AuraType.PeriodicDummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 51505 - Lava burst
|
||||
class spell_sha_lava_burst : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.PathOfFlamesTalent, SpellIds.PathOfFlamesSpread);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit caster = GetCaster();
|
||||
if (caster)
|
||||
{
|
||||
Unit target = GetExplTargetUnit();
|
||||
if (target)
|
||||
if (caster.HasAura(SpellIds.PathOfFlamesTalent))
|
||||
caster.CastSpell(target, SpellIds.PathOfFlamesSpread, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.SchoolDamage));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 77756 - Lava Surge
|
||||
class spell_sha_lava_surge : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LavaSurge);
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.LavaSurge, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 77762 - Lava Surge
|
||||
class spell_sha_lava_surge_proc : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LavaBurst);
|
||||
}
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
return GetCaster().IsTypeId(TypeId.Player);
|
||||
}
|
||||
|
||||
void ResetCooldown()
|
||||
{
|
||||
GetCaster().GetSpellHistory().RestoreCharge(Global.SpellMgr.GetSpellInfo(SpellIds.LavaBurst).ChargeCategoryId);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterHit.Add(new HitHandler(ResetCooldown));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 210621 - Path of Flames Spread
|
||||
class spell_sha_path_of_flames_spread : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.FlameShockMaelstrom);
|
||||
}
|
||||
|
||||
void FilterTargets(List<WorldObject> targets)
|
||||
{
|
||||
targets.Remove(GetExplTargetUnit());
|
||||
targets.RandomResize(target =>
|
||||
{
|
||||
return target.IsTypeId(TypeId.Unit) && !target.ToUnit().HasAura(SpellIds.FlameShockMaelstrom, GetCaster().GetGUID());
|
||||
}, 1);
|
||||
}
|
||||
|
||||
void HandleScript(uint effIndex)
|
||||
{
|
||||
Unit mainTarget = GetExplTargetUnit();
|
||||
if (mainTarget)
|
||||
{
|
||||
Aura flameShock = mainTarget.GetAura(SpellIds.FlameShockMaelstrom, GetCaster().GetGUID());
|
||||
if (flameShock != null)
|
||||
{
|
||||
Aura newAura = GetCaster().AddAura(SpellIds.FlameShockMaelstrom, GetHitUnit());
|
||||
if (newAura != null)
|
||||
{
|
||||
newAura.SetDuration(flameShock.GetDuration());
|
||||
newAura.SetMaxDuration(flameShock.GetDuration());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 1, Targets.UnitDestAreaEnemy));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 1, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 51562 - Tidal Waves
|
||||
class spell_sha_tidal_waves : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.TidalWaves);
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
int basePoints0 = -aurEff.GetAmount();
|
||||
int basePoints1 = aurEff.GetAmount();
|
||||
|
||||
GetTarget().CastCustomSpell(GetTarget(), SpellIds.TidalWaves, basePoints0, basePoints1, 0, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 28823 - Totemic Power
|
||||
class spell_sha_t3_6p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.TotemicPowerArmor, SpellIds.TotemicPowerAttackPower, SpellIds.TotemicPowerSpellPower, SpellIds.TotemicPowerMp5);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
uint spellId;
|
||||
Unit caster = eventInfo.GetActor();
|
||||
Unit target = eventInfo.GetProcTarget();
|
||||
|
||||
switch (target.GetClass())
|
||||
{
|
||||
case Class.Paladin:
|
||||
case Class.Priest:
|
||||
case Class.Shaman:
|
||||
case Class.Druid:
|
||||
spellId = SpellIds.TotemicPowerMp5;
|
||||
break;
|
||||
case Class.Mage:
|
||||
case Class.Warlock:
|
||||
spellId = SpellIds.TotemicPowerSpellPower;
|
||||
break;
|
||||
case Class.Hunter:
|
||||
case Class.Rogue:
|
||||
spellId = SpellIds.TotemicPowerAttackPower;
|
||||
break;
|
||||
case Class.Warrior:
|
||||
spellId = SpellIds.TotemicPowerArmor;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
caster.CastSpell(target, spellId, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 64928 - Item - Shaman T8 Elemental 4P Bonus
|
||||
class spell_sha_t8_elemental_4p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.Electrified);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
DamageInfo damageInfo = eventInfo.GetDamageInfo();
|
||||
if (damageInfo == null || damageInfo.GetDamage() == 0)
|
||||
return;
|
||||
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.Electrified);
|
||||
int amount = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount());
|
||||
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
|
||||
|
||||
// Add remaining ticks to healing done
|
||||
Unit caster = eventInfo.GetActor();
|
||||
Unit target = eventInfo.GetProcTarget();
|
||||
amount += (int)target.GetRemainingPeriodicAmount(caster.GetGUID(), SpellIds.Electrified, AuraType.PeriodicDamage);
|
||||
|
||||
caster.CastCustomSpell(SpellIds.Electrified, SpellValueMod.BasePoint0, amount, target, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 67228 - Item - Shaman T9 Elemental 4P Bonus (Lava Burst)
|
||||
class spell_sha_t9_elemental_4p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.LavaBurstBonusDamage);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
DamageInfo damageInfo = eventInfo.GetDamageInfo();
|
||||
if (damageInfo == null || damageInfo.GetDamage() == 0)
|
||||
return;
|
||||
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.LavaBurstBonusDamage);
|
||||
int amount = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount());
|
||||
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
|
||||
|
||||
// Add remaining ticks to healing done
|
||||
Unit caster = eventInfo.GetActor();
|
||||
Unit target = eventInfo.GetProcTarget();
|
||||
amount += (int)target.GetRemainingPeriodicAmount(caster.GetGUID(), SpellIds.LavaBurstBonusDamage, AuraType.PeriodicDamage);
|
||||
|
||||
caster.CastCustomSpell(SpellIds.LavaBurstBonusDamage, SpellValueMod.BasePoint0, amount, target, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 70817 - Item - Shaman T10 Elemental 4P Bonus
|
||||
class spell_sha_t10_elemental_4p_bonus : AuraScript
|
||||
{
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
Unit caster = eventInfo.GetActor();
|
||||
Unit target = eventInfo.GetProcTarget();
|
||||
|
||||
// try to find spell Flame Shock on the target
|
||||
AuraEffect flameShock = target.GetAuraEffect(AuraType.PeriodicDamage, SpellFamilyNames.Shaman, new FlagArray128(0x10000000), caster.GetGUID());
|
||||
if (flameShock == null)
|
||||
return;
|
||||
|
||||
Aura flameShockAura = flameShock.GetBase();
|
||||
|
||||
int maxDuration = flameShockAura.GetMaxDuration();
|
||||
int newDuration = flameShockAura.GetDuration() + aurEff.GetAmount() * Time.InMilliseconds;
|
||||
|
||||
flameShockAura.SetDuration(newDuration);
|
||||
// is it blizzlike to change max duration for FS?
|
||||
if (newDuration > maxDuration)
|
||||
flameShockAura.SetMaxDuration(newDuration);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 70808 - Item - Shaman T10 Restoration 4P Bonus
|
||||
class spell_sha_t10_restoration_4p_bonus : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ChainedHeal);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
HealInfo healInfo = eventInfo.GetHealInfo();
|
||||
if (healInfo == null || healInfo.GetHeal() == 0)
|
||||
return;
|
||||
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.ChainedHeal);
|
||||
int amount = (int)MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount());
|
||||
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
|
||||
|
||||
// Add remaining ticks to healing done
|
||||
Unit caster = eventInfo.GetActor();
|
||||
Unit target = eventInfo.GetProcTarget();
|
||||
amount += (int)target.GetRemainingPeriodicAmount(caster.GetGUID(), SpellIds.ChainedHeal, AuraType.PeriodicHeal);
|
||||
|
||||
caster.CastCustomSpell(SpellIds.ChainedHeal, SpellValueMod.BasePoint0, amount, target, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 33757 - Windfury
|
||||
class spell_sha_windfury : AuraScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.WindfuryAttack);
|
||||
}
|
||||
|
||||
void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
for (uint i = 0; i < 2; ++i)
|
||||
eventInfo.GetActor().CastSpell(eventInfo.GetProcTarget(), SpellIds.WindfuryAttack, true, null, aurEff);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy));
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user