initial commit
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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!)
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
{
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")]
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user