initial commit

This commit is contained in:
hondacrx
2017-06-19 17:30:18 -04:00
commit 6e265ea24b
763 changed files with 488824 additions and 0 deletions
@@ -0,0 +1,212 @@
/*
* 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.Scripting;
using Game.Maps;
using Game.Entities;
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);
}
}*/
}
+296
View File
@@ -0,0 +1,296 @@
/*
* 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;
using Game.AI;
using Game.Entities;
using Game.Scripting;
namespace Scripts.EasternKingdoms
{
[Script]
class npc_apprentice_mirveda : CreatureScript
{
public npc_apprentice_mirveda() : base("npc_apprentice_mirveda") { }
class npc_apprentice_mirvedaAI : ScriptedAI
{
public npc_apprentice_mirvedaAI(Creature creature)
: base(creature)
{
Summons = new SummonList(me);
}
public override void Reset()
{
SetCombatMovement(false);
KillCount = 0;
PlayerGUID.Clear();
Summons.DespawnAll();
}
public override void sQuestReward(Player player, Quest quest, uint opt)
{
if (quest.Id == QUEST_CORRUPTED_SOIL)
{
me.RemoveFlag64(UnitFields.NpcFlags, NPCFlags.QuestGiver);
_events.ScheduleEvent(EventTalk, 2000);
}
}
public override void sQuestAccept(Player player, Quest quest)
{
if (quest.Id == QUEST_UNEXPECTED_RESULT)
{
me.SetFaction(FactionCombat);
me.RemoveFlag64(UnitFields.NpcFlags, NPCFlags.QuestGiver);
_events.ScheduleEvent(EventSummon, 1000);
PlayerGUID = player.GetGUID();
}
}
public override void EnterCombat(Unit who)
{
_events.ScheduleEvent(EventFireball, 1000);
}
public override void JustSummoned(Creature summoned)
{
// This is the best I can do because AttackStart does nothing
summoned.GetMotionMaster().MovePoint(1, me.GetPositionX(), me.GetPositionY(), me.GetPositionZ());
// summoned.AI().AttackStart(me);
Summons.Summon(summoned);
}
public override void SummonedCreatureDies(Creature summoned, Unit who)
{
Summons.Despawn(summoned);
++KillCount;
}
public override void JustDied(Unit killer)
{
me.SetFaction(FactionNormal);
if (!PlayerGUID.IsEmpty())
{
Player player = Global.ObjAccessor.GetPlayer(me, PlayerGUID);
if (player)
player.FailQuest(QUEST_UNEXPECTED_RESULT);
}
}
public override void UpdateAI(uint diff)
{
if (KillCount >= 3 && !PlayerGUID.IsEmpty())
{
Player player = Global.ObjAccessor.GetPlayer(me, PlayerGUID);
if (player)
{
if (player.GetQuestStatus(QUEST_UNEXPECTED_RESULT) == QuestStatus.Incomplete)
{
player.CompleteQuest(QUEST_UNEXPECTED_RESULT);
me.SetFaction(FactionNormal);
me.SetFlag64(UnitFields.NpcFlags, NPCFlags.QuestGiver);
}
}
}
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case EventTalk:
Talk(SayTestSoil);
_events.ScheduleEvent(EventAddQuestGiverFlag, 7000);
break;
case EventAddQuestGiverFlag:
me.SetFlag64(UnitFields.NpcFlags, NPCFlags.QuestGiver);
break;
case EventSummon:
me.SummonCreature(NPC_GHARZUL, 8749.505f, -7132.595f, 35.31983f, 3.816502f, TempSummonType.CorpseTimedDespawn, 180000);
me.SummonCreature(NPC_ANGERSHADE, 8755.38f, -7131.521f, 35.30957f, 3.816502f, TempSummonType.CorpseTimedDespawn, 180000);
me.SummonCreature(NPC_ANGERSHADE, 8753.199f, -7125.975f, 35.31986f, 3.816502f, TempSummonType.CorpseTimedDespawn, 180000);
break;
case EventFireball:
if (UpdateVictim())
{
DoCastVictim(SpellFireball, true); // Not casting in combat
_events.ScheduleEvent(EventFireball, 3000);
}
break;
default:
break;
}
});
DoMeleeAttackIfReady();
}
uint KillCount;
ObjectGuid PlayerGUID;
SummonList Summons;
}
const uint EventTalk = 1; // Quest 8487
const uint EventAddQuestGiverFlag = 2; // Quest 8487
const uint EventSummon = 3; // Quest 8488
const uint EventFireball = 4; // Quest 8488
// Creatures
const uint NPC_GHARZUL = 15958; // Quest 8488
const uint NPC_ANGERSHADE = 15656; // Quest 8488
// Spells
const uint SpellTestSoil = 29535; // Quest 8487
const uint SpellFireball = 20811; // Quest 8488
//Texts
const uint SayTestSoil = 0; // Quest 8487
// Factions
const uint FactionNormal = 1604; // Quest 8488
const uint FactionCombat = 232; // Quest 8488
// Quest
const uint QUEST_CORRUPTED_SOIL = 8487;
const uint QUEST_UNEXPECTED_RESULT = 8488;
public override CreatureAI GetAI(Creature creature)
{
return new npc_apprentice_mirvedaAI(creature);
}
}
[Script]
class npc_infused_crystal : CreatureScript
{
public npc_infused_crystal() : base("npc_infused_crystal") { }
class npc_infused_crystalAI : ScriptedAI
{
public npc_infused_crystalAI(Creature creature)
: base(creature)
{
SetCombatMovement(false);
}
public override void Reset()
{
EndTimer = 0;
Completed = false;
Progress = false;
PlayerGUID.Clear();
WaveTimer = 0;
}
public override void MoveInLineOfSight(Unit who)
{
if (!Progress && who.IsTypeId(TypeId.Player) && me.IsWithinDistInMap(who, 10.0f))
{
if (who.ToPlayer().GetQuestStatus(QuestPoweringOurDefenses) == QuestStatus.Incomplete)
{
PlayerGUID = who.GetGUID();
WaveTimer = 1000;
EndTimer = 60000;
Progress = true;
}
}
}
public override void JustSummoned(Creature summoned)
{
summoned.GetAI().AttackStart(me);
}
public override void JustDied(Unit killer)
{
if (!PlayerGUID.IsEmpty() && !Completed)
{
Player player = Global.ObjAccessor.GetPlayer(me, PlayerGUID);
if (player)
player.FailQuest(QuestPoweringOurDefenses);
}
}
public override void UpdateAI(uint diff)
{
if (EndTimer < diff && Progress)
{
Talk(Emote);
Completed = true;
if (!PlayerGUID.IsEmpty())
{
Player player = Global.ObjAccessor.GetPlayer(me, PlayerGUID);
if (player)
player.CompleteQuest(QuestPoweringOurDefenses);
}
me.DealDamage(me, (uint)me.GetHealth(), null, DamageEffectType.Direct, SpellSchoolMask.Normal, null, false);
me.RemoveCorpse();
}
else EndTimer -= diff;
if (WaveTimer < diff && !Completed && Progress)
{
uint ran1 = RandomHelper.Rand32() % 8;
uint ran2 = RandomHelper.Rand32() % 8;
uint ran3 = RandomHelper.Rand32() % 8;
me.SummonCreature(NpcEnragedWeaith, SpawnLocations[ran1].X, SpawnLocations[ran1].Y, SpawnLocations[ran1].Z, 0, TempSummonType.TimedOrCorpseDespawn, 10000);
me.SummonCreature(NpcEnragedWeaith, SpawnLocations[ran2].X, SpawnLocations[ran2].Y, SpawnLocations[ran2].Z, 0, TempSummonType.TimedOrCorpseDespawn, 10000);
me.SummonCreature(NpcEnragedWeaith, SpawnLocations[ran3].X, SpawnLocations[ran3].Y, SpawnLocations[ran3].Z, 0, TempSummonType.TimedOrCorpseDespawn, 10000);
WaveTimer = 30000;
}
else WaveTimer -= diff;
}
uint EndTimer;
uint WaveTimer;
bool Completed;
bool Progress;
ObjectGuid PlayerGUID;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_infused_crystalAI(creature);
}
// Quest
const uint QuestPoweringOurDefenses = 8490;
// Says
const uint Emote = 0;
// Creatures
const uint NpcEnragedWeaith = 17086;
static Vector3[] SpawnLocations =
{
new Vector3(8270.68f, -7188.53f, 139.619f),
new Vector3(8284.27f, -7187.78f, 139.603f),
new Vector3(8297.43f, -7193.53f, 139.603f),
new Vector3(8303.5f, -7201.96f, 139.577f),
new Vector3(8273.22f, -7241.82f, 139.382f),
new Vector3(8254.89f, -7222.12f, 139.603f),
new Vector3(8278.51f, -7242.13f, 139.162f),
new Vector3(8267.97f, -7239.17f, 139.517f)
};
}
}
@@ -0,0 +1,325 @@
/*
* 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]
class boss_attumen : CreatureScript
{
public boss_attumen() : base("boss_attumen") { }
public class boss_attumenAI : ScriptedAI
{
public boss_attumenAI(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.PickRandom();
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.boss_midnightAI)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;
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_attumenAI(creature);
}
}
[Script]
class boss_midnight : CreatureScript
{
public boss_midnight() : base("boss_midnight") { }
public class boss_midnightAI : ScriptedAI
{
public boss_midnightAI(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.boss_attumenAI)pAttumen.GetAI()).Midnight = value;
}
ObjectGuid Attumen;
byte Phase;
uint mountTimer;
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_midnightAI(creature);
}
}
}
File diff suppressed because it is too large Load Diff
+168
View File
@@ -0,0 +1,168 @@
/*
* 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 : CreatureScript
{
public boss_curator() : base("boss_curator") { }
class boss_curatorAI : ScriptedAI
{
public boss_curatorAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_curatorAI(creature);
}
}
}
@@ -0,0 +1,462 @@
/*
* 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;
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);
}
}
}
+778
View File
@@ -0,0 +1,778 @@
/*
* 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]
class boss_moroes : CreatureScript
{
public boss_moroes() : base("boss_moroes") { }
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_moroesAI>(creature);
}
public class boss_moroesAI : ScriptedAI
{
public boss_moroesAI(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.boss_moroesAI)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 : CreatureScript
{
public boss_baroness_dorothea_millstipe() : base("boss_baroness_dorothea_millstipe") { }
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_baroness_dorothea_millstipeAI>(creature);
}
class boss_baroness_dorothea_millstipeAI : boss_moroes_guestAI
{
//Shadow Priest
public boss_baroness_dorothea_millstipeAI(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 : CreatureScript
{
public boss_baron_rafe_dreuger() : base("boss_baron_rafe_dreuger") { }
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_baron_rafe_dreugerAI>(creature);
}
class boss_baron_rafe_dreugerAI : boss_moroes_guestAI
{
//Retr Pally
public boss_baron_rafe_dreugerAI(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 : CreatureScript
{
public boss_lady_catriona_von_indi() : base("boss_lady_catriona_von_indi") { }
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_lady_catriona_von_indiAI>(creature);
}
class boss_lady_catriona_von_indiAI : boss_moroes_guestAI
{
//Holy Priest
public boss_lady_catriona_von_indiAI(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 : CreatureScript
{
public boss_lady_keira_berrybuck() : base("boss_lady_keira_berrybuck") { }
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_lady_keira_berrybuckAI>(creature);
}
class boss_lady_keira_berrybuckAI : boss_moroes_guestAI
{
//Holy Pally
public boss_lady_keira_berrybuckAI(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 : CreatureScript
{
public boss_lord_robin_daris() : base("boss_lord_robin_daris") { }
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_lord_robin_darisAI>(creature);
}
class boss_lord_robin_darisAI : boss_moroes_guestAI
{
//Arms Warr
public boss_lord_robin_darisAI(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 : CreatureScript
{
public boss_lord_crispin_ference() : base("boss_lord_crispin_ference") { }
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_lord_crispin_ferenceAI>(creature);
}
class boss_lord_crispin_ferenceAI : boss_moroes_guestAI
{
//Arms Warr
public boss_lord_crispin_ferenceAI(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,384 @@
/*
* 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]
class npc_unworthy_initiate : CreatureScript
{
public npc_unworthy_initiate() : base("npc_unworthy_initiate") { }
public class npc_unworthy_initiateAI : ScriptedAI
{
public npc_unworthy_initiateAI(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;
}
public const uint SpellSoulPrisonChainSelf = 54612;
public const uint SpellSoulPrisonChain = 54613;
public const uint SpellDKInitateVisual = 51519;
public const uint SpellIcyTouch = 52372;
public const uint SpellPlagueStrike = 52373;
public const uint SpellBloodStrike = 52374;
public const uint SpellDeathCoil = 52375;
public const uint SayEventStart = 0;
public const uint SayEventAttack = 1;
public const uint EventIcyTouch = 1;
public const uint EventPlagueStrike = 2;
public const uint EventBloodStrike = 3;
public const uint EventDeathCoil = 4;
public static uint[] acherus_soul_prison = { 191577, 191580, 191581, 191582, 191583, 191584, 191585, 191586, 191587, 191588, 191589, 191590 };
public override CreatureAI GetAI(Creature creature)
{
return new npc_unworthy_initiateAI(creature);
}
}
[Script]
class npc_unworthy_initiate_anchor : CreatureScript
{
public npc_unworthy_initiate_anchor() : base("npc_unworthy_initiate_anchor") { }
class npc_unworthy_initiate_anchorAI : PassiveAI
{
public npc_unworthy_initiate_anchorAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_unworthy_initiate_anchorAI(creature);
}
}
[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.npc_unworthy_initiateAI)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 : CreatureScript
{
public npc_eye_of_acherus() : base("npc_eye_of_acherus") { }
class npc_eye_of_acherusAI : ScriptedAI
{
public npc_eye_of_acherusAI(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);
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_eye_of_acherusAI(creature);
}
}
}
@@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 : CreatureScript
{
public boss_hogger() : base("boss_hogger") { }
class boss_hoggerAI : BossAI
{
public boss_hoggerAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_hoggerAI>(creature, nameof(instance_the_stockade));
}
}
[Script]
class npc_warden_thelwater : CreatureScript
{
public npc_warden_thelwater() : base("npc_warden_thelwater") { }
class npc_warden_thelwaterAI : ScriptedAI
{
public npc_warden_thelwaterAI(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;
}
});
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_warden_thelwaterAI>(creature, nameof(instance_the_stockade));
}
}
}
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.Maps;
using Game.Scripting;
using Game.AI;
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);
}
}
}
+151
View File
@@ -0,0 +1,151 @@
/*
* 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 : CreatureScript
{
public npc_lazy_peon() : base("npc_lazy_peon") { }
class npc_lazy_peonAI : NullCreatureAI
{
public npc_lazy_peonAI(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 = 25134;
const int GoLumberpile = 175784;
const uint SpellBuffSleep = 17743;
const int SpellAwakenPeon = 19938;
const int SaySpellHit = 0;
TaskScheduler scheduler = new TaskScheduler();
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_lazy_peonAI(creature);
}
}
[Script]
class spell_voodoo : SpellScriptLoader
{
public spell_voodoo() : base("spell_voodoo") { }
class spell_voodoo_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_voodoo_SpellScript();
}
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!)
}
}
+38
View File
@@ -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 RageFireChasm : InstanceMapScript
{
public RageFireChasm() : 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,209 @@
/*
* 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 : CreatureScript
{
public boss_amanitar() : base("boss_amanitar") { }
class boss_amanitarAI : BossAI
{
public boss_amanitarAI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_amanitarAI>(creature);
}
}
[Script]
class npc_amanitar_mushrooms : CreatureScript
{
public npc_amanitar_mushrooms() : base("npc_amanitar_mushrooms") { }
class npc_amanitar_mushroomsAI : ScriptedAI
{
public npc_amanitar_mushroomsAI(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;
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_amanitar_mushroomsAI(creature);
}
}
}
@@ -0,0 +1,276 @@
/*
* 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 : CreatureScript
{
public boss_elder_nadox() : base("boss_elder_nadox") { }
class boss_elder_nadoxAI : BossAI
{
public boss_elder_nadoxAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_elder_nadoxAI>(creature, "instance_ahnkahet");
}
}
[Script]
class npc_ahnkahar_nerubian : CreatureScript
{
public npc_ahnkahar_nerubian() : base("npc_ahnkahar_nerubian") { }
class npc_ahnkahar_nerubianAI : ScriptedAI
{
public npc_ahnkahar_nerubianAI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_ahnkahar_nerubianAI(creature);
}
}
// 56159 - Swarm
[Script]
class spell_ahn_kahet_swarm : SpellScriptLoader
{
public spell_ahn_kahet_swarm() : base("spell_ahn_kahet_swarm") { }
class spell_ahn_kahet_swarm_SpellScript : SpellScript
{
public spell_ahn_kahet_swarm_SpellScript()
{
_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;
}
public override SpellScript GetSpellScript()
{
return new spell_ahn_kahet_swarm_SpellScript();
}
}
[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,295 @@
/*
* 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 : CreatureScript
{
public boss_volazj() : base("boss_volazj") { }
class boss_volazjAI : ScriptedAI
{
public boss_volazjAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_volazjAI>(creature);
}
}
}
@@ -0,0 +1,602 @@
/*
* 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 RandomLightningVisual = 56327;
public const uint SacrificeBeam = 56150;
public const uint SacrificeVisual = 56133;
}
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]
class boss_jedoga_shadowseeker : CreatureScript
{
public boss_jedoga_shadowseeker() : base("boss_jedoga_shadowseeker") { }
public class boss_jedoga_shadowseekerAI : ScriptedAI
{
public boss_jedoga_shadowseekerAI(Creature creature) : base(creature)
{
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();
DoCast(SpellIds.RandomLightningVisual);
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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_jedoga_shadowseekerAI>(creature);
}
}
[Script]
class npc_jedoga_twilight_volunteer : CreatureScript
{
public npc_jedoga_twilight_volunteer() : base("npc_jedoga_initiand") { }
class npc_jedoga_twilight_volunteerAI : ScriptedAI
{
public npc_jedoga_twilight_volunteerAI(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.boss_jedoga_shadowseekerAI>().bOpFerok)
boss.GetAI<boss_jedoga_shadowseeker.boss_jedoga_shadowseekerAI>().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.boss_jedoga_shadowseekerAI>().bOpFerok = true;
boss.GetAI<boss_jedoga_shadowseeker.boss_jedoga_shadowseekerAI>().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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_jedoga_twilight_volunteerAI>(creature);
}
}
[Script]
class npc_jedoga_controller : CreatureScript
{
public npc_jedoga_controller() : base("npc_jedogas_aufseher_trigger") { }
class npc_jedoga_controllerAI : ScriptedAI
{
public npc_jedoga_controllerAI(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, JedogaShadowseekerConst.SpellBeamVisualJedogasAufseher1, false);
bCast = true;
}
}
if (!bRemoved2 && me.GetPositionX() < 440.0f)
{
if (!bCast2 && instance.GetData(DataTypes.JedogaTriggerSwitch) != 0)
{
//DoCast(me, JedogaShadowseekerConst.SpellBeamVisualJedogasAufseher2, 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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_jedoga_controllerAI>(creature);
}
}
[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,476 @@
/*
* 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]
class boss_prince_taldaram : CreatureScript
{
public boss_prince_taldaram() : base("boss_prince_taldaram") { }
public class boss_prince_taldaramAI : BossAI
{
public boss_prince_taldaramAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_prince_taldaramAI>(creature);
}
}
[Script] // 30106, 31686, 31687 - Flame Sphere
class npc_prince_taldaram_flame_sphere : CreatureScript
{
public npc_prince_taldaram_flame_sphere() : base("npc_prince_taldaram_flame_sphere") { }
class npc_prince_taldaram_flame_sphereAI : ScriptedAI
{
public npc_prince_taldaram_flame_sphereAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_prince_taldaram_flame_sphereAI(creature);
}
}
[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.boss_prince_taldaramAI>().CheckSpheres();
}
return true;
}
}
[Script] // 55931 - Conjure Flame Sphere
class spell_prince_taldaram_conjure_flame_sphere : SpellScriptLoader
{
public spell_prince_taldaram_conjure_flame_sphere() : base("spell_prince_taldaram_conjure_flame_sphere") { }
class spell_prince_taldaram_conjure_flame_sphere_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_prince_taldaram_conjure_flame_sphere_SpellScript();
}
}
[Script] // 55895, 59511, 59512 - Flame Sphere Summon
class spell_prince_taldaram_flame_sphere_summon : SpellScriptLoader
{
public spell_prince_taldaram_flame_sphere_summon() : base("spell_prince_taldaram_flame_sphere_summon") { }
class spell_prince_taldaram_flame_sphere_summon_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_prince_taldaram_flame_sphere_summon_SpellScript();
}
}
}
@@ -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
{
[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.PickRandom();
}
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);
}
}
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;
}
}
@@ -0,0 +1,722 @@
/*
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Scripts.Northrend.AzjolNerub.AzjolNerub.Anubarak
{
struct SpellIds
{
public const uint Emerge = 53500;
public const uint Submerge = 53421;
public const uint ImpaleAura = 53456;
public const uint ImpaleVisual = 53455;
public const uint ImpaleDamage = 53454;
public const uint LeechingSwarm = 53467;
public const uint Pound = 59433;
public const uint PoundDamage = 59432;
public const uint CarrionBeetles = 53520;
public const uint CarrionBeetle = 53521;
public const uint SummonDarter = 53599;
public const uint SummonAssassin = 53609;
public const uint SummonGuardian = 53614;
public const uint SummonVenomancer = 53615;
public const uint Dart = 59349;
public const uint Backstab = 52540;
public const uint AssassinVisual = 53611;
public const uint SunderArmor = 53618;
public const uint PoisonBolt = 53617;
}
struct CreatureIds
{
public const uint WorldTrigger = 22515;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SaySlay = 1;
public const uint SayDeath = 2;
public const uint SayLocust = 3;
public const uint SaySubmerge = 4;
public const uint SayIntro = 5;
}
struct EventIds
{
public const uint Pound = 1;
public const uint Impale = 2;
public const uint LeechingSwarm = 3;
public const uint CarrionBeetles = 4;
public const uint Submerge = 5; // Use Event For This So We Don'T Submerge Mid-Cast
public const uint Darter = 6;
public const uint Assassin = 7;
public const uint Guardian = 8;
public const uint Venomancer = 9;
public const uint CloseDoor = 10;
}
struct Misc
{
public const uint AchievGottaGoStartEvent = 20381;
public const byte PhaseEmerge = 1;
public const byte PhaseSubmerge = 2;
public const int GuidTypePet = 0;
public const int GuidTypeImpale = 1;
public const byte SummonGroupWorldTriggerGuardian = 1;
public const int ActionPetDied = 1;
public const int ActionPetEvade = 2;
}
[Script]
class boss_anub_arak : CreatureScript
{
public boss_anub_arak() : base("boss_anub_arak") { }
class boss_anub_arakAI : BossAI
{
public boss_anub_arakAI(Creature creature) : base(creature, ANDataTypes.Anubarak) { }
public override void Reset()
{
base.Reset();
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
instance.DoStopCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievGottaGoStartEvent);
_nextSubmerge = 75;
_petCount = 0;
}
public override void EnterCombat(Unit who)
{
base.EnterCombat(who);
GameObject door = instance.GetGameObject(ANDataTypes.AnubarakWall);
if (door)
door.SetGoState(GameObjectState.Active); // open door for now
Talk(TextIds.SayAggro);
instance.DoStartCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievGottaGoStartEvent);
_events.SetPhase(Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.CloseDoor, TimeSpan.FromSeconds(5));
_events.ScheduleEvent(EventIds.Pound, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), 0, Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.LeechingSwarm, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(7), 0, Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.CarrionBeetles, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(17), 0, Misc.PhaseEmerge);
// set up world triggers
List<TempSummon> summoned;
me.SummonCreatureGroup(Misc.SummonGroupWorldTriggerGuardian, out summoned);
if (summoned.Empty()) // something went wrong
{
EnterEvadeMode(EvadeReason.Other);
return;
}
_guardianTrigger = summoned.First().GetGUID();
Creature trigger = DoSummon(CreatureIds.WorldTrigger, me.GetPosition(), 0u, TempSummonType.ManualDespawn);
if (trigger)
_assassinTrigger = trigger.GetGUID();
else
{
EnterEvadeMode(EvadeReason.Other);
return;
}
}
public override void EnterEvadeMode(EvadeReason why)
{
summons.DespawnAll();
_DespawnAtEvade();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case EventIds.CloseDoor:
GameObject door = instance.GetGameObject(ANDataTypes.AnubarakWall);
if (door)
door.SetGoState(GameObjectState.Ready);
break;
case EventIds.Pound:
DoCastVictim(SpellIds.Pound);
_events.Repeat(TimeSpan.FromSeconds(26), TimeSpan.FromSeconds(32));
break;
case EventIds.LeechingSwarm:
Talk(TextIds.SayLocust);
DoCastAOE(SpellIds.LeechingSwarm);
_events.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(28));
break;
case EventIds.CarrionBeetles:
DoCastAOE(SpellIds.CarrionBeetles);
_events.Repeat(TimeSpan.FromSeconds(24), TimeSpan.FromSeconds(27));
break;
case EventIds.Impale:
Creature impaleTarget = ObjectAccessor.GetCreature(me, _impaleTarget);
if (impaleTarget)
DoCast(impaleTarget, SpellIds.ImpaleDamage, true);
break;
case EventIds.Submerge:
Talk(TextIds.SaySubmerge);
DoCastSelf(SpellIds.Submerge);
break;
case EventIds.Darter:
{
List<Creature> triggers = new List<Creature>();
me.GetCreatureListWithEntryInGrid(triggers, CreatureIds.WorldTrigger);
if (!triggers.Empty())
{
var it = triggers.PickRandom();
it.CastSpell(it, SpellIds.SummonDarter, true);
_events.Repeat(TimeSpan.FromSeconds(11));
}
else
EnterEvadeMode(EvadeReason.Other);
break;
}
case EventIds.Assassin:
{
Creature trigger = ObjectAccessor.GetCreature(me, _assassinTrigger);
if (trigger)
{
trigger.CastSpell(trigger, SpellIds.SummonAssassin, true);
trigger.CastSpell(trigger, SpellIds.SummonAssassin, true);
if (_assassinCount > 2)
{
_assassinCount -= 2;
_events.Repeat(TimeSpan.FromSeconds(20));
}
else
_assassinCount = 0;
}
else // something went wrong
EnterEvadeMode(EvadeReason.Other);
break;
}
case EventIds.Guardian:
{
Creature trigger = ObjectAccessor.GetCreature(me, _guardianTrigger);
if (trigger)
{
trigger.CastSpell(trigger, SpellIds.SummonGuardian, true);
trigger.CastSpell(trigger, SpellIds.SummonGuardian, true);
if (_guardianCount > 2)
{
_guardianCount -= 2;
_events.Repeat(TimeSpan.FromSeconds(20));
}
else
_guardianCount = 0;
}
else
EnterEvadeMode(EvadeReason.Other);
}
break;
case EventIds.Venomancer:
{
Creature trigger = ObjectAccessor.GetCreature(me, _guardianTrigger);
if (trigger)
{
trigger.CastSpell(trigger, SpellIds.SummonVenomancer, true);
trigger.CastSpell(trigger, SpellIds.SummonVenomancer, true);
if (_venomancerCount > 2)
{
_venomancerCount -= 2;
_events.Repeat(TimeSpan.FromSeconds(20));
}
else
_venomancerCount = 0;
}
else
EnterEvadeMode(EvadeReason.Other);
}
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
DoMeleeAttackIfReady();
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
}
public override void KilledUnit(Unit victim)
{
if (victim.IsTypeId(TypeId.Player))
Talk(TextIds.SaySlay);
}
public override void SetGUID(ObjectGuid guid, int type)
{
switch (type)
{
case Misc.GuidTypePet:
{
Creature creature = ObjectAccessor.GetCreature(me, guid);
if (creature)
JustSummoned(creature);
else // something has gone horribly wrong
EnterEvadeMode(EvadeReason.Other);
break;
}
case Misc.GuidTypeImpale:
_impaleTarget = guid;
_events.ScheduleEvent(EventIds.Impale, TimeSpan.FromSeconds(4));
break;
}
}
public override void DoAction(int action)
{
switch (action)
{
case Misc.ActionPetDied:
if (_petCount == 0) // underflow check - something has gone horribly wrong
{
EnterEvadeMode(EvadeReason.Other);
return;
}
if (--_petCount == 0) // last pet died, emerge
{
me.RemoveAurasDueToSpell(SpellIds.Submerge);
me.RemoveAurasDueToSpell(SpellIds.ImpaleAura);
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
DoCastSelf(SpellIds.Emerge);
_events.SetPhase(Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.Pound, TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(18), 0, Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.LeechingSwarm, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7), 0, Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.CarrionBeetles, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), 0, Misc.PhaseEmerge);
}
break;
case Misc.ActionPetEvade:
EnterEvadeMode(EvadeReason.Other);
break;
}
}
public override void DamageTaken(Unit source, ref uint damage)
{
if (me.HasAura(SpellIds.Submerge))
damage = 0;
else
if (_nextSubmerge != 0 && me.HealthBelowPctDamaged((int)_nextSubmerge, damage))
{
_events.CancelEvent(EventIds.Submerge);
_events.ScheduleEvent(EventIds.Submerge, 0, 0, Misc.PhaseEmerge);
_nextSubmerge = _nextSubmerge - 25;
}
}
public override void SpellHit(Unit whose, SpellInfo spell)
{
if (spell.Id == SpellIds.Submerge)
{
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
me.RemoveAurasDueToSpell(SpellIds.LeechingSwarm);
DoCastSelf(SpellIds.ImpaleAura, true);
_events.SetPhase(Misc.PhaseSubmerge);
switch (_nextSubmerge)
{
case 50: // first submerge phase
_assassinCount = 4;
_guardianCount = 2;
_venomancerCount = 0;
break;
case 25: // second submerge phase
_assassinCount = 6;
_guardianCount = 2;
_venomancerCount = 2;
break;
case 0: // third submerge phase
_assassinCount = 6;
_guardianCount = 2;
_venomancerCount = 2;
_events.ScheduleEvent(EventIds.Darter, TimeSpan.FromSeconds(0), 0, Misc.PhaseSubmerge);
break;
}
_petCount = (uint)(_guardianCount + _venomancerCount);
if (_assassinCount != 0)
_events.ScheduleEvent(EventIds.Assassin, TimeSpan.FromSeconds(0), 0, Misc.PhaseSubmerge);
if (_guardianCount != 0)
_events.ScheduleEvent(EventIds.Guardian, TimeSpan.FromSeconds(4), 0, Misc.PhaseSubmerge);
if (_venomancerCount != 0)
_events.ScheduleEvent(EventIds.Venomancer, TimeSpan.FromSeconds(20), 0, Misc.PhaseSubmerge);
}
}
ObjectGuid _impaleTarget;
uint _nextSubmerge;
uint _petCount;
ObjectGuid _guardianTrigger;
ObjectGuid _assassinTrigger;
byte _assassinCount;
byte _guardianCount;
byte _venomancerCount;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_anub_arakAI>(creature);
}
}
[Script]
class npc_anubarak_pet_template : ScriptedAI
{
public npc_anubarak_pet_template(Creature creature, bool isLarge) : base(creature)
{
_instance = creature.GetInstanceScript();
_isLarge = isLarge;
}
public override void InitializeAI()
{
base.InitializeAI();
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
if (anubarak)
anubarak.GetAI().SetGUID(me.GetGUID(), Misc.GuidTypePet);
else
me.DespawnOrUnsummon();
}
public override void JustDied(Unit killer)
{
base.JustDied(killer);
if (_isLarge)
{
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
if (anubarak)
anubarak.GetAI().DoAction(Misc.ActionPetDied);
}
}
public override void EnterEvadeMode(EvadeReason why)
{
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
if (anubarak)
anubarak.GetAI().DoAction(Misc.ActionPetEvade);
else
me.DespawnOrUnsummon();
}
protected InstanceScript _instance;
bool _isLarge;
}
[Script]
class npc_anubarak_anub_ar_darter : CreatureScript
{
public npc_anubarak_anub_ar_darter() : base("npc_anubarak_anub_ar_darter") { }
class npc_anubarak_anub_ar_darterAI : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_darterAI(Creature creature) : base(creature, false) { }
public override void InitializeAI()
{
base.InitializeAI();
DoCastAOE(SpellIds.Dart);
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_anub_ar_darterAI>(creature);
}
}
[Script]
class npc_anubarak_anub_ar_assassin : CreatureScript
{
public npc_anubarak_anub_ar_assassin() : base("npc_anubarak_anub_ar_assassin") { }
class npc_anubarak_anub_ar_assassinAI : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_assassinAI(Creature creature) : base(creature, false)
{
_backstabTimer = 6 * Time.InMilliseconds;
}
bool IsInBounds(Position jumpTo, List<AreaBoundary> boundary)
{
if (boundary == null)
return true;
foreach (var it in boundary)
if (!it.IsWithinBoundary(jumpTo))
return false;
return true;
}
Position GetRandomPositionAround(Creature anubarak)
{
float DISTANCE_MIN = 10.0f;
float DISTANCE_MAX = 30.0f;
double angle = RandomHelper.NextDouble() * 2.0 * Math.PI;
return new Position(anubarak.GetPositionX() + (float)(RandomHelper.FRand(DISTANCE_MIN, DISTANCE_MAX) * Math.Sin(angle)), anubarak.GetPositionY() + (float)(RandomHelper.FRand(DISTANCE_MIN, DISTANCE_MAX) * Math.Cos(angle)), anubarak.GetPositionZ());
}
public override void InitializeAI()
{
base.InitializeAI();
var boundary = _instance.GetBossBoundary(ANDataTypes.Anubarak);
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
if (anubarak)
{
Position jumpTo;
do
jumpTo = GetRandomPositionAround(anubarak);
while (!IsInBounds(jumpTo, boundary));
me.GetMotionMaster().MoveJump(jumpTo, 40.0f, 40.0f);
DoCastSelf(SpellIds.AssassinVisual, true);
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (diff >= _backstabTimer)
{
if (me.GetVictim() && me.GetVictim().isInBack(me))
DoCastVictim(SpellIds.Backstab);
_backstabTimer = 6 * Time.InMilliseconds;
}
else
_backstabTimer -= diff;
DoMeleeAttackIfReady();
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (id == EventId.Jump)
{
me.RemoveAurasDueToSpell(SpellIds.AssassinVisual);
DoZoneInCombat();
}
}
uint _backstabTimer;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_anub_ar_assassinAI>(creature);
}
}
[Script]
class npc_anubarak_anub_ar_guardian : CreatureScript
{
public npc_anubarak_anub_ar_guardian() : base("npc_anubarak_anub_ar_guardian") { }
class npc_anubarak_anub_ar_guardianAI : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_guardianAI(Creature creature) : base(creature, true)
{
_sunderTimer = 6 * Time.InMilliseconds;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (diff >= _sunderTimer)
{
DoCastVictim(SpellIds.SunderArmor);
_sunderTimer = 12 * Time.InMilliseconds;
}
else
_sunderTimer -= diff;
DoMeleeAttackIfReady();
}
uint _sunderTimer;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_anub_ar_guardianAI>(creature);
}
}
[Script]
class npc_anubarak_anub_ar_venomancer : CreatureScript
{
public npc_anubarak_anub_ar_venomancer() : base("npc_anubarak_anub_ar_venomancer") { }
class npc_anubarak_anub_ar_venomancerAI : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_venomancerAI(Creature creature) : base(creature, true)
{
_boltTimer = 5 * Time.InMilliseconds;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (diff >= _boltTimer)
{
DoCastVictim(SpellIds.PoisonBolt);
_boltTimer = RandomHelper.URand(2, 3) * Time.InMilliseconds;
}
else
_boltTimer -= diff;
DoMeleeAttackIfReady();
}
uint _boltTimer;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_anub_ar_venomancerAI>(creature);
}
}
[Script]
class npc_anubarak_impale_target : CreatureScript
{
public npc_anubarak_impale_target() : base("npc_anubarak_impale_target") { }
class npc_anubarak_impale_targetAI : NullCreatureAI
{
public npc_anubarak_impale_targetAI(Creature creature) : base(creature) { }
public override void InitializeAI()
{
Creature anubarak = me.GetInstanceScript().GetCreature(ANDataTypes.Anubarak);
if (anubarak)
{
DoCastSelf(SpellIds.ImpaleVisual);
me.DespawnOrUnsummon(TimeSpan.FromSeconds(6));
anubarak.GetAI().SetGUID(me.GetGUID(), Misc.GuidTypeImpale);
}
else
me.DespawnOrUnsummon();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_impale_targetAI>(creature);
}
}
[Script]
class spell_anubarak_pound : SpellScriptLoader
{
public spell_anubarak_pound() : base("spell_anubarak_pound") { }
class spell_anubarak_pound_SpellScript : SpellScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.PoundDamage);
}
void HandleDummy(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
GetCaster().CastSpell(target, SpellIds.PoundDamage, true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.ApplyAura));
}
}
public override SpellScript GetSpellScript()
{
return new spell_anubarak_pound_SpellScript();
}
}
[Script]
class spell_anubarak_carrion_beetles : SpellScriptLoader
{
public spell_anubarak_carrion_beetles() : base("spell_anubarak_carrion_beetles") { }
class spell_anubarak_carrion_beetles_AuraScript : AuraScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.CarrionBeetle);
}
void HandlePeriodic(AuraEffect eff)
{
GetCaster().CastSpell(GetCaster(), SpellIds.CarrionBeetle, true);
GetCaster().CastSpell(GetCaster(), SpellIds.CarrionBeetle, true);
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodic, 0, AuraType.PeriodicDummy));
}
}
public override AuraScript GetAuraScript()
{
return new spell_anubarak_carrion_beetles_AuraScript();
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -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 Game.Entities;
using Game.Maps;
using Game.Scripting;
namespace Scripts.Northrend.AzjolNerub.AzjolNerub
{
[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 InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_azjol_nerub_InstanceScript(map);
}
}
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;
}
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.AnubarakDoor3, ANDataTypes.AnubarakWall)
};
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))
};
}
}
@@ -0,0 +1,729 @@
/*
* 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;
}
/*
struct Point
{
float x, y, z;
}
const Point MovementPoint[] =
{
{746.84f, 623.15f, 411.41f},
{747.96f, 620.29f, 411.09f},
{750.23f, 618.35f, 411.09f}
}
*/
/*
* Generic AI for vehicles used by npcs in ToC, it needs more improvements. *
* Script Complete: 25%. *
*/
[Script]
class generic_vehicleAI_toc5 : CreatureScript
{
public generic_vehicleAI_toc5() : base("generic_vehicleAI_toc5") { }
class generic_vehicleAI_toc5AI : npc_escortAI
{
public generic_vehicleAI_toc5AI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<generic_vehicleAI_toc5AI>(creature);
}
public static 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);
}
}
}
}
public static 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;
}
}
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 && generic_vehicleAI_toc5.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)
{
generic_vehicleAI_toc5.AggroAllPlayers(me);
uiPhase = 0;
}
}
else
uiPhaseTimer -= diff;
}
public bool InVehicle()
{
return !me.m_movementInfo.transport.guid.IsEmpty();
}
public TaskScheduler NonCombatEvents = new TaskScheduler();
public InstanceScript instance;
public byte uiPhase;
public uint uiPhaseTimer;
bool bDone;
public bool bHome;
}
[Script]
class boss_warrior_toc5 : CreatureScript
{
public boss_warrior_toc5() : base("boss_warrior_toc5") { }
// Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
class boss_warrior_toc5AI : boss_basic_toc5AI
{
public boss_warrior_toc5AI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_warrior_toc5AI>(creature);
}
}
[Script]
class boss_mage_toc5 : CreatureScript
{
public boss_mage_toc5() : base("boss_mage_toc5") { }
// Ambrose Boltspark && Eressea Dawnsinger || Mage
class boss_mage_toc5AI : boss_basic_toc5AI
{
public boss_mage_toc5AI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_mage_toc5AI>(creature);
}
}
[Script]
class boss_shaman_toc5 : CreatureScript
{
public boss_shaman_toc5() : base("boss_shaman_toc5") { }
// Colosos && Runok Wildmane || Shaman
class boss_shaman_toc5AI : boss_basic_toc5AI
{
public boss_shaman_toc5AI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_shaman_toc5AI>(creature);
}
}
[Script]
class boss_hunter_toc5 : CreatureScript
{
public boss_hunter_toc5() : base("boss_hunter_toc5") { }
// Jaelyne Evensong && Zul'tore || Hunter
class boss_hunter_toc5AI : boss_basic_toc5AI
{
public boss_hunter_toc5AI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_hunter_toc5AI>(creature);
}
}
[Script]
class boss_rouge_toc5 : CreatureScript
{
public boss_rouge_toc5() : base("boss_rouge_toc5") { }
// Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
class boss_rouge_toc5AI : boss_basic_toc5AI
{
public boss_rouge_toc5AI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_rouge_toc5AI>(creature);
}
}
}
@@ -0,0 +1,333 @@
/*
* 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;
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) { }
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_trial_of_the_champion_InstanceMapScript(map);
}
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;
}
}
}
@@ -0,0 +1,587 @@
/*
* 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 CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_announcer_toc5AI>(creature);
}
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;
}
}
}
@@ -0,0 +1,568 @@
/*
* 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 : CreatureScript
{
public
boss_jaraxxus() : base("boss_jaraxxus") { }
class boss_jaraxxusAI : BossAI
{
public boss_jaraxxusAI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_jaraxxusAI>(creature);
}
}
[Script]
class npc_legion_flame : CreatureScript
{
public npc_legion_flame() : base("npc_legion_flame") { }
class npc_legion_flameAI : ScriptedAI
{
public npc_legion_flameAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_legion_flameAI>(creature);
}
}
[Script]
class npc_infernal_volcano : CreatureScript
{
public npc_infernal_volcano() : base("npc_infernal_volcano") { }
class npc_infernal_volcanoAI : ScriptedAI
{
public npc_infernal_volcanoAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_infernal_volcanoAI(creature);
}
}
[Script]
class npc_fel_infernal : CreatureScript
{
public npc_fel_infernal() : base("npc_fel_infernal") { }
class npc_fel_infernalAI : ScriptedAI
{
public npc_fel_infernalAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_fel_infernalAI>(creature);
}
}
[Script]
class npc_nether_portal : CreatureScript
{
public npc_nether_portal() : base("npc_nether_portal") { }
class npc_nether_portalAI : ScriptedAI
{
public npc_nether_portalAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_nether_portalAI(creature);
}
}
[Script]
class npc_mistress_of_pain : CreatureScript
{
public npc_mistress_of_pain() : base("npc_mistress_of_pain") { }
class npc_mistress_of_painAI : ScriptedAI
{
public npc_mistress_of_painAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_mistress_of_painAI>(creature);
}
}
[Script]
class spell_mistress_kiss : SpellScriptLoader
{
public spell_mistress_kiss() : base("spell_mistress_kiss") { }
class spell_mistress_kiss_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_mistress_kiss_AuraScript();
}
}
[Script]
class spell_mistress_kiss_area : SpellScriptLoader
{
public spell_mistress_kiss_area() : base("spell_mistress_kiss_area") { }
class spell_mistress_kiss_area_SpellScript : 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.PickRandom();
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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_mistress_kiss_area_SpellScript();
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -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 TypeCounter = 8;
public const uint TypeEvent = 9;
public const uint TypeEventTimer = 101;
public const uint TypeEventNpc = 102;
public const uint TypeNorthrendBeasts = 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
}
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;
}
}
+223
View File
@@ -0,0 +1,223 @@
/*
* 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 : CreatureScript
{
public npc_mageguard_dalaran() : base("npc_mageguard_dalaran") { }
class npc_mageguard_dalaranAI : ScriptedAI
{
public npc_mageguard_dalaranAI(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) { }
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_mageguard_dalaranAI(creature);
}
}
[Script]
class npc_minigob_manabonk : CreatureScript
{
public npc_minigob_manabonk() : base("npc_minigob_manabonk") { }
class npc_minigob_manabonkAI : ScriptedAI
{
public npc_minigob_manabonkAI(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.PickRandom();
}
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;
}
});
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_minigob_manabonkAI(creature);
}
}
}
@@ -0,0 +1,281 @@
/*
* 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 : CreatureScript
{
public boss_king_dred() : base("boss_king_dred") { }
class boss_king_dredAI : BossAI
{
public boss_king_dredAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_king_dredAI>(creature);
}
}
[Script]
class npc_drakkari_gutripper : CreatureScript
{
public npc_drakkari_gutripper() : base("npc_drakkari_gutripper") { }
class npc_drakkari_gutripperAI : ScriptedAI
{
public npc_drakkari_gutripperAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_drakkari_gutripperAI>(creature);
}
}
[Script]
class npc_drakkari_scytheclaw : CreatureScript
{
public npc_drakkari_scytheclaw() : base("npc_drakkari_scytheclaw") { }
class npc_drakkari_scytheclawAI : ScriptedAI
{
public npc_drakkari_scytheclawAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_drakkari_scytheclawAI>(creature);
}
}
[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,440 @@
/*
* 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 : CreatureScript
{
public boss_novos() : base("boss_novos") { }
class boss_novosAI : BossAI
{
public boss_novosAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_novosAI>(creature);
}
}
[Script]
class npc_crystal_channel_target : CreatureScript
{
public npc_crystal_channel_target() : base("npc_crystal_channel_target") { }
class npc_crystal_channel_targetAI : ScriptedAI
{
public npc_crystal_channel_targetAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_crystal_channel_targetAI>(creature);
}
}
[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 : SpellScriptLoader
{
public spell_novos_summon_minions() : base("spell_novos_summon_minions") { }
class spell_novos_summon_minions_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_novos_summon_minions_SpellScript();
}
}
}
@@ -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.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 : CreatureScript
{
public boss_tharon_ja() : base("boss_tharon_ja") { }
class boss_tharon_jaAI : BossAI
{
public boss_tharon_jaAI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_tharon_jaAI>(creature);
}
}
[Script]
class spell_tharon_ja_clear_gift_of_tharon_ja : SpellScriptLoader
{
public spell_tharon_ja_clear_gift_of_tharon_ja() : base("spell_tharon_ja_clear_gift_of_tharon_ja") { }
class spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript();
}
}
}
@@ -0,0 +1,335 @@
/*
* 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 : CreatureScript
{
public boss_trollgore() : base("boss_trollgore") { }
class boss_trollgoreAI : BossAI
{
public boss_trollgoreAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_trollgoreAI>(creature);
}
}
[Script]
class npc_drakkari_invader : CreatureScript
{
public npc_drakkari_invader() : base("npc_drakkari_invader") { }
class npc_drakkari_invaderAI : ScriptedAI
{
public npc_drakkari_invaderAI(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);
}
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_drakkari_invaderAI>(creature);
}
}
[Script] // 49380, 59803 - Consume
class spell_trollgore_consume : SpellScriptLoader
{
public spell_trollgore_consume() : base("spell_trollgore_consume") { }
class spell_trollgore_consume_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_trollgore_consume_SpellScript();
}
}
[Script] // 49555, 59807 - Corpse Explode
class spell_trollgore_corpse_explode : SpellScriptLoader
{
public spell_trollgore_corpse_explode() : base("spell_trollgore_corpse_explode") { }
class spell_trollgore_corpse_explode_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_trollgore_corpse_explode_AuraScript();
}
}
[Script] // 49405 - Invader Taunt Trigger
class spell_trollgore_invader_taunt : SpellScriptLoader
{
public spell_trollgore_invader_taunt() : base("spell_trollgore_invader_taunt") { }
class spell_trollgore_invader_taunt_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_trollgore_invader_taunt_SpellScript();
}
}
[Script]
class achievement_consumption_junction : AchievementCriteriaScript
{
public achievement_consumption_junction() : base("achievement_consumption_junction")
{
}
public override bool OnCheck(Player player, 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,444 @@
/*
* 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 : CreatureScript
{
public boss_drakkari_colossus() : base("boss_drakkari_colossus") { }
class boss_drakkari_colossusAI : BossAI
{
public boss_drakkari_colossusAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_drakkari_colossusAI>(creature);
}
}
[Script]
class boss_drakkari_elemental : CreatureScript
{
public boss_drakkari_elemental() : base("boss_drakkari_elemental") { }
class boss_drakkari_elementalAI : ScriptedAI
{
public boss_drakkari_elementalAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_drakkari_elementalAI>(creature);
}
}
[Script]
class npc_living_mojo : CreatureScript
{
public npc_living_mojo() : base("npc_living_mojo") { }
class npc_living_mojoAI : ScriptedAI
{
public npc_living_mojoAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_living_mojoAI>(creature);
}
}
}
+128
View File
@@ -0,0 +1,128 @@
/*
* 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 : CreatureScript
{
public boss_eck() : base("boss_eck") { }
class boss_eckAI : BossAI
{
public boss_eckAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_eckAI>(creature);
}
}
}
@@ -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,734 @@
/*
* 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]
class boss_lord_marrowgar : CreatureScript
{
public boss_lord_marrowgar() : base("boss_lord_marrowgar") { }
public class boss_lord_marrowgarAI : BossAI
{
public boss_lord_marrowgarAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return InstanceIcecrownCitadel.GetInstanceAI<boss_lord_marrowgarAI>(creature);
}
}
[Script]
class npc_coldflame : CreatureScript
{
public npc_coldflame() : base("npc_coldflame") { }
class npc_coldflameAI : ScriptedAI
{
public npc_coldflameAI(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.boss_lord_marrowgarAI)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);
}
}
}
public override CreatureAI GetAI(Creature creature)
{
return InstanceIcecrownCitadel.GetInstanceAI<npc_coldflameAI>(creature);
}
}
[Script]
class npc_bone_spike : CreatureScript
{
public npc_bone_spike() : base("npc_bone_spike") { }
class npc_bone_spikeAI : ScriptedAI
{
public npc_bone_spikeAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return InstanceIcecrownCitadel.GetInstanceAI<npc_bone_spikeAI>(creature);
}
}
[Script]
class spell_marrowgar_coldflame : SpellScriptLoader
{
public spell_marrowgar_coldflame() : base("spell_marrowgar_coldflame") { }
class spell_marrowgar_coldflame_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_coldflame_SpellScript();
}
}
[Script]
class spell_marrowgar_coldflame_bonestorm : SpellScriptLoader
{
public spell_marrowgar_coldflame_bonestorm() : base("spell_marrowgar_coldflame_bonestorm") { }
class spell_marrowgar_coldflame_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_coldflame_SpellScript();
}
}
[Script]
class spell_marrowgar_coldflame_damage : SpellScriptLoader
{
public spell_marrowgar_coldflame_damage() : base("spell_marrowgar_coldflame_damage") { }
class spell_marrowgar_coldflame_damage_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_marrowgar_coldflame_damage_AuraScript();
}
}
[Script]
class spell_marrowgar_bone_spike_graveyard : SpellScriptLoader
{
public spell_marrowgar_bone_spike_graveyard() : base("spell_marrowgar_bone_spike_graveyard") { }
class spell_marrowgar_bone_spike_graveyard_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_bone_spike_graveyard_SpellScript();
}
}
[Script]
class spell_marrowgar_bone_storm : SpellScriptLoader
{
public spell_marrowgar_bone_storm() : base("spell_marrowgar_bone_storm") { }
class spell_marrowgar_bone_storm_SpellScript : SpellScript
{
void RecalculateDamage()
{
SetHitDamage((int)(GetHitDamage() / Math.Max(Math.Sqrt(GetHitUnit().GetExactDist2d(GetCaster())), 1.0f)));
}
public override void Register()
{
OnHit.Add(new HitHandler(RecalculateDamage));
}
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_bone_storm_SpellScript();
}
}
[Script]
class spell_marrowgar_bone_slice : SpellScriptLoader
{
public spell_marrowgar_bone_slice() : base("spell_marrowgar_bone_slice") { }
class spell_marrowgar_bone_slice_SpellScript : 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;
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_bone_slice_SpellScript();
}
}
}
}
File diff suppressed because it is too large Load Diff
@@ -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,29 @@
/*
* 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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,291 @@
/*
* 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 : CreatureScript
{
public boss_anomalus() : base("boss_anomalus") { }
class boss_anomalusAI : ScriptedAI
{
public boss_anomalusAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_anomalusAI>(creature);
}
}
[Script]
class npc_chaotic_rift : CreatureScript
{
public npc_chaotic_rift() : base("npc_chaotic_rift") { }
class npc_chaotic_riftAI : ScriptedAI
{
public npc_chaotic_riftAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_chaotic_riftAI>(creature);
}
}
[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,277 @@
/*
* 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]
class boss_keristrasza : CreatureScript
{
public boss_keristrasza() : base("boss_keristrasza") { }
public class boss_keristraszaAI : BossAI
{
public boss_keristraszaAI(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>();
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_keristraszaAI>(creature);
}
}
[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.boss_keristraszaAI)pKeristrasza.GetAI()).CheckContainmentSpheres(true);
}
return true;
}
}
[Script]
class spell_intense_cold : SpellScriptLoader
{
public spell_intense_cold() : base("spell_intense_cold") { }
class spell_intense_cold_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_intense_cold_AuraScript();
}
}
[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.boss_keristraszaAI)target.ToCreature().GetAI())._intenseColdList;
if (!_intenseColdList.Empty())
{
foreach (var guid in _intenseColdList)
if (player.GetGUID() == guid)
return false;
}
return true;
}
}
}
@@ -0,0 +1,349 @@
/*
* 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 : CreatureScript
{
public boss_magus_telestra() : base("boss_magus_telestra") { }
class boss_magus_telestraAI : ScriptedAI
{
public boss_magus_telestraAI(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];
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_magus_telestraAI>(creature);
}
}
[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;
}
}
[Script]
class spell_gravity_well_effect : SpellScriptLoader
{
public spell_gravity_well_effect() : base("spell_gravity_well_effect") { }
class spell_gravity_well_effect_SpellScript : SpellScript
{
void HandleDummy(uint index)
{
}
public override void Register()
{
}
}
public override SpellScript GetSpellScript()
{
return new spell_gravity_well_effect_SpellScript();
}
}
}
@@ -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;
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 : CreatureScript
{
public boss_nexus_commanders() : base("boss_nexus_commanders") { }
class boss_nexus_commandersAI : BossAI
{
boss_nexus_commandersAI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_nexus_commandersAI>(creature);
}
}
}
@@ -0,0 +1,291 @@
/*
* 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 : CreatureScript
{
public boss_ormorok() : base("boss_ormorok") { }
class boss_ormorokAI : BossAI
{
public boss_ormorokAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_ormorokAI>(creature);
}
}
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 : CreatureScript
{
public npc_crystal_spike_trigger() : base("npc_crystal_spike_trigger") { }
class npc_crystal_spike_triggerAI : ScriptedAI
{
public npc_crystal_spike_triggerAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_crystal_spike_triggerAI(creature);
}
}
[Script]
class spell_crystal_spike : SpellScriptLoader
{
public spell_crystal_spike() : base("spell_crystal_spike") { }
class spell_crystal_spike_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_crystal_spike_AuraScript();
}
}
}
@@ -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,368 @@
/*
* 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.Entities;
using Game.Scripting;
using Game.Maps;
using Framework.Constants;
using Game.Network.Packets;
using Framework.Dynamic;
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();
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_oculus_InstanceMapScript(map);
}
}
*/
}
@@ -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
+162
View File
@@ -0,0 +1,162 @@
/*
* 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.Entities;
using Game.Scripting;
using Game.AI;
using Framework.Constants;
using Game.Spells;
namespace Scripts.Northrend.Ulduar
{
namespace Razorscale
{
/*class boss_razorscale_controller : CreatureScript
{
public boss_razorscale_controller() : base("boss_razorscale_controller") { }
class boss_razorscale_controllerAI : BossAI
{
public boss_razorscale_controllerAI(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 GetAI(Creature creature)
{
return GetInstanceAI<boss_razorscale_controllerAI>(creature);
}
}*/
}
}
+409
View File
@@ -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/>.
*/
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;
}
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
File diff suppressed because it is too large Load Diff
+39
View File
@@ -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,756 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.Scripting;
using Game.Maps;
using Game.WorldEntities;
using Framework.Util;
using Framework.Constants;
using Game.Spells;
using Game;
namespace Scripts.Northrend.VioletHold
{
class instance_violet_hold : InstanceMapScript
{
public instance_violet_hold() : base("instance_violet_hold", 608) { }
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_violet_hold_InstanceMapScript(map);
}
class instance_violet_hold_InstanceMapScript : InstanceScript
{
public instance_violet_hold_InstanceMapScript(Map map) : base(map) { }
public override void Initialize()
{
uiMoragg = 0;
uiErekem = 0;
uiIchoron = 0;
uiLavanthor = 0;
uiXevozz = 0;
uiZuramat = 0;
uiCyanigosa = 0;
uiSinclari = 0;
uiMoraggCell = 0;
uiErekemCell = 0;
uiErekemGuard[0] = 0;
uiErekemGuard[1] = 0;
uiIchoronCell = 0;
uiLavanthorCell = 0;
uiXevozzCell = 0;
uiZuramatCell = 0;
uiMainDoor = 0;
uiTeleportationPortal = 0;
uiSaboteurPortal = 0;
trashMobs.Clear();
uiRemoveNpc = 0;
uiDoorIntegrity = 100;
uiWaveCount = 0;
uiLocation = (byte)RandomHelper.URand(0, 5);
uiFirstBoss = 0;
uiSecondBoss = 0;
uiCountErekemGuards = 0;
uiCountActivationCrystals = 0;
uiCyanigosaEventPhase = 1;
uiActivationTimer = 5000;
uiDoorSpellTimer = 2000;
uiCyanigosaEventTimer = 3 * Time.InMilliseconds;
bActive = false;
bIsDoorSpellCast = false;
bCrystalActivated = false;
defenseless = true;
uiMainEventPhase = EncounterState.NotStarted;
}
public override bool IsEncounterInProgress()
{
for (byte i = 0; i < MAX_ENCOUNTER; ++i)
if ((EncounterState)m_auiEncounter[i] == EncounterState.InProgress)
return true;
return false;
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case CREATURE_XEVOZZ:
uiXevozz = creature.GetGUID();
break;
case CREATURE_LAVANTHOR:
uiLavanthor = creature.GetGUID();
break;
case CREATURE_ICHORON:
uiIchoron = creature.GetGUID();
break;
case CREATURE_ZURAMAT:
uiZuramat = creature.GetGUID();
break;
case CREATURE_EREKEM:
uiErekem = creature.GetGUID();
break;
case CREATURE_EREKEM_GUARD:
if (uiCountErekemGuards < 2)
{
uiErekemGuard[uiCountErekemGuards++] = creature.GetGUID();
creature.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
}
break;
case CREATURE_MORAGG:
uiMoragg = creature.GetGUID();
break;
case CREATURE_CYANIGOSA:
uiCyanigosa = creature.GetGUID();
creature.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
break;
case CREATURE_SINCLARI:
uiSinclari = creature.GetGUID();
break;
}
if (creature.GetGUID() == uiFirstBoss || creature.GetGUID() == uiSecondBoss)
{
creature.AllLootRemovedFromCorpse();
creature.RemoveLootMode(1);
}
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GO_EREKEM_GUARD_1_DOOR:
uiErekemLeftGuardCell = go.GetGUID();
break;
case GO_EREKEM_GUARD_2_DOOR:
uiErekemRightGuardCell = go.GetGUID();
break;
case GO_EREKEM_DOOR:
uiErekemCell = go.GetGUID();
break;
case GO_ZURAMAT_DOOR:
uiZuramatCell = go.GetGUID();
break;
case GO_LAVANTHOR_DOOR:
uiLavanthorCell = go.GetGUID();
break;
case GO_MORAGG_DOOR:
uiMoraggCell = go.GetGUID();
break;
case GO_ICHORON_DOOR:
uiIchoronCell = go.GetGUID();
break;
case GO_XEVOZZ_DOOR:
uiXevozzCell = go.GetGUID();
break;
case GO_MAIN_DOOR:
uiMainDoor = go.GetGUID();
break;
case GO_ACTIVATION_CRYSTAL:
if (uiCountActivationCrystals < 4)
uiActivationCrystal[uiCountActivationCrystals++] = go.GetGUID();
break;
}
}
public override void SetData(uint type, uint data)
{
switch (type)
{
case DATA_1ST_BOSS_EVENT:
UpdateEncounterState(EncounterCreditType.KillCreature, CREATURE_EREKEM, null);
m_auiEncounter[0] = (byte)data;
if ((EncounterState)data == EncounterState.Done)
SaveToDB();
break;
case DATA_2ND_BOSS_EVENT:
UpdateEncounterState(EncounterCreditType.KillCreature, CREATURE_MORAGG, null);
m_auiEncounter[1] = (byte)data;
if ((EncounterState)data == EncounterState.Done)
SaveToDB();
break;
case DATA_CYANIGOSA_EVENT:
m_auiEncounter[2] = (byte)data;
if ((EncounterState)data == EncounterState.Done)
{
SaveToDB();
uiMainEventPhase = EncounterState.EncounterState.Done;
if (GameObject pMainDoor = instance.GetGameObject(uiMainDoor))
pMainDoor.SetGoState(GameObjectState.Active);
}
break;
case DATA_WAVE_COUNT:
uiWaveCount = (byte)data;
bActive = true;
break;
case DATA_REMOVE_NPC:
uiRemoveNpc = (byte)data;
break;
case DATA_PORTAL_LOCATION:
uiLocation = (byte)data;
break;
case DATA_DOOR_INTEGRITY:
uiDoorIntegrity = (byte)data;
defenseless = false;
DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, uiDoorIntegrity);
break;
case DATA_NPC_PRESENCE_AT_DOOR_ADD:
NpcAtDoorCastingList.Add((byte)data);
break;
case DATA_NPC_PRESENCE_AT_DOOR_REMOVE:
if (!NpcAtDoorCastingList.Empty())
NpcAtDoorCastingList.RemoveAt(0);//.pop_back();
break;
case DATA_MAIN_DOOR:
if (GameObject pMainDoor = instance.GetGameObject(uiMainDoor))
{
switch ((GameObjectState)data)
{
case GameObjectState.Active:
case GameObjectState.Ready:
case GameObjectState.ActiveAlternative:
pMainDoor.SetGoState((GameObjectState)data);
break;
}
}
break;
case DATA_START_BOSS_ENCOUNTER:
switch (uiWaveCount)
{
case 6:
StartBossEncounter(uiFirstBoss);
break;
case 12:
StartBossEncounter(uiSecondBoss);
break;
}
break;
case DATA_ACTIVATE_CRYSTAL:
ActivateCrystal();
break;
case DATA_MAIN_EVENT_PHASE:
uiMainEventPhase = (EncounterState)data;
if ((EncounterState)data == EncounterState.InProgress) // Start event
{
if (GameObject mainDoor = instance.GetGameObject(uiMainDoor))
mainDoor.SetGoState(GameObjectState.Ready);
uiWaveCount = 1;
bActive = true;
for (int i = 0; i < 4; ++i)
{
if (GameObject crystal = instance.GetGameObject(uiActivationCrystal[i]))
crystal.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
uiRemoveNpc = 0; // might not have been reset after a wipe on a boss.
}
break;
}
}
public override void SetData64(uint type, ulong data)
{
switch (type)
{
case DATA_ADD_TRASH_MOB:
trashMobs.Add(data);
break;
case DATA_DEL_TRASH_MOB:
trashMobs.Remove(data);
break;
}
}
public override uint GetData(uint type)
{
switch (type)
{
case DATA_1ST_BOSS_EVENT:
return m_auiEncounter[0];
case DATA_2ND_BOSS_EVENT:
return m_auiEncounter[1];
case DATA_CYANIGOSA_EVENT:
return m_auiEncounter[2];
case DATA_WAVE_COUNT:
return uiWaveCount;
case DATA_REMOVE_NPC:
return uiRemoveNpc;
case DATA_PORTAL_LOCATION:
return uiLocation;
case DATA_DOOR_INTEGRITY:
return uiDoorIntegrity;
case DATA_NPC_PRESENCE_AT_DOOR:
return (uint)NpcAtDoorCastingList.Count;
case DATA_FIRST_BOSS:
return uiFirstBoss;
case DATA_SECOND_BOSS:
return uiSecondBoss;
case DATA_MAIN_EVENT_PHASE:
return (uint)uiMainEventPhase;
case DATA_DEFENSELESS:
return (uint)(defenseless ? 1 : 0);
}
return 0;
}
public override ulong GetData64(uint identifier)
{
switch (identifier)
{
case DATA_MORAGG: return uiMoragg;
case DATA_EREKEM: return uiErekem;
case DATA_EREKEM_GUARD_1: return uiErekemGuard[0];
case DATA_EREKEM_GUARD_2: return uiErekemGuard[1];
case DATA_ICHORON: return uiIchoron;
case DATA_LAVANTHOR: return uiLavanthor;
case DATA_XEVOZZ: return uiXevozz;
case DATA_ZURAMAT: return uiZuramat;
case DATA_CYANIGOSA: return uiCyanigosa;
case DATA_MORAGG_CELL: return uiMoraggCell;
case DATA_EREKEM_CELL: return uiErekemCell;
case DATA_EREKEM_RIGHT_GUARD_CELL: return uiErekemRightGuardCell;
case DATA_EREKEM_LEFT_GUARD_CELL: return uiErekemLeftGuardCell;
case DATA_ICHORON_CELL: return uiIchoronCell;
case DATA_LAVANTHOR_CELL: return uiLavanthorCell;
case DATA_XEVOZZ_CELL: return uiXevozzCell;
case DATA_ZURAMAT_CELL: return uiZuramatCell;
case DATA_MAIN_DOOR: return uiMainDoor;
case DATA_SINCLARI: return uiSinclari;
case DATA_TELEPORTATION_PORTAL: return uiTeleportationPortal;
case DATA_SABOTEUR_PORTAL: return uiSaboteurPortal;
}
return 0;
}
void SpawnPortal()
{
SetData(DATA_PORTAL_LOCATION, (GetData(DATA_PORTAL_LOCATION) + RandomHelper.URand(1, 5)) % 6);
if (Creature pSinclari = instance.GetCreature(uiSinclari))
if (Creature portal = pSinclari.SummonCreature(CREATURE_TELEPORTATION_PORTAL, PortalLocation[GetData(DATA_PORTAL_LOCATION)], TempSummonType.CorpseDespawn))
uiTeleportationPortal = portal.GetGUID();
}
void StartBossEncounter(byte uiBoss, bool bForceRespawn = true)
{
Creature pBoss = null;
switch (uiBoss)
{
case BOSS_MORAGG:
HandleGameObject(uiMoraggCell, bForceRespawn);
pBoss = instance.GetCreature(uiMoragg);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove1);
break;
case BOSS_EREKEM:
HandleGameObject(uiErekemCell, bForceRespawn);
HandleGameObject(uiErekemRightGuardCell, bForceRespawn);
HandleGameObject(uiErekemLeftGuardCell, bForceRespawn);
pBoss = instance.GetCreature(uiErekem);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove2);
if (Creature pGuard1 = instance.GetCreature(uiErekemGuard[0]))
{
if (bForceRespawn)
pGuard1.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
else
pGuard1.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
pGuard1.GetMotionMaster().MovePoint(0, BossStartMove21);
}
if (Creature pGuard2 = instance.GetCreature(uiErekemGuard[1]))
{
if (bForceRespawn)
pGuard2.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
else
pGuard2.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
pGuard2.GetMotionMaster().MovePoint(0, BossStartMove22);
}
break;
case BOSS_ICHORON:
HandleGameObject(uiIchoronCell, bForceRespawn);
pBoss = instance.GetCreature(uiIchoron);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove3);
break;
case BOSS_LAVANTHOR:
HandleGameObject(uiLavanthorCell, bForceRespawn);
pBoss = instance.GetCreature(uiLavanthor);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove4);
break;
case BOSS_XEVOZZ:
HandleGameObject(uiXevozzCell, bForceRespawn);
pBoss = instance.GetCreature(uiXevozz);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove5);
break;
case BOSS_ZURAMAT:
HandleGameObject(uiZuramatCell, bForceRespawn);
pBoss = instance.GetCreature(uiZuramat);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove6);
break;
}
// generic boss state changes
if (pBoss)
{
pBoss.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
pBoss.SetReactState(ReactStates.Aggressive);
if (!bForceRespawn)
{
if (pBoss.IsDead())
{
// respawn but avoid to be looted again
pBoss.Respawn();
pBoss.RemoveLootMode(1);
}
pBoss.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
uiWaveCount = 0;
}
}
}
void AddWave()
{
DoUpdateWorldState(WORLD_STATE_VH, 1);
DoUpdateWorldState(WORLD_STATE_VH_WAVE_COUNT, uiWaveCount);
switch (uiWaveCount)
{
case 6:
if (uiFirstBoss == 0)
uiFirstBoss = (byte)RandomHelper.URand(1, 6);
if (Creature pSinclari = instance.GetCreature(uiSinclari))
{
if (Creature pPortal = pSinclari.SummonCreature(CREATURE_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TempSummonType.CorpseDespawn))
uiSaboteurPortal = pPortal.GetGUID();
if (Creature pAzureSaboteur = pSinclari.SummonCreature(CREATURE_SABOTEOUR, MiddleRoomLocation, TempSummonType.DeadDespawn))
pAzureSaboteur.CastSpell(pAzureSaboteur, SABOTEUR_SHIELD_EFFECT, false);
}
break;
case 12:
if (uiSecondBoss == 0)
do
{
uiSecondBoss = (byte)RandomHelper.URand(1, 6);
} while (uiSecondBoss == uiFirstBoss);
if (Creature pSinclari = instance.GetCreature(uiSinclari))
{
if (Creature pPortal = pSinclari.SummonCreature(CREATURE_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TempSummonType.CorpseDespawn))
uiSaboteurPortal = pPortal.GetGUID();
if (Creature pAzureSaboteur = pSinclari.SummonCreature(CREATURE_SABOTEOUR, MiddleRoomLocation, TempSummonType.DeadDespawn))
pAzureSaboteur.CastSpell(pAzureSaboteur, SABOTEUR_SHIELD_EFFECT, false);
}
break;
case 18:
{
Creature pSinclari = instance.GetCreature(uiSinclari);
if (pSinclari)
pSinclari.SummonCreature(CREATURE_CYANIGOSA, CyanigosasSpawnLocation, TempSummonType.DeadDespawn);
break;
}
case 1:
{
if (GameObject pMainDoor = instance.GetGameObject(uiMainDoor))
pMainDoor.SetGoState(GameObjectState.Ready);
DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, 100);
// no break
}
goto default;
default:
SpawnPortal();
break;
}
}
public override string GetSaveData()
{
OUT_SAVE_INST_DATA();
str_data = string.Format("V H {0} {1} {2} {3} {4}", m_auiEncounter[0], m_auiEncounter[1], m_auiEncounter[2], uiFirstBoss, uiSecondBoss);
OUT_SAVE_INST_DATA_COMPLETE();
return str_data;
}
public override void Load(string str)
{
if (!string.IsNullOrEmpty(str))
{
OUT_LOAD_INST_DATA_FAIL();
return;
}
OUT_LOAD_INST_DATA(str);
StringArguments args = new StringArguments(str);
char dataHead1 = args.NextChar();
char dataHead2 = args.NextChar();
ushort data0 = args.NextUInt16();
ushort data1 = args.NextUInt16();
ushort data2 = args.NextUInt16();
ushort data3 = args.NextUInt16();
ushort data4 = args.NextUInt16();
if (dataHead1 == 'V' && dataHead2 == 'H')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
for (byte i = 0; i < MAX_ENCOUNTER; ++i)
if ((EncounterState)m_auiEncounter[i] == EncounterState.InProgress)
m_auiEncounter[i] = (ushort)EncounterState.NotStarted;
uiFirstBoss = (byte)data3;
uiSecondBoss = (byte)data4;
}
else
OUT_LOAD_INST_DATA_FAIL();
OUT_LOAD_INST_DATA_COMPLETE();
}
bool CheckWipe()
{
var players = instance.GetPlayers();
foreach (var player in players)
{
if (player.IsGameMaster())
continue;
if (player.IsAlive())
return false;
}
return true;
}
public override void Update(uint diff)
{
if (!instance.HavePlayers())
return;
// portals should spawn if other portal is dead and doors are closed
if (bActive && uiMainEventPhase == EncounterState.InProgress)
{
if (uiActivationTimer < diff)
{
AddWave();
bActive = false;
// 1 minute waiting time after each boss fight
uiActivationTimer = (uint)((uiWaveCount == 6 || uiWaveCount == 12) ? 60000 : 5000);
} else uiActivationTimer -= diff;
}
// if main event is in progress and players have wiped then reset instance
if (uiMainEventPhase == EncounterState.InProgress && CheckWipe())
{
SetData(DATA_REMOVE_NPC, 1);
StartBossEncounter(uiFirstBoss, false);
StartBossEncounter(uiSecondBoss, false);
SetData(DATA_MAIN_DOOR, GameObjectState.Active);
SetData(DATA_WAVE_COUNT, 0);
uiMainEventPhase = EncounterState.NotStarted;
for (int i = 0; i < 4; ++i)
{
if (GameObject crystal = instance.GetGameObject(uiActivationCrystal[i]))
crystal.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
if (Creature pSinclari = instance.GetCreature(uiSinclari))
{
pSinclari.SetVisible(true);
List<Creature> GuardList = new List<Creature>();
pSinclari.GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
if (!GuardList.Empty())
{
foreach (var pGuard in GuardList)
{
pGuard.SetVisible(true);
pGuard.SetReactState(ReactStates.Aggressive);
pGuard.GetMotionMaster().MovePoint(1, pGuard.GetHomePosition());
}
}
pSinclari.GetMotionMaster().MovePoint(1, pSinclari.GetHomePosition());
pSinclari.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
}
}
// Cyanigosa is spawned but not tranformed, prefight event
Creature pCyanigosa = instance.GetCreature(uiCyanigosa);
if (pCyanigosa && !pCyanigosa.HasAura(CYANIGOSA_SPELL_TRANSFORM))
{
if (uiCyanigosaEventTimer <= diff)
{
switch (uiCyanigosaEventPhase)
{
case 1:
pCyanigosa.CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false);
pCyanigosa.GetAI().Talk(CYANIGOSA_SAY_SPAWN);
uiCyanigosaEventTimer = 7 * Time.InMilliseconds;
++uiCyanigosaEventPhase;
break;
case 2:
pCyanigosa.GetMotionMaster().MoveJump(MiddleRoomLocation.GetPositionX(), MiddleRoomLocation.GetPositionY(), MiddleRoomLocation.GetPositionZ(), 10.0f, 20.0f);
pCyanigosa.CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false);
uiCyanigosaEventTimer = 7 * Time.InMilliseconds;
++uiCyanigosaEventPhase;
break;
case 3:
pCyanigosa.RemoveAurasDueToSpell(CYANIGOSA_BLUE_AURA);
pCyanigosa.CastSpell(pCyanigosa, CYANIGOSA_SPELL_TRANSFORM, 0);
pCyanigosa.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
pCyanigosa.SetReactState(ReactStates.Aggressive);
uiCyanigosaEventTimer = 2 * Time.InMilliseconds;
++uiCyanigosaEventPhase;
break;
case 4:
uiCyanigosaEventPhase = 0;
break;
}
} else uiCyanigosaEventTimer -= diff;
}
// if there are NPCs in front of the prison door, which are casting the door seal spell and doors are active
if (GetData(DATA_NPC_PRESENCE_AT_DOOR) && uiMainEventPhase == EncounterState.InProgress)
{
// if door integrity is > 0 then decrase it's integrity state
if (GetData(DATA_DOOR_INTEGRITY))
{
if (uiDoorSpellTimer < diff)
{
SetData(DATA_DOOR_INTEGRITY, GetData(DATA_DOOR_INTEGRITY) - 1);
uiDoorSpellTimer = 2000;
} else uiDoorSpellTimer -= diff;
}
// else set door state to active (means door will open and group have failed to sustain mob invasion on the door)
else
{
SetData(DATA_MAIN_DOOR, GameObjectState.Active);
uiMainEventPhase = EncounterState.Fail;
}
}
}
void ActivateCrystal()
{
// just to make things easier we'll get the gameobject from the map
GameObject invoker = instance.GetGameObject(uiActivationCrystal[0]);
if (!invoker)
return;
SpellInfo spellInfoLightning = Global.SpellMgr.GetSpellInfo(SPELL_ARCANE_LIGHTNING);
if (spellInfoLightning == null)
return;
// the orb
TempSummon trigger = invoker.SummonCreature(NPC_DEFENSE_SYSTEM, ArcaneSphere, TempSummonType.ManualDespawn, 0);
if (!trigger)
return;
// visuals
trigger.CastSpell(trigger, spellInfoLightning, true, 0, 0, trigger.GetGUID());
// Kill all mobs registered with SetData64(ADD_TRASH_MOB)
foreach (var guid in trashMobs)
{
Creature creature = instance.GetCreature(guid);
if (creature && creature.IsAlive())
trigger.Kill(creature);
}
}
public override void ProcessEvent(WorldObject go, uint uiEventId)
{
switch (uiEventId)
{
case EVENT_ACTIVATE_CRYSTAL:
bCrystalActivated = true; // Activation by player's will throw event signal
ActivateCrystal();
break;
}
}
#region Fields
ulong uiMoragg;
ulong uiErekem;
ulong[] uiErekemGuard = new ulong[2];
ulong uiIchoron;
ulong uiLavanthor;
ulong uiXevozz;
ulong uiZuramat;
ulong uiCyanigosa;
ulong uiSinclari;
ulong uiMoraggCell;
ulong uiErekemCell;
ulong uiErekemLeftGuardCell;
ulong uiErekemRightGuardCell;
ulong uiIchoronCell;
ulong uiLavanthorCell;
ulong uiXevozzCell;
ulong uiZuramatCell;
ulong uiMainDoor;
ulong uiTeleportationPortal;
ulong uiSaboteurPortal;
ulong[] uiActivationCrystal = new ulong[4];
uint uiActivationTimer;
uint uiCyanigosaEventTimer;
uint uiDoorSpellTimer;
List<ulong> trashMobs = new List<ulong>(); // to kill with crystal
byte uiWaveCount;
byte uiLocation;
byte uiFirstBoss;
byte uiSecondBoss;
byte uiRemoveNpc;
byte uiDoorIntegrity;
ushort[] m_auiEncounter = new ushort[MAX_ENCOUNTER];
byte uiCountErekemGuards;
byte uiCountActivationCrystals;
byte uiCyanigosaEventPhase;
EncounterState uiMainEventPhase; // SPECIAL: pre event animations, InProgress: event itself
bool bActive;
bool bWiped;
bool bIsDoorSpellCast;
bool bCrystalActivated;
bool defenseless;
List<byte> NpcAtDoorCastingList = new List<byte>();
string str_data;
#endregion
}
}
}
@@ -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
{
}
+116
View File
@@ -0,0 +1,116 @@
/*
* 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 : SpellScriptLoader
{
public spell_wintergrasp_defender_teleport() : base("spell_wintergrasp_defender_teleport") { }
class spell_wintergrasp_defender_teleport_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_wintergrasp_defender_teleport_SpellScript();
}
}
[Script]
class spell_wintergrasp_defender_teleport_trigger : SpellScriptLoader
{
public spell_wintergrasp_defender_teleport_trigger() : base("spell_wintergrasp_defender_teleport_trigger") { }
class spell_wintergrasp_defender_teleport_trigger_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_wintergrasp_defender_teleport_trigger_SpellScript();
}
}
[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;
}
}
}
+340
View File
@@ -0,0 +1,340 @@
/*
* 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.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 : CreatureScript
{
public npc_aeranas() : base("npc_aeranas") { }
class npc_aeranasAI : ScriptedAI
{
public npc_aeranasAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_aeranasAI(creature);
}
}
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 : CreatureScript
{
public npc_ancestral_wolf() : base("npc_ancestral_wolf") { }
class npc_ancestral_wolfAI : npc_escortAI
{
public npc_ancestral_wolfAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_ancestral_wolfAI(creature);
}
}
[Script]
class npc_wounded_blood_elf : CreatureScript
{
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;
public npc_wounded_blood_elf() : base("npc_wounded_blood_elf") { }
class npc_wounded_blood_elfAI : npc_escortAI
{
public npc_wounded_blood_elfAI(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;
}
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_wounded_blood_elfAI(creature);
}
}
[Script]
class npc_fel_guard_hound : CreatureScript
{
const uint SPELL_SUMMON_POO = 37688;
const uint NPC_DERANGED_HELBOAR = 16863;
public npc_fel_guard_hound() : base("npc_fel_guard_hound") { }
class npc_fel_guard_houndAI : ScriptedAI
{
public npc_fel_guard_houndAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_fel_guard_houndAI(creature);
}
}
}
+402
View File
@@ -0,0 +1,402 @@
/*
* 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_mortog_steamhead : CreatureScript
{
public npc_mortog_steamhead() : base("npc_mortog_steamhead") { }
public override bool OnGossipHello(Player player, Creature creature)
{
if (creature.IsVendor() && player.GetReputationRank(942) == ReputationRank.Exalted)
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Vendor, GOSSIP_TEXT_BROWSE_GOODS, eTradeskill.GossipSenderMain, eTradeskill.GossipActionTrade);
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.GossipActionTrade)
player.GetSession().SendListInventory(creature.GetGUID());
return true;
}
const string GOSSIP_TEXT_BROWSE_GOODS = "I'd like to browse your goods.";
}
[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;
}
[Script]
class npc_timothy_daniels : CreatureScript
{
public npc_timothy_daniels() : base("npc_timothy_daniels") { }
public override bool OnGossipHello(Player player, Creature creature)
{
if (creature.IsQuestGiver())
player.PrepareQuestMenu(creature.GetGUID());
if (creature.IsVendor())
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Vendor, GOSSIP_TEXT_BROWSE_POISONS, eTradeskill.GossipSenderMain, eTradeskill.GossipActionTrade);
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_TIMOTHY_DANIELS_ITEM1, 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();
switch (action)
{
case eTradeskill.GossipActionInfoDef + 1:
player.SEND_GOSSIP_MENU(GOSSIP_TEXTID_TIMOTHY_DANIELS1, creature.GetGUID());
break;
case eTradeskill.GossipActionTrade:
player.GetSession().SendListInventory(creature.GetGUID());
break;
}
return true;
}
const string GOSSIP_TIMOTHY_DANIELS_ITEM1 = "Specialist, eh? Just what kind of specialist are you, anyway?";
const string GOSSIP_TEXT_BROWSE_POISONS = "Let me browse your reagents and poison supplies.";
const uint GOSSIP_TEXTID_TIMOTHY_DANIELS1 = 9239;
}
}
+137
View File
@@ -0,0 +1,137 @@
/*
* 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 : CreatureScript
{
public npc_pet_dk_ebon_gargoyle() : base("npc_pet_dk_ebon_gargoyle") { }
class npc_pet_dk_ebon_gargoyleAI : CasterAI
{
public npc_pet_dk_ebon_gargoyleAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_pet_dk_ebon_gargoyleAI(creature);
}
}
[Script]
class npc_pet_dk_guardian : CreatureScript
{
public npc_pet_dk_guardian() : base("npc_pet_dk_guardian") { }
class npc_pet_dk_guardianAI : AggressorAI
{
public npc_pet_dk_guardianAI(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);
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_pet_dk_guardianAI(creature);
}
}
}
+85
View File
@@ -0,0 +1,85 @@
/*
* 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 : CreatureScript
{
public npc_pet_gen_mojo() : base("npc_pet_gen_mojo") { }
class npc_pet_gen_mojoAI : ScriptedAI
{
public npc_pet_gen_mojoAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_pet_gen_mojoAI(creature);
}
}
}
+127
View File
@@ -0,0 +1,127 @@
/*
* 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 : CreatureScript
{
public npc_pet_hunter_snake_trap() : base("npc_pet_hunter_snake_trap") { }
class npc_pet_hunter_snake_trapAI : ScriptedAI
{
public npc_pet_hunter_snake_trapAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_pet_hunter_snake_trapAI(creature);
}
const uint SpellCripplingPoison = 30981; // Viper
const uint SpellDeadlyPoisonPassive = 34657; // Venomous Snake
const uint SpellMindNumbingPoison = 25810; // Viper
const int NpcViper = 19921;
}
}
+252
View File
@@ -0,0 +1,252 @@
/*
* 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 : CreatureScript
{
public npc_pet_mage_mirror_image() : base("npc_pet_mage_mirror_image") { }
class npc_pet_mage_mirror_imageAI : CasterAI
{
public npc_pet_mage_mirror_imageAI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_pet_mage_mirror_imageAI(creature);
}
}
}
+83
View File
@@ -0,0 +1,83 @@
/*
* 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 : CreatureScript
{
public npc_pet_pri_lightwell() : base("npc_pet_pri_lightwell") { }
class npc_pet_pri_lightwellAI : PassiveAI
{
public npc_pet_pri_lightwellAI(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();
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_pet_pri_lightwellAI(creature);
}
}
[Script]
class npc_pet_pri_shadowfiend : CreatureScript
{
public npc_pet_pri_shadowfiend() : base("npc_pet_pri_shadowfiend") { }
class npc_pet_pri_shadowfiendAI : PetAI
{
public npc_pet_pri_shadowfiendAI(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit summoner)
{
if (summoner.HasAura(SpellIds.GlyphOfShadowFiend))
DoCastAOE(SpellIds.ShadowFiendDeath);
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_pet_pri_shadowfiendAI(creature);
}
}
}
+133
View File
@@ -0,0 +1,133 @@
/*
* 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 : CreatureScript
{
public npc_pet_shaman_earth_elemental() : base("npc_pet_shaman_earth_elemental") { }
class npc_pet_shaman_earth_elementalAI : ScriptedAI
{
public npc_pet_shaman_earth_elementalAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_pet_shaman_earth_elementalAI(creature);
}
}
[Script]
class npc_pet_shaman_fire_elemental : CreatureScript
{
public npc_pet_shaman_fire_elemental() : base("npc_pet_shaman_fire_elemental") { }
public class npc_pet_shaman_fire_elementalAI : ScriptedAI
{
public npc_pet_shaman_fire_elementalAI(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;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_pet_shaman_fire_elementalAI(creature);
}
}
}
+36
View File
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Scripts")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Scripts")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("92f1ec3f-c8fc-4423-91ee-00ec1b5c5272")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+193
View File
@@ -0,0 +1,193 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9E28B9C1-E473-4DAE-813F-3243CE318736}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Scripts</RootNamespace>
<AssemblyName>Scripts</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Build\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<Optimize>false</Optimize>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Build\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Build\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="EasternKingdoms\Deadmines\InstanceDeadmines.cs" />
<Compile Include="EasternKingdoms\TheStockade\BossHogger.cs" />
<Compile Include="EasternKingdoms\TheStockade\InstanceTheStockade.cs" />
<Compile Include="Northrend\AzjolNerub\AzjolNerub\BossAnubarak.cs" />
<Compile Include="Northrend\AzjolNerub\AzjolNerub\BossKrikthirTheGatewatcher.cs" />
<Compile Include="Northrend\AzjolNerub\AzjolNerub\BossNadronox.cs" />
<Compile Include="Northrend\AzjolNerub\AzjolNerub\InstanceAzjolNerub.cs" />
<Compile Include="Northrend\DraktharonKeep\BossKingDred.cs" />
<Compile Include="Northrend\DraktharonKeep\BossNovos.cs" />
<Compile Include="Northrend\DraktharonKeep\BossTharonJa.cs" />
<Compile Include="Northrend\DraktharonKeep\BossTrollgore.cs" />
<Compile Include="Northrend\DraktharonKeep\InstanceDrakTharonKeep.cs" />
<Compile Include="Northrend\Gundrak\BossDrakkariColossus.cs" />
<Compile Include="Northrend\Gundrak\BossEck.cs" />
<Compile Include="Northrend\Gundrak\InstanceGundrak.cs" />
<Compile Include="Northrend\Naxxramas\BossAnubrekhan.cs" />
<Compile Include="Spells\DemonHunter.cs" />
<Compile Include="Spells\Warlock.cs" />
<Compile Include="World\BossEmeraldDragons.cs" />
<Compile Include="World\DuelReset.cs" />
<Compile Include="EasternKingdoms\Karazhan\Curator.cs" />
<Compile Include="EasternKingdoms\Karazhan\InstanceKarazhan.cs" />
<Compile Include="EasternKingdoms\Karazhan\AttumenMidnight.cs" />
<Compile Include="EasternKingdoms\Karazhan\Moroes.cs" />
<Compile Include="EasternKingdoms\Karazhan\OperaEvent.cs" />
<Compile Include="EasternKingdoms\ScarletEnclave\Chapter1.cs" />
<Compile Include="EasternKingdoms\EversongWoods.cs" />
<Compile Include="Kalimdor\Durotar.cs" />
<Compile Include="Kalimdor\RageFireChasm.cs" />
<Compile Include="Northrend\AzjolNerub\Ahnkahet\BossAmanitar.cs" />
<Compile Include="Northrend\AzjolNerub\Ahnkahet\BossElderNadox.cs" />
<Compile Include="Northrend\AzjolNerub\Ahnkahet\BossHeraldVolazj.cs" />
<Compile Include="Northrend\AzjolNerub\Ahnkahet\BossJedogaShadowseeker.cs" />
<Compile Include="Northrend\AzjolNerub\Ahnkahet\BossPrinceTaldaram.cs" />
<Compile Include="Northrend\AzjolNerub\Ahnkahet\InstanceAhnahet.cs" />
<Compile Include="Northrend\CrusadersColiseum\TrialOfTheChampion\GrandChampions.cs" />
<Compile Include="Northrend\CrusadersColiseum\TrialOfTheChampion\InstanceTrialOfTheChampion.cs" />
<Compile Include="Northrend\CrusadersColiseum\TrialOfTheChampion\TrialOfTheChampion.cs" />
<Compile Include="Northrend\Nexus\EyeOfEternity\BossMalygos.cs" />
<Compile Include="Northrend\Nexus\EyeOfEternity\EyeOfEternity.cs" />
<Compile Include="Northrend\Nexus\Nexus\BossAnomalus.cs" />
<Compile Include="Northrend\Nexus\Nexus\BossKeristrasza.cs" />
<Compile Include="Northrend\Nexus\Nexus\BossMagusTelestra.cs" />
<Compile Include="Northrend\Nexus\Nexus\BossNexusCommanders.cs" />
<Compile Include="Northrend\Nexus\Nexus\BossOrmorok.cs" />
<Compile Include="Northrend\Nexus\Nexus\InstanceNexus.cs" />
<Compile Include="Northrend\Nexus\Oculus\InstanceOculus.cs" />
<Compile Include="Northrend\Ulduar\Mimiron.cs" />
<Compile Include="Northrend\Ulduar\Razorscale.cs" />
<Compile Include="Northrend\Ulduar\Xt002.cs" />
<Compile Include="Spells\Holiday.cs" />
<Compile Include="Spells\Items.cs" />
<Compile Include="Spells\Monk.cs" />
<Compile Include="World\Achievements.cs" />
<Compile Include="World\AreaTrigger.cs" />
<Compile Include="World\GameObjects.cs" />
<Compile Include="World\Guards.cs" />
<Compile Include="World\ItemScripts.cs" />
<Compile Include="World\MobGenericCreature.cs" />
<Compile Include="World\NpcProfessions.cs" />
<Compile Include="World\NpcSpecial.cs" />
<Compile Include="Northrend\CrusadersColiseum\TrialOfTheCrusader\LordJaraxxus.cs" />
<Compile Include="Northrend\CrusadersColiseum\TrialOfTheCrusader\NorthrendBeasts.cs" />
<Compile Include="Northrend\CrusadersColiseum\TrialOfTheCrusader\TrialOfTheCrusader.cs" />
<Compile Include="Northrend\CrusadersColiseum\TrialOfTheCrusader\TrialOfTheCrusaderConst.cs" />
<Compile Include="Northrend\WinterGrasp.cs" />
<Compile Include="Pets\Shaman.cs" />
<Compile Include="Pets\Priest.cs" />
<Compile Include="Pets\Mage.cs" />
<Compile Include="Pets\Hunter.cs" />
<Compile Include="Pets\DeathKinght.cs" />
<Compile Include="Pets\Generic.cs" />
<Compile Include="Northrend\Dalaran.cs" />
<Compile Include="Northrend\IcecrownCitadel\GunshipBattle.cs" />
<Compile Include="Northrend\IcecrownCitadel\IcecrownCitadel.cs" />
<Compile Include="Northrend\IcecrownCitadel\IcecrownCitadelConst.cs" />
<Compile Include="Northrend\IcecrownCitadel\IcecrownCitadelTeleport.cs" />
<Compile Include="Northrend\IcecrownCitadel\InstanceIcecrownCitadel.cs" />
<Compile Include="Northrend\IcecrownCitadel\LadyDeathwhisper.cs" />
<Compile Include="Northrend\IcecrownCitadel\LordMarrowgar.cs" />
<Compile Include="Northrend\IcecrownCitadel\Sindragosa.cs" />
<Compile Include="Northrend\IcecrownCitadel\TheLichKing.cs" />
<Compile Include="Northrend\IcecrownCitadel\ValithriaDreamwalker.cs" />
<Compile Include="Northrend\Ulduar\AlgalonTheObserver.cs" />
<Compile Include="Northrend\Ulduar\FlameLeviathan.cs" />
<Compile Include="Northrend\Ulduar\UlduarConst.cs" />
<Compile Include="Northrend\Ulduar\UlduarInstance.cs" />
<Compile Include="Northrend\Ulduar\YoggSaron.cs" />
<Compile Include="Outlands\HellfirePeninsula.cs" />
<Compile Include="Outlands\Zangarmarsh.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Spells\DeathKnight.cs" />
<Compile Include="Spells\Druid.cs" />
<Compile Include="Spells\Generic.cs" />
<Compile Include="Spells\Hunter.cs" />
<Compile Include="Spells\Mage.cs" />
<Compile Include="Spells\Paladin.cs" />
<Compile Include="Spells\Priest.cs" />
<Compile Include="Spells\Quest.cs" />
<Compile Include="Spells\Rogue.cs" />
<Compile Include="Spells\Shaman.cs" />
<Compile Include="Spells\Warrior.cs" />
<Compile Include="Northrend\VioletHold\VioletHold.cs" />
<Compile Include="World\SceneScripts.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Framework\Framework.csproj">
<Project>{82d442a9-18c0-4c59-8ec6-0dfe3e34d334}</Project>
<Name>Framework</Name>
</ProjectReference>
<ProjectReference Include="..\Game\Game.csproj">
<Project>{83ef8d5c-afa1-4546-bcdd-6422d55b1515}</Project>
<Name>Game</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Custom\" />
<Folder Include="Northrend\FrozenHalls\ForgeOfSouls\" />
<Folder Include="Northrend\FrozenHalls\HallsOfReflection\" />
<Folder Include="Northrend\FrozenHalls\PitOfSaron\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
File diff suppressed because it is too large Load Diff
+29
View File
@@ -0,0 +1,29 @@
/*
* 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Scripts.Spells
{
class DemonHunter
{
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+984
View File
@@ -0,0 +1,984 @@
/*
* 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 : SpellScriptLoader
{
public spell_love_is_in_the_air_romantic_picnic() : base("spell_love_is_in_the_air_romantic_picnic") { }
class spell_love_is_in_the_air_romantic_picnic_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_love_is_in_the_air_romantic_picnic_AuraScript();
}
}
[Script] // 24750 Trick
class spell_hallow_end_trick : SpellScriptLoader
{
public spell_hallow_end_trick() : base("spell_hallow_end_trick") { }
class spell_hallow_end_trick_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_hallow_end_trick_SpellScript();
}
}
[Script] // 24751 Trick or Treat
class spell_hallow_end_trick_or_treat : SpellScriptLoader
{
public spell_hallow_end_trick_or_treat() : base("spell_hallow_end_trick_or_treat") { }
class spell_hallow_end_trick_or_treat_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_hallow_end_trick_or_treat_SpellScript();
}
}
[Script]
class spell_hallow_end_tricky_treat : SpellScriptLoader
{
public spell_hallow_end_tricky_treat() : base("spell_hallow_end_tricky_treat") { }
class spell_hallow_end_tricky_treat_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_hallow_end_tricky_treat_SpellScript();
}
}
[Script]
class spell_hallow_end_wand : SpellScriptLoader
{
public spell_hallow_end_wand() : base("spell_hallow_end_wand") { }
class spell_hallow_end_wand_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_hallow_end_wand_SpellScript();
}
}
[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 : SpellScriptLoader
{
public spell_pilgrims_bounty_buff_food(string name, uint triggeredSpellId) : base(name)
{
_triggeredSpellId = triggeredSpellId;
}
class spell_pilgrims_bounty_buff_food_AuraScript : AuraScript
{
public spell_pilgrims_bounty_buff_food_AuraScript(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;
}
public override AuraScript GetAuraScript()
{
return new spell_pilgrims_bounty_buff_food_AuraScript(_triggeredSpellId);
}
uint _triggeredSpellId;
}
[Script]
class spell_winter_veil_mistletoe : SpellScriptLoader
{
public spell_winter_veil_mistletoe() : base("spell_winter_veil_mistletoe") { }
class spell_winter_veil_mistletoe_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_winter_veil_mistletoe_SpellScript();
}
}
[Script] // 26275 - PX-238 Winter Wondervolt TRAP
class spell_winter_veil_px_238_winter_wondervolt : SpellScriptLoader
{
public spell_winter_veil_px_238_winter_wondervolt() : base("spell_winter_veil_px_238_winter_wondervolt") { }
class spell_winter_veil_px_238_winter_wondervolt_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_winter_veil_px_238_winter_wondervolt_SpellScript();
}
}
[Script] // 42924 - Giddyup!
class spell_brewfest_giddyup : SpellScriptLoader
{
public spell_brewfest_giddyup() : base("spell_brewfest_giddyup") { }
class spell_brewfest_giddyup_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_brewfest_giddyup_AuraScript();
}
}
// 43310 - Ram Level - Neutral
// 42992 - Ram - Trot
// 42993 - Ram - Canter
// 42994 - Ram - Gallop
[Script]
class spell_brewfest_ram : SpellScriptLoader
{
public spell_brewfest_ram() : base("spell_brewfest_ram") { }
class spell_brewfest_ram_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_brewfest_ram_AuraScript();
}
}
[Script] // 43052 - Ram Fatigue
class spell_brewfest_ram_fatigue : SpellScriptLoader
{
public spell_brewfest_ram_fatigue() : base("spell_brewfest_ram_fatigue") { }
class spell_brewfest_ram_fatigue_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_brewfest_ram_fatigue_AuraScript();
}
}
[Script] // 43450 - Brewfest - apple trap - friendly DND
class spell_brewfest_apple_trap : SpellScriptLoader
{
public spell_brewfest_apple_trap() : base("spell_brewfest_apple_trap") { }
class spell_brewfest_apple_trap_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_brewfest_apple_trap_AuraScript();
}
}
[Script] // 43332 - Exhausted Ram
class spell_brewfest_exhausted_ram : SpellScriptLoader
{
public spell_brewfest_exhausted_ram() : base("spell_brewfest_exhausted_ram") { }
class spell_brewfest_exhausted_ram_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_brewfest_exhausted_ram_AuraScript();
}
}
[Script] // 43714 - Brewfest - Relay Race - Intro - Force - Player to throw- DND
class spell_brewfest_relay_race_intro_force_player_to_throw : SpellScriptLoader
{
public spell_brewfest_relay_race_intro_force_player_to_throw() : base("spell_brewfest_relay_race_intro_force_player_to_throw") { }
class spell_brewfest_relay_race_intro_force_player_to_throw_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_brewfest_relay_race_intro_force_player_to_throw_SpellScript();
}
}
[Script]
class spell_brewfest_relay_race_turn_in : SpellScriptLoader
{
public spell_brewfest_relay_race_turn_in() : base("spell_brewfest_relay_race_turn_in") { }
class spell_brewfest_relay_race_turn_in_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_brewfest_relay_race_turn_in_SpellScript();
}
}
[Script] // 43876 - Dismount Ram
class spell_brewfest_dismount_ram : SpellScriptLoader
{
public spell_brewfest_dismount_ram() : base("spell_brewfest_dismount_ram") { }
class spell_brewfest_relay_race_intro_force_player_to_throw_SpellScript : SpellScript
{
void HandleScript(uint effIndex)
{
GetCaster().RemoveAura(SpellIds.RentalRacingRam);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
public override SpellScript GetSpellScript()
{
return new spell_brewfest_relay_race_intro_force_player_to_throw_SpellScript();
}
}
// 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 : SpellScriptLoader
{
public spell_brewfest_barker_bunny() : base("spell_brewfest_barker_bunny") { }
class spell_brewfest_barker_bunny_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_brewfest_barker_bunny_AuraScript();
}
}
[Script] // 45724 - Braziers Hit!
class spell_midsummer_braziers_hit : SpellScriptLoader
{
public spell_midsummer_braziers_hit() : base("spell_midsummer_braziers_hit") { }
class spell_midsummer_braziers_hit_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_midsummer_braziers_hit_AuraScript();
}
}
[Script]
class spell_gen_ribbon_pole_dancer_check : SpellScriptLoader
{
public spell_gen_ribbon_pole_dancer_check() : base("spell_gen_ribbon_pole_dancer_check") { }
class spell_gen_ribbon_pole_dancer_check_AuraScript : 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));
}
}
public override AuraScript GetAuraScript()
{
return new spell_gen_ribbon_pole_dancer_check_AuraScript();
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+169
View File
@@ -0,0 +1,169 @@
/*
* 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 : SpellScriptLoader
{
public spell_monk_crackling_jade_lightning() : base("spell_monk_crackling_jade_lightning") { }
class spell_monk_crackling_jade_lightning_AuraScript : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(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, Framework.Constants.AuraType.PeriodicDamage));
}
}
public override AuraScript GetAuraScript()
{
return new spell_monk_crackling_jade_lightning_AuraScript();
}
}
[Script] // 117959 - Crackling Jade Lightning
class spell_monk_crackling_jade_lightning_knockback_proc_aura : SpellScriptLoader
{
public spell_monk_crackling_jade_lightning_knockback_proc_aura() : base("spell_monk_crackling_jade_lightning_knockback_proc_aura") { }
class spell_monk_crackling_jade_lightning_aura_AuraScript : 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, Framework.Constants.AuraType.Dummy));
}
}
public override AuraScript GetAuraScript()
{
return new spell_monk_crackling_jade_lightning_aura_AuraScript();
}
}
[Script] // 115546 - Provoke
class spell_monk_provoke : SpellScriptLoader
{
public spell_monk_provoke() : base("spell_monk_provoke") { }
class spell_monk_provoke_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_monk_provoke_SpellScript();
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+217
View File
@@ -0,0 +1,217 @@
/*
* 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 : SpellScriptLoader
{
public spell_rog_killing_spree() : base("spell_rog_killing_spree") { }
class spell_rog_killing_spree_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_rog_killing_spree_SpellScript();
}
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.PickRandom();
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>();
}
public override AuraScript GetAuraScript()
{
return new spell_rog_killing_spree_AuraScript();
}
}
[Script] // 70805 - Rogue T10 2P Bonus -- THIS SHOULD BE REMOVED WITH NEW PROC SYSTEM.
class spell_rog_t10_2p_bonus : SpellScriptLoader
{
public spell_rog_t10_2p_bonus() : base("spell_rog_t10_2p_bonus") { }
class spell_rog_t10_2p_bonus_AuraScript : AuraScript
{
bool CheckProc(ProcEventInfo eventInfo)
{
return eventInfo.GetActor() == eventInfo.GetActionTarget();
}
public override void Register()
{
DoCheckProc.Add(new CheckProcHandler(CheckProc));
}
}
public override AuraScript GetAuraScript()
{
return new spell_rog_t10_2p_bonus_AuraScript();
}
}
[Script] // 2098 - Eviscerate
class spell_rog_eviscerate : SpellScriptLoader
{
public spell_rog_eviscerate() : base("spell_rog_eviscerate") { }
class spell_rog_eviscerate_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_rog_eviscerate_SpellScript();
}
}
[Script] // 32645 - Envenom
class spell_rog_envenom : SpellScriptLoader
{
public spell_rog_envenom() : base("spell_rog_envenom") { }
class spell_rog_envenom_SpellScript : 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));
}
}
public override SpellScript GetSpellScript()
{
return new spell_rog_envenom_SpellScript();
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+304
View File
@@ -0,0 +1,304 @@
/*
* 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.BattleGrounds;
using Game.BattleGrounds.Zones;
using Game.Entities;
using Game.Scripting;
namespace Scripts.World
{
struct AchievementConst
{
//Tilted
public const uint AreaArgentTournamentFields = 4658;
public const uint AreaRingOfAspirants = 4670;
public const uint AreaRingOfArgentValiants = 4671;
public const uint AreaRingOfAllianceValiants = 4672;
public const uint AreaRingOfHordeValiants = 4673;
public const uint AreaRingOfChampions = 4669;
//Flirt With Disaster
public const uint AuraPerfumeForever = 70235;
public const uint AuraPerfumeEnchantress = 70234;
public const uint AuraPerfumeVictory = 70233;
}
[Script]
class achievement_resilient_victory : AchievementCriteriaScript
{
public achievement_resilient_victory() : base("achievement_resilient_victory") { }
public override bool OnCheck(Player source, Unit target)
{
Battleground bg = source.GetBattleground();
if (bg)
return bg.CheckAchievementCriteriaMeet((uint)BattlegroundCriteriaId.ResilientVictory, source, target);
return false;
}
}
[Script]
class achievement_bg_control_all_nodes : AchievementCriteriaScript
{
public achievement_bg_control_all_nodes() : base("achievement_bg_control_all_nodes") { }
public override bool OnCheck(Player source, Unit target)
{
Battleground bg = source.GetBattleground();
if (bg)
return bg.IsAllNodesControlledByTeam(source.GetTeam());
return false;
}
}
[Script]
class achievement_save_the_day : AchievementCriteriaScript
{
public achievement_save_the_day() : base("achievement_save_the_day") { }
public override bool OnCheck(Player source, Unit target)
{
Battleground bg = source.GetBattleground();
if (bg)
return bg.CheckAchievementCriteriaMeet((uint)BattlegroundCriteriaId.SaveTheDay, source, target);
return false;
}
}
[Script]
class achievement_bg_ic_resource_glut : AchievementCriteriaScript
{
public achievement_bg_ic_resource_glut() : base("achievement_bg_ic_resource_glut") { }
public override bool OnCheck(Player source, Unit target)
{
if (source.HasAura(ICSpells.OilRefinery) && source.HasAura(ICSpells.Quarry))
return true;
return false;
}
}
[Script]
class achievement_bg_ic_glaive_grave : AchievementCriteriaScript
{
public achievement_bg_ic_glaive_grave() : base("achievement_bg_ic_glaive_grave") { }
public override bool OnCheck(Player source, Unit target)
{
Creature vehicle = source.GetVehicleCreatureBase();
if (vehicle)
{
if (vehicle.GetEntry() == ICCreatures.GlaiveThrowerH || vehicle.GetEntry() == ICCreatures.GlaiveThrowerA)
return true;
}
return false;
}
}
[Script]
class achievement_bg_ic_mowed_down : AchievementCriteriaScript
{
public achievement_bg_ic_mowed_down() : base("achievement_bg_ic_mowed_down") { }
public override bool OnCheck(Player source, Unit target)
{
Creature vehicle = source.GetVehicleCreatureBase();
if (vehicle)
{
if (vehicle.GetEntry() == ICCreatures.KeepCannon)
return true;
}
return false;
}
}
[Script]
class achievement_bg_sa_artillery : AchievementCriteriaScript
{
public achievement_bg_sa_artillery() : base("achievement_bg_sa_artillery") { }
public override bool OnCheck(Player source, Unit target)
{
Creature vehicle = source.GetVehicleCreatureBase();
if (vehicle)
{
if (vehicle.GetEntry() == SACreatureIds.AntiPersonnalCannon)
return true;
}
return false;
}
}
[Script("achievement_arena_2v2_kills", ArenaTypes.Team2v2)]
[Script("achievement_arena_3v3_kills", ArenaTypes.Team3v3)]
[Script("achievement_arena_5v5_kills", ArenaTypes.Team5v5)]
class achievement_arena_kills : AchievementCriteriaScript
{
public achievement_arena_kills(string name, ArenaTypes arenaType) : base(name)
{
_arenaType = arenaType;
}
public override bool OnCheck(Player source, Unit target)
{
// this checks GetBattleground() for NULL already
if (!source.InArena())
return false;
return source.GetBattleground().GetArenaType() == _arenaType;
}
ArenaTypes _arenaType;
}
[Script]
class achievement_sickly_gazelle : AchievementCriteriaScript
{
public achievement_sickly_gazelle() : base("achievement_sickly_gazelle") { }
public override bool OnCheck(Player source, Unit target)
{
if (!target)
return false;
Player victim = target.ToPlayer();
if (victim)
if (victim.IsMounted())
return true;
return false;
}
}
[Script]
class achievement_everything_counts : AchievementCriteriaScript
{
public achievement_everything_counts() : base("achievement_everything_counts") { }
public override bool OnCheck(Player source, Unit target)
{
Battleground bg = source.GetBattleground();
if (bg)
return bg.CheckAchievementCriteriaMeet((uint)BattlegroundCriteriaId.EverythingCounts, source, target);
return false;
}
}
[Script]
class achievement_bg_av_perfection : AchievementCriteriaScript
{
public achievement_bg_av_perfection() : base("achievement_bg_av_perfection") { }
public override bool OnCheck(Player source, Unit target)
{
Battleground bg = source.GetBattleground();
if (bg)
return bg.CheckAchievementCriteriaMeet((uint)BattlegroundCriteriaId.AvPerfection, source, target);
return false;
}
}
[Script]
class achievement_bg_sa_defense_of_ancients : AchievementCriteriaScript
{
public achievement_bg_sa_defense_of_ancients() : base("achievement_bg_sa_defense_of_ancients") { }
public override bool OnCheck(Player source, Unit target)
{
Battleground bg = source.GetBattleground();
if (bg)
return bg.CheckAchievementCriteriaMeet((uint)BattlegroundCriteriaId.DefenseOfTheAncients, source, target);
return false;
}
}
[Script]
class achievement_tilted : AchievementCriteriaScript
{
public achievement_tilted() : base("achievement_tilted") { }
public override bool OnCheck(Player player, Unit target)
{
if (!player)
return false;
bool checkArea = player.GetAreaId() == AchievementConst.AreaArgentTournamentFields ||
player.GetAreaId() == AchievementConst.AreaRingOfAspirants ||
player.GetAreaId() == AchievementConst.AreaRingOfArgentValiants ||
player.GetAreaId() == AchievementConst.AreaRingOfAllianceValiants ||
player.GetAreaId() == AchievementConst.AreaRingOfHordeValiants ||
player.GetAreaId() == AchievementConst.AreaRingOfChampions;
return checkArea && player.duel != null && player.duel.isMounted;
}
}
[Script]
class achievement_not_even_a_scratch : AchievementCriteriaScript
{
public achievement_not_even_a_scratch() : base("achievement_not_even_a_scratch") { }
public override bool OnCheck(Player source, Unit target)
{
Battleground bg = source.GetBattleground();
if (bg)
return bg.CheckAchievementCriteriaMeet((uint)BattlegroundCriteriaId.NotEvenAScratch, source, target);
return false;
}
}
[Script]
class achievement_flirt_with_disaster_perf_check : AchievementCriteriaScript
{
public achievement_flirt_with_disaster_perf_check() : base("achievement_flirt_with_disaster_perf_check") { }
public override bool OnCheck(Player player, Unit target)
{
if (!player)
return false;
if (player.HasAura(AchievementConst.AuraPerfumeForever) || player.HasAura(AchievementConst.AuraPerfumeEnchantress) || player.HasAura(AchievementConst.AuraPerfumeVictory))
return true;
return false;
}
}
[Script]
class achievement_killed_exp_or_honor_target : AchievementCriteriaScript
{
public achievement_killed_exp_or_honor_target() : base("achievement_killed_exp_or_honor_target") { }
public override bool OnCheck(Player player, Unit target)
{
return target && player.isHonorOrXPTarget(target);
}
}
}
+398
View File
@@ -0,0 +1,398 @@
/*
* 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.DataStorage;
using Game.Entities;
using Game.Scripting;
using System.Collections.Generic;
namespace Scripts.World
{
struct AreaTriggerConst
{
//Coilfang Waterfall
public const uint GoCoilfangWaterfall = 184212;
//Legion Teleporter
public const uint SpellTeleATo = 37387;
public const uint QuestGainingAccessA = 10589;
public const uint SpellTeleHTo = 37389;
public const uint QuestGainingAccessH = 10604;
//Stormwright Shelf
public const uint QuestStrengthOfTheTempest = 12741;
public const uint SpellCreateTruePowerOfTheTempest = 53067;
//Scent Larkorwi
public const uint QuestScentOfLarkorwi = 4291;
public const uint NpcLarkorwiMate = 9683;
//Last Rites
public const uint QuestLastRites = 12019;
public const uint QuestBreakingThrough = 11898;
//Sholazar Waygate
public const uint SpellSholazarToUngoroTeleport = 52056;
public const uint SpellUngoroToSholazarTeleport = 52057;
public const uint AtSholazar = 5046;
public const uint AtUngoro = 5047;
public const uint QuestTheMakersOverlook = 12613;
public const uint QuestTheMakersPerch = 12559;
public const uint QuestMeetingAGreatOne = 13956;
//Nats Landing
public const uint QuestNatsBargain = 11209;
public const uint SpellFishPaste = 42644;
public const uint NpcLurkingShark = 23928;
//Brewfest
public const uint NpcTapperSwindlekeg = 24711;
public const uint NpcIpfelkoferIronkeg = 24710;
public const uint AtBrewfestDurotar = 4829;
public const uint AtBrewfestDunMorogh = 4820;
public const uint SayWelcome = 4;
public const uint AreatriggerTalkCooldown = 5; // In Seconds
//Area 52
public const uint SpellA52Neuralyzer = 34400;
public const uint NpcSpotlight = 19913;
public const uint SummonCooldown = 5;
public const uint AtArea52South = 4472;
public const uint AtArea52North = 4466;
public const uint AtArea52West = 4471;
public const uint AtArea52East = 4422;
//Frostgrips Hollow
public const uint QuestTheLonesomeWatcher = 12877;
public const uint NpcStormforgedMonitor = 29862;
public const uint NpcStormforgedEradictor = 29861;
public const uint TypeWaypoint = 0;
public const uint DataStart = 0;
public static Position StormforgedMonitorPosition = new Position(6963.95f, 45.65f, 818.71f, 4.948f);
public static Position StormforgedEradictorPosition = new Position(6983.18f, 7.15f, 806.33f, 2.228f);
}
[Script]
class AreaTrigger_at_coilfang_waterfall : AreaTriggerScript
{
public AreaTrigger_at_coilfang_waterfall() : base("at_coilfang_waterfall") { }
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
GameObject go = player.FindNearestGameObject(AreaTriggerConst.GoCoilfangWaterfall, 35.0f);
if (go)
if (go.getLootState() == LootState.Ready)
go.UseDoorOrButton();
return false;
}
}
[Script]
class AreaTrigger_at_legion_teleporter : AreaTriggerScript
{
public AreaTrigger_at_legion_teleporter() : base("at_legion_teleporter") { }
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
if (player.IsAlive() && !player.IsInCombat())
{
if (player.GetTeam() == Team.Alliance && player.GetQuestRewardStatus(AreaTriggerConst.QuestGainingAccessA))
{
player.CastSpell(player, AreaTriggerConst.SpellTeleATo, false);
return true;
}
if (player.GetTeam() == Team.Horde && player.GetQuestRewardStatus(AreaTriggerConst.QuestGainingAccessH))
{
player.CastSpell(player, AreaTriggerConst.SpellTeleHTo, false);
return true;
}
return false;
}
return false;
}
}
[Script]
class AreaTrigger_at_stormwright_shelf : AreaTriggerScript
{
public AreaTrigger_at_stormwright_shelf() : base("at_stormwright_shelf") { }
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
if (!player.IsDead() && player.GetQuestStatus(AreaTriggerConst.QuestStrengthOfTheTempest) == QuestStatus.Incomplete)
player.CastSpell(player, AreaTriggerConst.SpellCreateTruePowerOfTheTempest, false);
return true;
}
}
[Script]
class AreaTrigger_at_scent_larkorwi : AreaTriggerScript
{
public AreaTrigger_at_scent_larkorwi() : base("at_scent_larkorwi") { }
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
if (!player.IsDead() && player.GetQuestStatus(AreaTriggerConst.QuestScentOfLarkorwi) == QuestStatus.Incomplete)
{
if (!player.FindNearestCreature(AreaTriggerConst.NpcLarkorwiMate, 15))
player.SummonCreature(AreaTriggerConst.NpcLarkorwiMate, player.GetPositionX() + 5, player.GetPositionY(), player.GetPositionZ(), 3.3f, TempSummonType.TimedDespawnOOC, 100000);
}
return false;
}
}
[Script]
class AreaTrigger_at_last_rites : AreaTriggerScript
{
public AreaTrigger_at_last_rites() : base("at_last_rites") { }
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
if (!(player.GetQuestStatus(AreaTriggerConst.QuestLastRites) == QuestStatus.Incomplete ||
player.GetQuestStatus(AreaTriggerConst.QuestLastRites) == QuestStatus.Complete ||
player.GetQuestStatus(AreaTriggerConst.QuestBreakingThrough) == QuestStatus.Incomplete ||
player.GetQuestStatus(AreaTriggerConst.QuestBreakingThrough) == QuestStatus.Complete))
return false;
WorldLocation pPosition;
switch (trigger.Id)
{
case 5332:
case 5338:
pPosition = new WorldLocation(571, 3733.68f, 3563.25f, 290.812f, 3.665192f);
break;
case 5334:
pPosition = new WorldLocation(571, 3802.38f, 3585.95f, 49.5765f, 0.0f);
break;
case 5340:
if (player.GetQuestStatus(AreaTriggerConst.QuestLastRites) == QuestStatus.Incomplete ||
player.GetQuestStatus(AreaTriggerConst.QuestLastRites) == QuestStatus.Complete)
pPosition = new WorldLocation(571, 3687.91f, 3577.28f, 473.342f);
else
pPosition = new WorldLocation(571, 3739.38f, 3567.09f, 341.58f);
break;
default:
return false;
}
player.TeleportTo(pPosition);
return false;
}
}
[Script]
class AreaTrigger_at_sholazar_waygate : AreaTriggerScript
{
public AreaTrigger_at_sholazar_waygate() : base("at_sholazar_waygate") { }
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
if (!player.IsDead() && (player.GetQuestStatus(AreaTriggerConst.QuestMeetingAGreatOne) != QuestStatus.None ||
(player.GetQuestStatus(AreaTriggerConst.QuestTheMakersOverlook) == QuestStatus.Rewarded && player.GetQuestStatus(AreaTriggerConst.QuestTheMakersPerch) == QuestStatus.Rewarded)))
{
switch (trigger.Id)
{
case AreaTriggerConst.AtSholazar:
player.CastSpell(player, AreaTriggerConst.SpellSholazarToUngoroTeleport, true);
break;
case AreaTriggerConst.AtUngoro:
player.CastSpell(player, AreaTriggerConst.SpellUngoroToSholazarTeleport, true);
break;
}
}
return false;
}
}
[Script]
class AreaTrigger_at_nats_landing : AreaTriggerScript
{
public AreaTrigger_at_nats_landing() : base("at_nats_landing") { }
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
if (!player.IsAlive() || !player.HasAura(AreaTriggerConst.SpellFishPaste))
return false;
if (player.GetQuestStatus(AreaTriggerConst.QuestNatsBargain) == QuestStatus.Incomplete)
{
if (!player.FindNearestCreature(AreaTriggerConst.NpcLurkingShark, 20.0f))
{
Creature shark = player.SummonCreature(AreaTriggerConst.NpcLurkingShark, -4246.243f, -3922.356f, -7.488f, 5.0f, TempSummonType.TimedDespawnOOC, 100000);
if (shark)
shark.GetAI().AttackStart(player);
return false;
}
}
return true;
}
}
[Script]
class AreaTrigger_at_brewfest : AreaTriggerScript
{
public AreaTrigger_at_brewfest() : base("at_brewfest")
{
// Initialize for cooldown
_triggerTimes[AreaTriggerConst.AtBrewfestDurotar] = _triggerTimes[AreaTriggerConst.AtBrewfestDunMorogh] = 0;
}
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
uint triggerId = trigger.Id;
// Second trigger happened too early after first, skip for now
if (Global.WorldMgr.GetGameTime() - _triggerTimes[triggerId] < AreaTriggerConst.AreatriggerTalkCooldown)
return false;
switch (triggerId)
{
case AreaTriggerConst.AtBrewfestDurotar:
Creature tapper = player.FindNearestCreature(AreaTriggerConst.NpcTapperSwindlekeg, 20.0f);
if (tapper)
tapper.GetAI().Talk(AreaTriggerConst.SayWelcome, player);
break;
case AreaTriggerConst.AtBrewfestDunMorogh:
Creature ipfelkofer = player.FindNearestCreature(AreaTriggerConst.NpcIpfelkoferIronkeg, 20.0f);
if (ipfelkofer)
ipfelkofer.GetAI().Talk(AreaTriggerConst.SayWelcome, player);
break;
default:
break;
}
_triggerTimes[triggerId] = Global.WorldMgr.GetGameTime();
return false;
}
Dictionary<uint, long> _triggerTimes = new Dictionary<uint, long>();
}
[Script]
class AreaTrigger_at_area_52_entrance : AreaTriggerScript
{
public AreaTrigger_at_area_52_entrance() : base("at_area_52_entrance")
{
_triggerTimes[AreaTriggerConst.AtArea52South] = _triggerTimes[AreaTriggerConst.AtArea52North] = _triggerTimes[AreaTriggerConst.AtArea52West] = _triggerTimes[AreaTriggerConst.AtArea52East] = 0;
}
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
float x = 0.0f, y = 0.0f, z = 0.0f;
if (!player.IsAlive())
return false;
uint triggerId = trigger.Id;
if (Global.WorldMgr.GetGameTime() - _triggerTimes[trigger.Id] < AreaTriggerConst.SummonCooldown)
return false;
switch (triggerId)
{
case AreaTriggerConst.AtArea52East:
x = 3044.176f;
y = 3610.692f;
z = 143.61f;
break;
case AreaTriggerConst.AtArea52North:
x = 3114.87f;
y = 3687.619f;
z = 143.62f;
break;
case AreaTriggerConst.AtArea52West:
x = 3017.79f;
y = 3746.806f;
z = 144.27f;
break;
case AreaTriggerConst.AtArea52South:
x = 2950.63f;
y = 3719.905f;
z = 143.33f;
break;
}
player.SummonCreature(AreaTriggerConst.NpcSpotlight, x, y, z, 0.0f, TempSummonType.TimedDespawn, 5000);
player.AddAura(AreaTriggerConst.SpellA52Neuralyzer, player);
_triggerTimes[trigger.Id] = Global.WorldMgr.GetGameTime();
return false;
}
Dictionary<uint, long> _triggerTimes = new Dictionary<uint, long>();
}
[Script]
class AreaTrigger_at_frostgrips_hollow : AreaTriggerScript
{
public AreaTrigger_at_frostgrips_hollow() : base("at_frostgrips_hollow") { }
public override bool OnTrigger(Player player, AreaTriggerRecord trigger, bool entered)
{
if (player.GetQuestStatus(AreaTriggerConst.QuestTheLonesomeWatcher) != QuestStatus.Incomplete)
return false;
Creature stormforgedMonitor = ObjectAccessor.GetCreature(player, stormforgedMonitorGUID);
if (stormforgedMonitor)
return false;
Creature stormforgedEradictor = ObjectAccessor.GetCreature(player, stormforgedEradictorGUID);
if (stormforgedEradictor)
return false;
stormforgedMonitor = player.SummonCreature(AreaTriggerConst.NpcStormforgedMonitor, AreaTriggerConst.StormforgedMonitorPosition, TempSummonType.TimedDespawnOOC, 60000);
if (stormforgedMonitor)
{
stormforgedMonitorGUID = stormforgedMonitor.GetGUID();
stormforgedMonitor.SetWalk(false);
// The npc would search an alternative way to get to the last waypoint without this unit state.
stormforgedMonitor.AddUnitState(UnitState.IgnorePathfinding);
stormforgedMonitor.GetMotionMaster().MovePath(AreaTriggerConst.NpcStormforgedMonitor * 100, false);
}
stormforgedEradictor = player.SummonCreature(AreaTriggerConst.NpcStormforgedEradictor, AreaTriggerConst.StormforgedEradictorPosition, TempSummonType.TimedDespawnOOC, 60000);
if (stormforgedEradictor)
{
stormforgedEradictorGUID = stormforgedEradictor.GetGUID();
stormforgedEradictor.GetMotionMaster().MovePath(AreaTriggerConst.NpcStormforgedEradictor * 100, false);
}
return true;
}
ObjectGuid stormforgedMonitorGUID;
ObjectGuid stormforgedEradictorGUID;
}
}
+621
View File
@@ -0,0 +1,621 @@
/*
* 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.World.BossEmeraldDragons
{
struct CreatureIds
{
public const uint DragonYsondre = 14887;
public const uint DragonLethon = 14888;
public const uint DragonEmeriss = 14889;
public const uint DragonTaerar = 14890;
public const uint DreamFog = 15224;
//Ysondre
public const uint DementedDruid = 15260;
//Lethon
public const uint SpiritShade = 15261;
}
struct Spells
{
public const uint TailSweep = 15847; // Tail Sweep - Slap Everything Behind Dragon (2 Seconds Interval)
public const uint SummonPlayer = 24776; // Teleport Highest Threat Player In Front Of Dragon If Wandering Off
public const uint DreamFog = 24777; // Auraspell For Dream Fog Npc (15224)
public const uint Sleep = 24778; // Sleep Triggerspell (Used For Dream Fog)
public const uint SeepingFogLeft = 24813; // Dream Fog - Summon Left
public const uint SeepingFogRight = 24814; // Dream Fog - Summon Right
public const uint NoxiousBreath = 24818;
public const uint MarkOfNature = 25040; // Mark Of Nature Trigger (Applied On Target Death - 15 Minutes Of Being Suspectible To Aura Of Nature)
public const uint MarkOfNatureAura = 25041; // Mark Of Nature (Passive Marker-Test; Ticks Every 10 Seconds From Boss; Triggers Spellid 25042 (Scripted)
public const uint AuraOfNature = 25043; // Stun For 2 Minutes (Used When public const uint MarkOfNature Exists On The Target)
//Ysondre
public const uint LightningWave = 24819;
public const uint SummonDruidSpirits = 24795;
//Lethon
public const uint DrawSpirit = 24811;
public const uint ShadowBoltWhirl = 24834;
public const uint DarkOffering = 24804;
//Emeriss
public const uint PutridMushroom = 24904;
public const uint CorruptionOfEarth = 24910;
public const uint VolatileInfection = 24928;
//Taerar
public const uint BellowingRoar = 22686;
public const uint Shade = 24313;
public const uint ArcaneBlast = 24857;
public static uint[] TaerarShadeSpells = { 24841, 24842, 24843 };
}
struct Texts
{
//Ysondre
public const uint YsondreAggro = 0;
public const uint YsondreSummonDruids = 1;
//Lethon
public const uint LethonAggro = 0;
public const uint LethonDrawSpirit = 1;
//Emeriss
public const uint EmerissAggro = 0;
public const uint EmerissCastCorruption = 1;
//Taerar
public const uint TaerarAggro = 0;
public const uint TaerarSummonShades = 1;
}
class emerald_dragonAI : WorldBossAI
{
public emerald_dragonAI(Creature creature) : base(creature) { }
public override void Reset()
{
base.Reset();
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.SetReactState(ReactStates.Aggressive);
DoCast(me, Spells.MarkOfNatureAura, true);
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
{
// Tail Sweep is cast every two seconds, no matter what goes on in front of the dragon
DoCast(me, Spells.TailSweep);
task.Repeat(TimeSpan.FromSeconds(2));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7.5), TimeSpan.FromSeconds(15), task =>
{
// Noxious Breath is cast on random intervals, no less than 7.5 seconds between
DoCast(me, Spells.NoxiousBreath);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(12.5), TimeSpan.FromSeconds(20), task =>
{
// Seeping Fog appears only as "pairs", and only ONE pair at any given time!
// Despawntime is 2 minutes, so reschedule it for new cast after 2 minutes + a minor "random time" (30 seconds at max)
DoCast(me, Spells.SeepingFogLeft, true);
DoCast(me, Spells.SeepingFogRight, true);
task.Repeat(TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(2.5));
});
}
// Target killed during encounter, mark them as suspectible for Aura Of Nature
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
who.CastSpell(who, Spells.MarkOfNature, true);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (me.HasUnitState(UnitState.Casting))
return;
_scheduler.Update(diff);
Unit target = SelectTarget(SelectAggroTarget.TopAggro, 0, -50.0f, true);
if (target)
DoCast(target, Spells.SummonPlayer);
DoMeleeAttackIfReady();
}
}
[Script]
class npc_dream_fog : CreatureScript
{
public npc_dream_fog() : base("npc_dream_fog") { }
class npc_dream_fogAI : ScriptedAI
{
public npc_dream_fogAI(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_roamTimer = 0;
}
public override void Reset()
{
Initialize();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (_roamTimer == 0)
{
// Chase target, but don't attack - otherwise just roam around
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (target)
{
_roamTimer = RandomHelper.URand(15000, 30000);
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveChase(target, 0.2f);
}
else
{
_roamTimer = 2500;
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveRandom(25.0f);
}
// Seeping fog movement is slow enough for a player to be able to walk backwards and still outpace it
me.SetWalk(true);
me.SetSpeedRate(UnitMoveType.Walk, 0.75f);
}
else
_roamTimer -= diff;
}
uint _roamTimer;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_dream_fogAI(creature);
}
}
[Script]
class boss_ysondre : CreatureScript
{
public boss_ysondre() : base("boss_ysondre") { }
class boss_ysondreAI : emerald_dragonAI
{
public boss_ysondreAI(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
}
public override void Reset()
{
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(Spells.LightningWave);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20));
});
}
public override void EnterCombat(Unit who)
{
Talk(Texts.YsondreAggro);
base.EnterCombat(who);
}
// Summon druid spirits on 75%, 50% and 25% health
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(100 - 25 * _stage))
{
Talk(Texts.YsondreSummonDruids);
for (byte i = 0; i < 10; ++i)
DoCast(me, Spells.SummonDruidSpirits, true);
++_stage;
}
}
byte _stage;
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_ysondreAI(creature);
}
}
[Script]
class boss_lethon : CreatureScript
{
public boss_lethon() : base("boss_lethon") { }
class boss_lethonAI : emerald_dragonAI
{
public boss_lethonAI(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
}
public override void Reset()
{
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
{
me.CastSpell((Unit)null, Spells.ShadowBoltWhirl, false);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30));
});
}
public override void EnterCombat(Unit who)
{
Talk(Texts.LethonAggro);
base.EnterCombat(who);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(100 - 25 * _stage))
{
Talk(Texts.LethonDrawSpirit);
DoCast(me, Spells.DrawSpirit);
++_stage;
}
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == Spells.DrawSpirit && target.IsTypeId(TypeId.Player))
{
Position targetPos = target.GetPosition();
me.SummonCreature(CreatureIds.SpiritShade, targetPos, TempSummonType.TimedDespawnOOC, 50000);
}
}
byte _stage;
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_lethonAI(creature);
}
}
[Script]
class npc_spirit_shade : CreatureScript
{
public npc_spirit_shade() : base("npc_spirit_shade") { }
class npc_spirit_shadeAI : PassiveAI
{
public npc_spirit_shadeAI(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit summoner)
{
_summonerGuid = summoner.GetGUID();
me.GetMotionMaster().MoveFollow(summoner, 0.0f, 0.0f);
}
public override void MovementInform(MovementGeneratorType moveType, uint data)
{
if (moveType == MovementGeneratorType.Follow && data == _summonerGuid.GetCounter())
{
me.CastSpell((Unit)null, Spells.DarkOffering, false);
me.DespawnOrUnsummon(1000);
}
}
ObjectGuid _summonerGuid;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_spirit_shadeAI(creature);
}
}
[Script]
class boss_emeriss : CreatureScript
{
public boss_emeriss() : base("boss_emeriss") { }
class boss_emerissAI : emerald_dragonAI
{
public boss_emerissAI(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
}
public override void Reset()
{
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(Spells.VolatileInfection);
task.Repeat(TimeSpan.FromSeconds(120));
});
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
DoCast(who, Spells.PutridMushroom, true);
base.KilledUnit(who);
}
public override void EnterCombat(Unit who)
{
Talk(Texts.EmerissAggro);
base.EnterCombat(who);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(100 - 25 * _stage))
{
Talk(Texts.EmerissCastCorruption);
DoCast(me, Spells.CorruptionOfEarth, true);
++_stage;
}
}
byte _stage;
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_emerissAI(creature);
}
}
[Script]
class boss_taerar : CreatureScript
{
public boss_taerar() : base("boss_taerar") { }
class boss_taerarAI : emerald_dragonAI
{
public boss_taerarAI(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
_shades = 0;
_banished = false;
_banishedTimer = 0;
}
public override void Reset()
{
me.RemoveAurasDueToSpell(Spells.Shade);
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCast(Spells.ArcaneBlast);
task.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(12));
});
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
{
DoCast(Spells.BellowingRoar);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(30));
});
}
public override void EnterCombat(Unit who)
{
Talk(Texts.TaerarAggro);
base.EnterCombat(who);
}
public override void SummonedCreatureDies(Creature summon, Unit killer)
{
--_shades;
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
// At 75, 50 or 25 percent health, we need to activate the shades and go "banished"
// Note: _stage holds the amount of times they have been summoned
if (!_banished && !HealthAbovePct(100 - 25 * _stage))
{
_banished = true;
_banishedTimer = 60000;
me.InterruptNonMeleeSpells(false);
DoStopAttack();
Talk(Texts.TaerarSummonShades);
foreach (var spell in Spells.TaerarShadeSpells)
DoCastVictim(spell, true);
_shades += (byte)Spells.TaerarShadeSpells.Length;
DoCast(Spells.Shade);
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.SetReactState(ReactStates.Passive);
++_stage;
}
}
public override void UpdateAI(uint diff)
{
if (!me.IsInCombat())
return;
if (_banished)
{
// If all three shades are dead, OR it has taken too long, end the current event and get Taerar back into business
if (_banishedTimer <= diff || _shades == 0)
{
_banished = false;
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.RemoveAurasDueToSpell(Spells.Shade);
me.SetReactState(ReactStates.Aggressive);
}
// _banishtimer has not expired, and we still have active shades:
else
_banishedTimer -= diff;
// Update the scheduler before we return (handled under emerald_dragonAI.UpdateAI(diff); if we're not inside this check)
_scheduler.Update(diff);
return;
}
base.UpdateAI(diff);
}
bool _banished; // used for shades activation testing
uint _banishedTimer; // counter for banishment timeout
byte _shades; // keep track of how many shades are dead
byte _stage; // check which "shade phase" we're at (75-50-25 percentage counters)
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_taerarAI(creature);
}
}
[Script]
class spell_dream_fog_sleep : SpellScriptLoader
{
public spell_dream_fog_sleep() : base("spell_dream_fog_sleep") { }
class spell_dream_fog_sleep_SpellScript : SpellScript
{
void FilterTargets(List<WorldObject> targets)
{
targets.RemoveAll(obj =>
{
Unit unit = obj.ToUnit();
if (unit)
return unit.HasAura(Spells.Sleep);
return true;
});
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaEnemy));
}
}
public override SpellScript GetSpellScript()
{
return new spell_dream_fog_sleep_SpellScript();
}
}
[Script]
class spell_mark_of_nature : SpellScriptLoader
{
public spell_mark_of_nature() : base("spell_mark_of_nature") { }
class spell_mark_of_nature_SpellScript : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(Spells.MarkOfNature, Spells.AuraOfNature);
}
void FilterTargets(List<WorldObject> targets)
{
targets.RemoveAll(obj =>
{
// return those not tagged or already under the influence of Aura of Nature
Unit unit = obj.ToUnit();
if (unit)
return !(unit.HasAura(Spells.MarkOfNature) && !unit.HasAura(Spells.AuraOfNature));
return true;
});
}
void HandleEffect(uint effIndex)
{
PreventHitDefaultEffect(effIndex);
GetHitUnit().CastSpell(GetHitUnit(), Spells.AuraOfNature, true);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEnemy));
OnEffectHitTarget.Add(new EffectHandler(HandleEffect, 0, SpellEffectName.ApplyAura));
}
}
public override SpellScript GetSpellScript()
{
return new spell_mark_of_nature_SpellScript();
}
}
}

Some files were not shown because too many files have changed in this diff Show More