diff --git a/Source/Framework/Constants/SharedConst.cs b/Source/Framework/Constants/SharedConst.cs index 3d9199906..5739b272e 100644 --- a/Source/Framework/Constants/SharedConst.cs +++ b/Source/Framework/Constants/SharedConst.cs @@ -562,6 +562,54 @@ namespace Framework.Constants Min = Hated } + public enum FactionTemplates + { + None = 0, + Creature = 7, + EscorteeANeutralPassive = 10, + Monster = 14, + Monster2 = 16, + TrollBloodscalp = 28, + Prey = 31, + EscorteeHNeutralPassive = 33, + Friendly = 35, + TrollFrostmane = 37, + Ogre = 45, + OrcDragonmaw = 62, + HordeGeneric = 83, + AllianceGeneric = 84, + Demon = 90, + Elemental = 91, + DragonflightBlack = 103, + EscorteeNNeutralPassive = 113, + Enemy = 168, + EscorteeANeutralActive = 231, + EscorteeHNeutralActive = 232, + EscorteeNNeutralActive = 250, + EscorteeNFriendPassive = 290, + Titan = 415, + EscorteeNFriendActive = 495, + Ratchet = 637, + GoblinDarkIronBarPatron = 736, + DarkIronDwarves = 754, + EscorteeAPassive = 774, + EscorteeHPassive = 775, + UndeadScourge = 974, + EarthenRing = 1726, + AllianceGenericWg = 1732, + HordeGenericWg = 1735, + Arakkoa = 1738, + AshtongueDeathsworn = 1820, + FlayerHunter = 1840, + MonsterSparBuddy = 1868, + EscorteeNActive = 1986, + EscorteeHActive = 2046, + UndeadScourge2 = 2068, + UndeadScourge3 = 2084, + ScarletCrusade = 2089, + ScarletCrusade2 = 2096 + }; + public enum ReputationSource { Kill, diff --git a/Source/Game/AI/ScriptedAI/ScriptedAI.cs b/Source/Game/AI/ScriptedAI/ScriptedAI.cs index e70191a9a..15cf65a32 100644 --- a/Source/Game/AI/ScriptedAI/ScriptedAI.cs +++ b/Source/Game/AI/ScriptedAI/ScriptedAI.cs @@ -585,9 +585,8 @@ namespace Game.AI void ForceCombatStopForCreatureEntry(uint entry, float maxSearchRange = 250.0f, bool reset = true) { Log.outDebug(LogFilter.ScriptsAi, $"BossAI::ForceStopCombatForCreature: called on {me.GetGUID()}. Debug info: {me.GetDebugInfo()}"); - List creatures = new(); - me.GetCreatureListWithEntryInGrid(creatures, entry, maxSearchRange); + List creatures = me.GetCreatureListWithEntryInGrid(entry, maxSearchRange); foreach (Creature creature in creatures) { creature.CombatStop(true); diff --git a/Source/Game/AI/SmartScripts/SmartScript.cs b/Source/Game/AI/SmartScripts/SmartScript.cs index 052d30c7e..f959a8c3a 100644 --- a/Source/Game/AI/SmartScripts/SmartScript.cs +++ b/Source/Game/AI/SmartScripts/SmartScript.cs @@ -3553,8 +3553,7 @@ namespace Game.AI } else if (e.Event.distance.entry != 0) { - List list = new(); - _me.GetCreatureListWithEntryInGrid(list, e.Event.distance.entry, e.Event.distance.dist); + List list = _me.GetCreatureListWithEntryInGrid(e.Event.distance.entry, e.Event.distance.dist); if (!list.Empty()) creature = list.FirstOrDefault(); @@ -3584,8 +3583,7 @@ namespace Game.AI } else if (e.Event.distance.entry != 0) { - List list = new(); - _me.GetGameObjectListWithEntryInGrid(list, e.Event.distance.entry, e.Event.distance.dist); + List list = _me.GetGameObjectListWithEntryInGrid(e.Event.distance.entry, e.Event.distance.dist); if (!list.Empty()) gameobject = list.FirstOrDefault(); diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 9bccded1c..f8d5f64c5 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -2784,20 +2784,24 @@ namespace Game.Entities return spellInfo.GetSpellXSpellVisualId(this); } - public void GetGameObjectListWithEntryInGrid(List gameobjectList, uint entry = 0, float maxSearchRange = 250.0f) + public List GetGameObjectListWithEntryInGrid(uint entry = 0, float maxSearchRange = 250.0f) { + List gameobjectList = new(); var check = new AllGameObjectsWithEntryInRange(this, entry, maxSearchRange); var searcher = new GameObjectListSearcher(this, gameobjectList, check); Cell.VisitGridObjects(this, searcher, maxSearchRange); + return gameobjectList; } - public void GetCreatureListWithEntryInGrid(List creatureList, uint entry = 0, float maxSearchRange = 250.0f) + public List GetCreatureListWithEntryInGrid(uint entry = 0, float maxSearchRange = 250.0f) { + List creatureList = new(); var check = new AllCreaturesOfEntryInRange(this, entry, maxSearchRange); var searcher = new CreatureListSearcher(this, creatureList, check); Cell.VisitGridObjects(this, searcher, maxSearchRange); + return creatureList; } public List GetPlayerListInGrid(float maxSearchRange, bool alive = true) diff --git a/Source/Game/Maps/Instances/InstanceScript.cs b/Source/Game/Maps/Instances/InstanceScript.cs index 9d2c3e873..7bb98ed9a 100644 --- a/Source/Game/Maps/Instances/InstanceScript.cs +++ b/Source/Game/Maps/Instances/InstanceScript.cs @@ -447,11 +447,11 @@ namespace Game.Maps { if (string.IsNullOrEmpty(data)) { - OUT_LOAD_INST_DATA_FAIL(); + OutLoadInstDataFail(); return; } - OUT_LOAD_INST_DATA(data); + OutLoadInstData(data); var loadStream = new StringArguments(data); @@ -461,9 +461,9 @@ namespace Game.Maps ReadSaveDataMore(loadStream); } else - OUT_LOAD_INST_DATA_FAIL(); + OutLoadInstDataFail(); - OUT_LOAD_INST_DATA_COMPLETE(); + OutLoadInstDataComplete(); } bool ReadSaveDataHeaders(StringArguments data) @@ -495,7 +495,7 @@ namespace Game.Maps public virtual string GetSaveData() { - OUT_SAVE_INST_DATA(); + OutSaveInstData(); StringBuilder saveStream = new(); @@ -503,7 +503,7 @@ namespace Game.Maps WriteSaveDataBossStates(saveStream); WriteSaveDataMore(saveStream); - OUT_SAVE_INST_DATA_COMPLETE(); + OutSaveInstDataComplete(); return saveStream.ToString(); } @@ -928,11 +928,11 @@ namespace Game.Maps bosses.Add(i, new BossInfo()); } - public void OUT_SAVE_INST_DATA() { Log.outDebug(LogFilter.Scripts, "Saving Instance Data for Instance {0} (Map {1}, Instance Id {2})", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); } - public void OUT_SAVE_INST_DATA_COMPLETE() { Log.outDebug(LogFilter.Scripts, "Saving Instance Data for Instance {0} (Map {1}, Instance Id {2}) completed.", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); } - public void OUT_LOAD_INST_DATA(string input) { Log.outDebug(LogFilter.Scripts, "Loading Instance Data for Instance {0} (Map {1}, Instance Id {2}). Input is '{3}'", instance.GetMapName(), instance.GetId(), instance.GetInstanceId(), input); } - public void OUT_LOAD_INST_DATA_COMPLETE() { Log.outDebug(LogFilter.Scripts, "Instance Data Load for Instance {0} (Map {1}, Instance Id: {2}) is complete.", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); } - public void OUT_LOAD_INST_DATA_FAIL() { Log.outDebug(LogFilter.Scripts, "Unable to load Instance Data for Instance {0} (Map {1}, Instance Id: {2}).", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); } + public void OutSaveInstData() { Log.outDebug(LogFilter.Scripts, "Saving Instance Data for Instance {0} (Map {1}, Instance Id {2})", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); } + public void OutSaveInstDataComplete() { Log.outDebug(LogFilter.Scripts, "Saving Instance Data for Instance {0} (Map {1}, Instance Id {2}) completed.", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); } + public void OutLoadInstData(string input) { Log.outDebug(LogFilter.Scripts, "Loading Instance Data for Instance {0} (Map {1}, Instance Id {2}). Input is '{3}'", instance.GetMapName(), instance.GetId(), instance.GetInstanceId(), input); } + public void OutLoadInstDataComplete() { Log.outDebug(LogFilter.Scripts, "Instance Data Load for Instance {0} (Map {1}, Instance Id: {2}) is complete.", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); } + public void OutLoadInstDataFail() { Log.outDebug(LogFilter.Scripts, "Unable to load Instance Data for Instance {0} (Map {1}, Instance Id: {2}).", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); } public virtual void ReadSaveDataMore(StringArguments data) { } diff --git a/Source/Game/Spells/Auras/AuraEffect.cs b/Source/Game/Spells/Auras/AuraEffect.cs index e846ed124..ee7fbd680 100644 --- a/Source/Game/Spells/Auras/AuraEffect.cs +++ b/Source/Game/Spells/Auras/AuraEffect.cs @@ -5725,8 +5725,7 @@ namespace Game.Spells // most of the spells have multiple effects with the same summon spell id for multiple spawns, so right now it's safe to assume there's only 1 spawn per effect foreach (uint summonEntry in summonedEntries) { - List nearbyEntries = new(); - target.GetCreatureListWithEntryInGrid(nearbyEntries, summonEntry); + List nearbyEntries = target.GetCreatureListWithEntryInGrid(summonEntry); foreach (var creature in nearbyEntries) { if (creature.GetOwner() == target) diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/AscendantLordObsidius.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/AscendantLordObsidius.cs new file mode 100644 index 000000000..ca7acc6e7 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/AscendantLordObsidius.cs @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using Game.Spells; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockCaverns.AscendantLordObsidius +{ + struct SpellIds + { + public const uint ManaTap = 36021; + public const uint ArcaneTorrent = 36022; + public const uint Domination = 35280; + } + + struct TextIds + { + public const uint YellAggro = 0; + public const uint YellKill = 1; + public const uint YellSwitchingShadows = 2; + public const uint YellDeath = 3; + + public const uint EmoteSwitchingShadows = 4; + } + + [Script] + class boss_ascendant_lord_obsidius : BossAI + { + public boss_ascendant_lord_obsidius(Creature creature) : base(creature, DataTypes.AscendantLordObsidius) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(30), ScheduleTasks => + { + DoCastVictim(SpellIds.ManaTap, new CastSpellExtraArgs(true)); + ScheduleTasks.Repeat(TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(22)); + }); + + Talk(TextIds.YellAggro); + } + + public override void KilledUnit(Unit who) + { + if (who.IsPlayer()) + Talk(TextIds.YellKill); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + Talk(TextIds.YellDeath); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/Beauty.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/Beauty.cs new file mode 100644 index 000000000..81d3c09f9 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/Beauty.cs @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using Game.Spells; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockCaverns.Beauty +{ + struct SpellIds + { + public const uint TerrifyingRoar = 76028; // Not yet Implemented + public const uint BerserkerCharge = 76030; + public const uint MagmaSpit = 76031; + public const uint Flamebreak = 76032; + public const uint Berserk = 82395; // Not yet Implemented + } + + struct SoundIds + { + public const uint Aggro = 18559; + public const uint Death = 18563; + } + + [Script] + class boss_beauty : BossAI + { + public boss_beauty(Creature creature) : base(creature, DataTypes.Beauty) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(10), task => + { + DoCast(SelectTarget(SelectTargetMethod.Random, 0, 100, true), SpellIds.MagmaSpit, new CastSpellExtraArgs(true)); + task.Repeat(); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(19), task => + { + DoCast(SelectTarget(SelectTargetMethod.Random, 0, 100, true), SpellIds.BerserkerCharge, new CastSpellExtraArgs(true)); + task.Repeat(); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(18), TimeSpan.FromSeconds(22), task => + { + DoCast(me, SpellIds.Flamebreak); + task.Repeat(); + }); + + DoPlaySoundToSet(me, SoundIds.Aggro); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + DoPlaySoundToSet(me, SoundIds.Death); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/Corla.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/Corla.cs new file mode 100644 index 000000000..4a200e928 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/Corla.cs @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockCaverns.Corla +{ + struct SpellIds + { + public const uint Evolution = 75610; + public const uint DrainEssense = 75645; + public const uint ShadowPower = 35322; + public const uint HShadowPower = 39193; + } + + struct TextIds + { + public const uint YellAggro = 0; + public const uint YellKill = 1; + public const uint YellEvolvedZealot = 2; + public const uint YellDeath = 3; + + public const uint EmoteEvolvedZealot = 4; + } + + [Script] + class boss_corla : BossAI + { + bool combatPhase; + + public boss_corla(Creature creature) : base(creature, DataTypes.Corla) { } + + public override void Reset() + { + _Reset(); + combatPhase = false; + + _scheduler.SetValidator(() => !combatPhase); + _scheduler.Schedule(TimeSpan.FromSeconds(2), drainTask => + { + DoCast(me, SpellIds.DrainEssense); + drainTask.Schedule(TimeSpan.FromSeconds(15), stopDrainTask => + { + me.InterruptSpell(CurrentSpellTypes.Channeled); + stopDrainTask.Schedule(TimeSpan.FromSeconds(2), evolutionTask => + { + DoCast(me, SpellIds.Evolution); + drainTask.Repeat(TimeSpan.FromSeconds(2)); + }); + }); + }); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + Talk(TextIds.YellAggro); + _scheduler.CancelAll(); + combatPhase = true; + } + + public override void KilledUnit(Unit who) + { + if (who.IsPlayer()) + Talk(TextIds.YellKill); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + Talk(TextIds.YellDeath); + } + + public override void UpdateAI(uint diff) + { + _scheduler.Update(diff); + + DoMeleeAttackIfReady(); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/InstanceBlackrockCaverns.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/InstanceBlackrockCaverns.cs new file mode 100644 index 000000000..cd50e2423 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/InstanceBlackrockCaverns.cs @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.Maps; +using Game.Scripting; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockCaverns +{ + struct DataTypes + { + // Encounter States // Boss GUIDs + public const uint RomoggBonecrusher = 0; + public const uint Corla = 1; + public const uint KarshSteelbender = 2; + public const uint Beauty = 3; + public const uint AscendantLordObsidius = 4; + + // Additional Objects + public const uint RazTheCrazed = 5; + } + + struct CreatureIds + { + public const uint TwilightFlameCaller = 39708; + public const uint RazTheCrazed = 39670; + public const uint RomoggBonecrusher = 39665; + } + + [Script] + class instance_blackrock_caverns : InstanceMapScript + { + static ObjectData[] creatureData = + { + new ObjectData(CreatureIds.RazTheCrazed, DataTypes.RazTheCrazed) + }; + + public instance_blackrock_caverns() : base(nameof(instance_blackrock_caverns), 645) { } + + class instance_blackrock_caverns_InstanceMapScript : InstanceScript + { + public instance_blackrock_caverns_InstanceMapScript(InstanceMap map) : base(map) + { + SetHeaders("BRC"); + SetBossNumber(5); + LoadObjectData(creatureData, null); + } + + public override bool SetBossState(uint type, EncounterState state) + { + if (!base.SetBossState(type, state)) + return false; + + switch (type) + { + case DataTypes.RomoggBonecrusher: + case DataTypes.Corla: + case DataTypes.KarshSteelbender: + case DataTypes.Beauty: + case DataTypes.AscendantLordObsidius: + break; + default: + break; + } + + return true; + } + } + + public override InstanceScript GetInstanceScript(InstanceMap map) + { + return new instance_blackrock_caverns_InstanceMapScript(map); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/KarshSteelbender.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/KarshSteelbender.cs new file mode 100644 index 000000000..165bf214d --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/KarshSteelbender.cs @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockCaverns.KarshSteelbender +{ + struct SpellIds + { + public const uint Cleave = 15284; + public const uint QuicksilverArmor = 75842; + public const uint SuperheatedQuicksilverArmor = 75846; + } + + struct TextIds + { + public const uint YellAggro = 0; + public const uint YellKill = 1; + public const uint YellQuicksilverArmor = 2; + public const uint YellDeath = 3; + + public const uint EmoteQuicksilverArmor = 4; + } + + [Script] + class boss_karsh_steelbender : BossAI + { + public boss_karsh_steelbender(Creature creature) : base(creature, DataTypes.KarshSteelbender) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + Talk(TextIds.YellAggro); + + _scheduler.Schedule(TimeSpan.FromSeconds(10), task => + { + DoCastVictim(SpellIds.Cleave); + task.Repeat(TimeSpan.FromSeconds(10)); + }); + } + + public override void KilledUnit(Unit who) + { + if (who.IsPlayer()) + Talk(TextIds.YellKill); + } + + public override void JustDied(Unit victim) + { + _JustDied(); + Talk(TextIds.YellDeath); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/RomoggBonecrusher.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/RomoggBonecrusher.cs new file mode 100644 index 000000000..73b3eb756 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/RomoggBonecrusher.cs @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using Game.Spells; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockCaverns.RomoggBonecrusher +{ + struct SpellIds + { + public const uint CallForHelp = 82137; // Needs Scripting + public const uint ChainsOfWoe = 75539; + public const uint Quake = 75272; + public const uint Skullcracker = 75543; + public const uint WoundingStrike = 75571; + } + + struct TextIds + { + public const uint YellAggro = 0; + public const uint YellKill = 1; + public const uint YellSkullcracker = 2; + public const uint YellDeath = 3; + + public const uint EmoteCallForHelp = 4; + public const uint EmoteSkullcracker = 5; + } + + struct MiscConst + { + public const uint TypeRaz = 1; + public const uint DataRomoggDead = 1; + public static Position SummonPos = new Position(249.2639f, 949.1614f, 191.7866f, 3.141593f); + } + + [Script] + class boss_romogg_bonecrusher : BossAI + { + public boss_romogg_bonecrusher(Creature creature) : base(creature, DataTypes.RomoggBonecrusher) + { + me.SummonCreature(CreatureIds.RazTheCrazed, MiscConst.SummonPos, TempSummonType.ManualDespawn, TimeSpan.FromSeconds(200)); + } + + public override void Reset() + { + _Reset(); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + Talk(TextIds.YellDeath); + + Creature raz = instance.GetCreature(DataTypes.RazTheCrazed); + if (raz) + raz.GetAI().SetData(MiscConst.TypeRaz, MiscConst.DataRomoggDead); + } + + public override void KilledUnit(Unit who) + { + if (who.IsPlayer()) + Talk(TextIds.YellKill); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(22), TimeSpan.FromSeconds(32), task => + { + Talk(TextIds.YellSkullcracker); + DoCast(me, SpellIds.ChainsOfWoe); + task.Repeat(TimeSpan.FromSeconds(22), TimeSpan.FromSeconds(32)); + _scheduler.Schedule(TimeSpan.FromSeconds(3), skullCrackerTask => + { + Talk(TextIds.EmoteSkullcracker); + DoCast(me, SpellIds.Skullcracker); + }); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(26), TimeSpan.FromSeconds(32), task => + { + DoCastVictim(SpellIds.WoundingStrike, new CastSpellExtraArgs(true)); + task.Repeat(TimeSpan.FromSeconds(26), TimeSpan.FromSeconds(32)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(45), task => + { + DoCast(me, SpellIds.Quake); + task.Repeat(TimeSpan.FromSeconds(32), TimeSpan.FromSeconds(40)); + }); + + Talk(TextIds.YellAggro); + Talk(TextIds.EmoteCallForHelp); + DoCast(me, SpellIds.CallForHelp); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/AmbassadorFlamelash.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/AmbassadorFlamelash.cs new file mode 100644 index 000000000..ab591ae5a --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/AmbassadorFlamelash.cs @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths.AmbassadorFlamelash +{ + struct SpellIds + { + public const uint Fireblast = 15573; + } + + [Script] + class boss_ambassador_flamelash : ScriptedAI + { + public boss_ambassador_flamelash(Creature creature) : base(creature) { } + + public override void Reset() + { + _scheduler.CancelAll(); + } + + public override void JustEngagedWith(Unit who) + { + _scheduler.Schedule(TimeSpan.FromSeconds(2), task => + { + DoCastVictim(SpellIds.Fireblast); + task.Repeat(TimeSpan.FromSeconds(7)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(24), task => + { + for (uint i = 0; i < 4; ++i) + SummonSpirit(me.GetVictim()); + task.Repeat(TimeSpan.FromSeconds(30)); + }); + } + + void SummonSpirit(Unit victim) + { + Creature spirit = DoSpawnCreature(9178, RandomHelper.FRand(-9, 9), RandomHelper.FRand(-9, 9), 0, 0, Framework.Constants.TempSummonType.TimedOrCorpseDespawn, TimeSpan.FromSeconds(60)); + if (spirit) + spirit.GetAI().AttackStart(victim); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/CorenDirebrew.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/CorenDirebrew.cs new file mode 100644 index 000000000..3e93997a7 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/CorenDirebrew.cs @@ -0,0 +1,531 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Groups; +using Game.Maps; +using Game.Scripting; +using Game.Spells; +using System; +using System.Collections.Generic; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths.CorenDirebrew +{ + struct SpellIds + { + public const uint MoleMachineEmerge = 50313; + public const uint DirebrewDisarmPreCast = 47407; + public const uint MoleMachineTargetPicker = 47691; + public const uint MoleMachineMinionSummoner = 47690; + public const uint DirebrewDisarmGrow = 47409; + public const uint DirebrewDisarm = 47310; + public const uint ChuckMug = 50276; + public const uint PortToCoren = 52850; + public const uint SendMugControlAura = 47369; + public const uint SendMugTargetPicker = 47370; + public const uint SendFirstMug = 47333; + public const uint SendSecondMug = 47339; + public const uint RequestSecondMug = 47344; + public const uint HasDarkBrewmaidensBrew = 47331; + public const uint BarreledControlAura = 50278; + public const uint Barreled = 47442; + } + + struct TextIds + { + public const uint SayIntro = 0; + public const uint SayIntro1 = 1; + public const uint SayIntro2 = 2; + public const uint SayInsult = 3; + public const uint SayAntagonist1 = 0; + public const uint SayAntagonist2 = 1; + public const uint SayAntagonistCombat = 2; + } + + struct ActionIds + { + public const int StartFight = -1; + public const int AntagonistSay1 = -2; + public const int AntagonistSay2 = -3; + public const int AntagonistHostile = -4; + } + + struct CreatureIds + { + public const uint IlsaDirebrew = 26764; + public const uint UrsulaDirebrew = 26822; + public const uint Antagonist = 23795; + } + + enum DirebrewPhases + { + All = 1, + Intro, + One, + Two, + Three + } + + struct MiscConst + { + public const uint GossipId = 11388; + public const uint GoMoleMachineTrap = 188509; + public const uint GossipOptionFight = 0; + public const uint GossipOptionApologize = 1; + public const int DataTargetGuid = 1; + public const uint MaxAntagonists = 3; + + public static Position[] AntagonistPos = + { + new Position(895.3782f, -132.1722f, -49.66423f, 2.6529f), + new Position(893.9837f, -133.2879f, -49.66541f, 2.583087f), + new Position(896.2667f, -130.483f, -49.66249f, 2.600541f) + }; + } + + [Script] + class boss_coren_direbrew : BossAI + { + DirebrewPhases phase; + + public boss_coren_direbrew(Creature creature) : base(creature, DataTypes.DataCoren) { } + + public override bool OnGossipSelect(Player player, uint menuId, uint gossipListId) + { + if (menuId != MiscConst.GossipId) + return false; + + if (gossipListId == MiscConst.GossipOptionFight) + { + Talk(TextIds.SayInsult, player); + DoAction(ActionIds.StartFight); + } + else if (gossipListId == MiscConst.GossipOptionApologize) + player.CloseGossipMenu(); + + return false; + } + + public override void Reset() + { + _Reset(); + me.SetImmuneToPC(true); + me.SetFaction((uint)FactionTemplates.Friendly); + phase = DirebrewPhases.All; + _scheduler.CancelAll(); + + for (byte i = 0; i < MiscConst.MaxAntagonists; ++i) + me.SummonCreature(CreatureIds.Antagonist, MiscConst.AntagonistPos[i], TempSummonType.DeadDespawn); + } + + public override void EnterEvadeMode(EvadeReason why) + { + _EnterEvadeMode(); + summons.DespawnAll(); + _DespawnAtEvade(TimeSpan.FromSeconds(10)); + } + + public override void MoveInLineOfSight(Unit who) + { + if (phase != DirebrewPhases.All || !who.IsPlayer()) + return; + + phase = DirebrewPhases.Intro; + _scheduler.Schedule(TimeSpan.FromSeconds(6), introTask1 => + { + Talk(TextIds.SayIntro1); + introTask1.Schedule(TimeSpan.FromSeconds(4), introTask2 => + { + EntryCheckPredicate pred = new(CreatureIds.Antagonist); + summons.DoAction(ActionIds.AntagonistSay1, pred); + introTask2.Schedule(TimeSpan.FromSeconds(3), introlTask3 => + { + Talk(TextIds.SayIntro2); + EntryCheckPredicate pred = new(CreatureIds.Antagonist); + summons.DoAction(ActionIds.AntagonistSay2, pred); + }); + }); + }); + Talk(TextIds.SayIntro); + } + + public override void DoAction(int action) + { + if (action == ActionIds.StartFight) + { + phase = DirebrewPhases.One; + //events.SetPhase(PhaseOne); + me.SetImmuneToPC(false); + me.SetFaction((uint)FactionTemplates.GoblinDarkIronBarPatron); + DoZoneInCombat(); + + EntryCheckPredicate pred = new(CreatureIds.Antagonist); + summons.DoAction(ActionIds.AntagonistHostile, pred); + + _scheduler.Schedule(TimeSpan.FromSeconds(15), task => + { + CastSpellExtraArgs args = new CastSpellExtraArgs(TriggerCastFlags.FullMask); + args.AddSpellMod(SpellValueMod.MaxTargets, 1); + me.CastSpell((WorldObject)null, SpellIds.MoleMachineTargetPicker, args); + task.Repeat(); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(20), task => + { + DoCastSelf(SpellIds.DirebrewDisarmPreCast, new CastSpellExtraArgs(true)); + task.Repeat(); + }); + } + } + + public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null) + { + if (me.HealthBelowPctDamaged(66, damage) && phase == DirebrewPhases.One) + { + phase = DirebrewPhases.Two; + SummonSister(CreatureIds.IlsaDirebrew); + } + else if (me.HealthBelowPctDamaged(33, damage) && phase == DirebrewPhases.Two) + { + phase = DirebrewPhases.Three; + SummonSister(CreatureIds.UrsulaDirebrew); + } + } + + public override void SummonedCreatureDies(Creature summon, Unit killer) + { + if (summon.GetEntry() == CreatureIds.IlsaDirebrew) + { + _scheduler.Schedule(TimeSpan.FromSeconds(1), task => + { + SummonSister(CreatureIds.IlsaDirebrew); + }); + } + else if (summon.GetEntry() == CreatureIds.UrsulaDirebrew) + { + _scheduler.Schedule(TimeSpan.FromSeconds(1), task => + { + SummonSister(CreatureIds.UrsulaDirebrew); + }); + } + } + + public override void JustDied(Unit killer) + { + _JustDied(); + + var players = me.GetMap().GetPlayers(); + if (!players.Empty()) + { + Group group = players[0].GetGroup(); + if (group) + if (group.IsLFGGroup()) + Global.LFGMgr.FinishDungeon(group.GetGUID(), 287, me.GetMap()); + } + } + + void SummonSister(uint entry) + { + Creature sister = me.SummonCreature(entry, me.GetPosition(), TempSummonType.DeadDespawn); + if (sister) + DoZoneInCombat(sister); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim() && phase != DirebrewPhases.Intro) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } + + class npc_coren_direbrew_sisters : ScriptedAI + { + ObjectGuid _targetGUID; + + public npc_coren_direbrew_sisters(Creature creature) : base(creature) { } + + public override void SetGUID(ObjectGuid guid, int id) + { + if (id == MiscConst.DataTargetGuid) + _targetGUID = guid; + } + + public override ObjectGuid GetGUID(int data) + { + if (data == MiscConst.DataTargetGuid) + return _targetGUID; + + return ObjectGuid.Empty; + } + + public override void JustEngagedWith(Unit who) + { + DoCastSelf(SpellIds.PortToCoren); + + if (me.GetEntry() == CreatureIds.UrsulaDirebrew) + DoCastSelf(SpellIds.BarreledControlAura); + else + DoCastSelf(SpellIds.SendMugControlAura); + + _scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting)); + + _scheduler.Schedule(TimeSpan.FromSeconds(2), mugChuck => + { + Unit target = SelectTarget(SelectTargetMethod.Random, 0, 0.0f, false, true, -(int)SpellIds.HasDarkBrewmaidensBrew); + if (target) + DoCast(target, SpellIds.ChuckMug); + mugChuck.Repeat(TimeSpan.FromSeconds(4)); + }); + } + + public override void UpdateAI(uint diff) + { + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } + + class npc_direbrew_minion : ScriptedAI + { + InstanceScript _instance; + + public npc_direbrew_minion(Creature creature) : base(creature) + { + _instance = creature.GetInstanceScript(); + } + + public override void Reset() + { + me.SetFaction((uint)FactionTemplates.GoblinDarkIronBarPatron); + DoZoneInCombat(); + } + + public override void IsSummonedBy(WorldObject summoner) + { + Creature coren = ObjectAccessor.GetCreature(me, _instance.GetGuidData(DataTypes.DataCoren)); + if (coren) + coren.GetAI().JustSummoned(me); + } + } + + class npc_direbrew_antagonist : ScriptedAI + { + public npc_direbrew_antagonist(Creature creature) : base(creature) { } + + public override void DoAction(int action) + { + switch (action) + { + case ActionIds.AntagonistSay1: + Talk(TextIds.SayAntagonist1); + break; + case ActionIds.AntagonistSay2: + Talk(TextIds.SayAntagonist2); + break; + case ActionIds.AntagonistHostile: + me.SetImmuneToPC(false); + me.SetFaction((uint)FactionTemplates.GoblinDarkIronBarPatron); + DoZoneInCombat(); + break; + default: + break; + } + } + + public override void JustEngagedWith(Unit who) + { + Talk(TextIds.SayAntagonistCombat, who); + base.JustEngagedWith(who); + } + } + + class go_direbrew_mole_machineAI : GameObjectAI + { + public go_direbrew_mole_machineAI(GameObject go) : base(go) { } + + public override void Reset() + { + me.SetLootState(LootState.Ready); + _scheduler.Schedule(TimeSpan.FromSeconds(1), context => + { + me.UseDoorOrButton(10000); + me.CastSpell(null, SpellIds.MoleMachineEmerge, true); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(4), context => + { + GameObject trap = me.GetLinkedTrap(); + if (trap) + { + trap.SetLootState(LootState.Activated); + trap.UseDoorOrButton(); + } + }); + } + + public override void UpdateAI(uint diff) + { + _scheduler.Update(diff); + } + } + + // 47691 - Summon Mole Machine Target Picker + class spell_direbrew_summon_mole_machine_target_picker : SpellScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.MoleMachineMinionSummoner); + } + + void HandleScriptEffect(uint effIndex) + { + GetCaster().CastSpell(GetHitUnit(), SpellIds.MoleMachineMinionSummoner, true); + } + + public override void Register() + { + OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect)); + } + } + + // 47370 - Send Mug Target Picker + class spell_send_mug_target_picker : SpellScript + { + void FilterTargets(List targets) + { + Unit caster = GetCaster(); + + targets.RemoveAll(new UnitAuraCheck(true, SpellIds.HasDarkBrewmaidensBrew)); + + if (targets.Count > 1) + { + targets.RemoveAll(obj => + { + if (obj.GetGUID() == caster.GetAI().GetGUID(MiscConst.DataTargetGuid)) + return true; + return false; + }); + } + + if (targets.Empty()) + return; + + WorldObject target = targets.SelectRandom(); + targets.Clear(); + targets.Add(target); + } + + void HandleDummy(uint effIndex) + { + Unit caster = GetCaster(); + caster.GetAI().SetGUID(GetHitUnit().GetGUID(), MiscConst.DataTargetGuid); + caster.CastSpell(GetHitUnit(), SpellIds.SendFirstMug, true); + } + + public override void Register() + { + OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEntry)); + OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy)); + } + } + + // 47344 - Request Second Mug + class spell_request_second_mug : SpellScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.SendSecondMug); + } + + void HandleScriptEffect(uint effIndex) + { + GetHitUnit().CastSpell(GetCaster(), SpellIds.SendSecondMug, true); + } + + public override void Register() + { + OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect)); + } + } + + // 47369 - Send Mug Control Aura + class spell_send_mug_control_aura : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.SendMugTargetPicker); + } + + void PeriodicTick(AuraEffect aurEff) + { + GetTarget().CastSpell(GetTarget(), SpellIds.SendMugTargetPicker, true); + } + + public override void Register() + { + OnEffectPeriodic.Add(new EffectPeriodicHandler(PeriodicTick, 0, AuraType.PeriodicDummy)); + } + } + + // 50278 - Barreled Control Aura + class spell_barreled_control_aura : AuraScript + { + void PeriodicTick(AuraEffect aurEff) + { + PreventDefaultAction(); + GetTarget().CastSpell(null, SpellIds.Barreled, true); + } + + public override void Register() + { + OnEffectPeriodic.Add(new EffectPeriodicHandler(PeriodicTick, 0, AuraType.PeriodicTriggerSpell)); + } + } + + // 47407 - Direbrew's Disarm (precast) + class spell_direbrew_disarm : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.DirebrewDisarm, SpellIds.DirebrewDisarmGrow); + } + + void PeriodicTick(AuraEffect aurEff) + { + Aura aura = GetTarget().GetAura(SpellIds.DirebrewDisarmGrow); + if (aura != null) + { + aura.SetStackAmount((byte)(aura.GetStackAmount() + 1)); + aura.SetDuration(aura.GetDuration() - 1500); + } + } + + void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode) + { + GetTarget().CastSpell(GetTarget(), SpellIds.DirebrewDisarmGrow, true); + GetTarget().CastSpell(GetTarget(), SpellIds.DirebrewDisarm); + } + + public override void Register() + { + OnEffectPeriodic.Add(new EffectPeriodicHandler(PeriodicTick, 1, AuraType.PeriodicDummy)); + OnEffectApply.Add(new EffectApplyHandler(OnApply, 1, AuraType.PeriodicDummy, AuraEffectHandleModes.Real)); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/EmperorDagranThaurissan.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/EmperorDagranThaurissan.cs new file mode 100644 index 000000000..bf8c10dfe --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/EmperorDagranThaurissan.cs @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Maps; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths.Draganthaurissan +{ + struct SpellIds + { + public const uint Handofthaurissan = 17492; + public const uint Avatarofflame = 15636; + } + + struct TextIds + { + public const uint SayAggro = 0; + public const uint SaySlay = 1; + + public const uint EmoteShaken = 0; + } + + [Script] + class boss_draganthaurissan : ScriptedAI + { + InstanceScript _instance; + + public boss_draganthaurissan(Creature creature) : base(creature) + { + _instance = me.GetInstanceScript(); + } + + public override void Reset() + { + _scheduler.CancelAll(); + } + + public override void JustEngagedWith(Unit who) + { + Talk(TextIds.SayAggro); + me.CallForHelp(166.0f); + _scheduler.Schedule(TimeSpan.FromSeconds(4), task => + { + Unit target = SelectTarget(SelectTargetMethod.Random, 0); + if (target) + DoCast(target, SpellIds.Handofthaurissan); + task.Repeat(TimeSpan.FromSeconds(5)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(25), task => + { + DoCastVictim(SpellIds.Avatarofflame); + task.Repeat(TimeSpan.FromSeconds(18)); + }); + } + + public override void KilledUnit(Unit who) + { + if (who.IsPlayer()) + Talk(TextIds.SaySlay); + } + + public override void JustDied(Unit killer) + { + Creature moira = ObjectAccessor.GetCreature(me, _instance.GetGuidData(DataTypes.DataMoira)); + if (moira) + { + moira.GetAI().EnterEvadeMode(); + moira.SetFaction((uint)FactionTemplates.Friendly); + moira.GetAI().Talk(TextIds.EmoteShaken); + } + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/GeneralAngerforge.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/GeneralAngerforge.cs new file mode 100644 index 000000000..ef3a007c0 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/GeneralAngerforge.cs @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using Game.Spells; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths.GeneralAngerforge +{ + struct SpellIds + { + public const uint Mightyblow = 14099; + public const uint Hamstring = 9080; + public const uint Cleave = 20691; + } + + enum Phases + { + One = 1, + Two = 2 + } + + [Script] + class boss_general_angerforge : ScriptedAI + { + Phases phase; + + public boss_general_angerforge(Creature creature) : base(creature) { } + + public override void Reset() + { + _scheduler.CancelAll(); + } + + public override void JustEngagedWith(Unit who) + { + phase = Phases.One; + _scheduler.Schedule(TimeSpan.FromSeconds(8), task => + { + DoCastVictim(SpellIds.Mightyblow); + task.Repeat(TimeSpan.FromSeconds(18)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(12), task => + { + DoCastVictim(SpellIds.Hamstring); + task.Repeat(TimeSpan.FromSeconds(15)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(16), task => + { + DoCastVictim(SpellIds.Cleave); + task.Repeat(TimeSpan.FromSeconds(9)); + }); + } + + public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null) + { + if (me.HealthBelowPctDamaged(20, damage) && phase == Phases.One) + { + phase = Phases.Two; + _scheduler.Schedule(TimeSpan.FromSeconds(0), task => + { + for (byte i = 0; i < 2; ++i) + SummonMedic(me.GetVictim()); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(0), task => + { + for (byte i = 0; i < 3; ++i) + SummonAdd(me.GetVictim()); + task.Repeat(TimeSpan.FromSeconds(25)); + }); + } + } + + void SummonAdd(Unit victim) + { + Creature SummonedAdd = DoSpawnCreature(8901, RandomHelper.IRand(-14, 14), RandomHelper.IRand(-14, 14), 0, 0, TempSummonType.TimedOrCorpseDespawn, TimeSpan.FromSeconds(120)); + if (SummonedAdd) + SummonedAdd.GetAI().AttackStart(victim); + } + + void SummonMedic(Unit victim) + { + Creature SummonedMedic = DoSpawnCreature(8894, RandomHelper.IRand(-9, 9), RandomHelper.IRand(-9, 9), 0, 0, TempSummonType.TimedOrCorpseDespawn, TimeSpan.FromSeconds(120)); + if (SummonedMedic) + SummonedMedic.GetAI().AttackStart(victim); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/HighInterrogatorGerstahn.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/HighInterrogatorGerstahn.cs new file mode 100644 index 000000000..8dc61b951 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/HighInterrogatorGerstahn.cs @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths.HighInterrogatorGerstahn +{ + struct SpellIds + { + public const uint Shadowwordpain = 10894; + public const uint Manaburn = 10876; + public const uint Psychicscream = 8122; + public const uint Shadowshield = 22417; + } + + [Script] + class boss_high_interrogator_gerstahn : ScriptedAI + { + public boss_high_interrogator_gerstahn(Creature creature) : base(creature) { } + + public override void Reset() + { + _scheduler.CancelAll(); + } + + public override void JustEngagedWith(Unit who) + { + _scheduler.Schedule(TimeSpan.FromSeconds(4), task => + { + Unit target = SelectTarget(SelectTargetMethod.Random, 0, 100.0f, true); + if (target) + DoCast(target, SpellIds.Shadowwordpain); + task.Repeat(TimeSpan.FromSeconds(7)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(14), task => + { + Unit target = SelectTarget(SelectTargetMethod.Random, 0, 100.0f, true); + if (target) + DoCast(target, SpellIds.Manaburn); + task.Repeat(TimeSpan.FromSeconds(10)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(32), task => + { + DoCastVictim(SpellIds.Psychicscream); + task.Repeat(TimeSpan.FromSeconds(30)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(8), task => + { + DoCast(me, SpellIds.Shadowshield); + task.Repeat(TimeSpan.FromSeconds(25)); + }); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/InstanceBlackrockDepths.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/InstanceBlackrockDepths.cs new file mode 100644 index 000000000..b0dabb00f --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/InstanceBlackrockDepths.cs @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Framework.IO; +using Game.Entities; +using Game.Maps; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths +{ + struct CreatureIds + { + public const uint Emperor = 9019; + public const uint Phalanx = 9502; + public const uint Angerrel = 9035; + public const uint Doperel = 9040; + public const uint Haterel = 9034; + public const uint Vilerel = 9036; + public const uint Seethrel = 9038; + public const uint Gloomrel = 9037; + public const uint Doomrel = 9039; + public const uint Magmus = 9938; + public const uint Moira = 8929; + public const uint Coren = 23872; + } + + struct GameObjectIds + { + public const uint Arena1 = 161525; + public const uint Arena2 = 161522; + public const uint Arena3 = 161524; + public const uint Arena4 = 161523; + public const uint ShadowLock = 161460; + public const uint ShadowMechanism = 161461; + public const uint ShadowGiantDoor = 157923; + public const uint ShadowDummy = 161516; + public const uint BarKegShot = 170607; + public const uint BarKegTrap = 171941; + public const uint BarDoor = 170571; + public const uint TombEnter = 170576; + public const uint TombExit = 170577; + public const uint Lyceum = 170558; + public const uint SfN = 174745; // Shadowforge Brazier North + public const uint SfS = 174744; // Shadowforge Brazier South + public const uint GolemRoomN = 170573; // Magmus door North + public const uint GolemRoomS = 170574; // Magmus door Soutsh + public const uint ThroneRoom = 170575; // Throne door + public const uint SpectralChalice = 164869; + public const uint ChestSeven = 169243; + } + + struct DataTypes + { + public const uint TypeRingOfLaw = 1; + public const uint TypeVault = 2; + public const uint TypeBar = 3; + public const uint TypeTombOfSeven = 4; + public const uint TypeLyceum = 5; + public const uint TypeIronHall = 6; + + public const uint DataEmperor = 10; + public const uint DataPhalanx = 11; + + public const uint DataArena1 = 12; + public const uint DataArena2 = 13; + public const uint DataArena3 = 14; + public const uint DataArena4 = 15; + + public const uint DataGoBarKeg = 16; + public const uint DataGoBarKegTrap = 17; + public const uint DataGoBarDoor = 18; + public const uint DataGoChalice = 19; + + public const uint DataGhostkill = 20; + public const uint DataEvenstarter = 21; + + public const uint DataGolemDoorN = 22; + public const uint DataGolemDoorS = 23; + + public const uint DataThroneDoor = 24; + + public const uint DataSfBrazierN = 25; + public const uint DataSfBrazierS = 26; + public const uint DataMoira = 27; + public const uint DataCoren = 28; + } + + struct MiscConst + { + public const uint TimerTombOfTheSeven = 15000; + public const uint MaxEncounter = 6; + public const uint TombOfSevenBossNum = 7; + } + + class instance_blackrock_depths : InstanceMapScript + { + public instance_blackrock_depths() : base(nameof(instance_blackrock_depths), 230) { } + + class instance_blackrock_depths_InstanceMapScript : InstanceScript + { + uint[] encounter = new uint[MiscConst.MaxEncounter]; + string str_data; + + ObjectGuid EmperorGUID; + ObjectGuid PhalanxGUID; + ObjectGuid MagmusGUID; + ObjectGuid MoiraGUID; + ObjectGuid CorenGUID; + + ObjectGuid GoArena1GUID; + ObjectGuid GoArena2GUID; + ObjectGuid GoArena3GUID; + ObjectGuid GoArena4GUID; + ObjectGuid GoShadowLockGUID; + ObjectGuid GoShadowMechGUID; + ObjectGuid GoShadowGiantGUID; + ObjectGuid GoShadowDummyGUID; + ObjectGuid GoBarKegGUID; + ObjectGuid GoBarKegTrapGUID; + ObjectGuid GoBarDoorGUID; + ObjectGuid GoTombEnterGUID; + ObjectGuid GoTombExitGUID; + ObjectGuid GoLyceumGUID; + ObjectGuid GoSFSGUID; + ObjectGuid GoSFNGUID; + ObjectGuid GoGolemNGUID; + ObjectGuid GoGolemSGUID; + ObjectGuid GoThroneGUID; + ObjectGuid GoChestGUID; + ObjectGuid GoSpectralChaliceGUID; + + uint BarAleCount; + uint GhostKillCount; + ObjectGuid[] TombBossGUIDs = new ObjectGuid[MiscConst.TombOfSevenBossNum]; + ObjectGuid TombEventStarterGUID; + uint TombTimer; + uint TombEventCounter; + + public instance_blackrock_depths_InstanceMapScript(InstanceMap map) : base(map) + { + SetHeaders("BRD"); + + BarAleCount = 0; + GhostKillCount = 0; + TombTimer = MiscConst.TimerTombOfTheSeven; + TombEventCounter = 0; + } + + public override void OnCreatureCreate(Creature creature) + { + switch (creature.GetEntry()) + { + case CreatureIds.Emperor: EmperorGUID = creature.GetGUID(); break; + case CreatureIds.Phalanx: PhalanxGUID = creature.GetGUID(); break; + case CreatureIds.Moira: MoiraGUID = creature.GetGUID(); break; + case CreatureIds.Coren: CorenGUID = creature.GetGUID(); break; + case CreatureIds.Doomrel: TombBossGUIDs[0] = creature.GetGUID(); break; + case CreatureIds.Doperel: TombBossGUIDs[1] = creature.GetGUID(); break; + case CreatureIds.Haterel: TombBossGUIDs[2] = creature.GetGUID(); break; + case CreatureIds.Vilerel: TombBossGUIDs[3] = creature.GetGUID(); break; + case CreatureIds.Seethrel: TombBossGUIDs[4] = creature.GetGUID(); break; + case CreatureIds.Gloomrel: TombBossGUIDs[5] = creature.GetGUID(); break; + case CreatureIds.Angerrel: TombBossGUIDs[6] = creature.GetGUID(); break; + case CreatureIds.Magmus: + MagmusGUID = creature.GetGUID(); + if (!creature.IsAlive()) + HandleGameObject(GetGuidData(DataTypes.DataThroneDoor), true); // if Magmus is dead open door to last boss + break; + } + } + + public override void OnGameObjectCreate(GameObject go) + { + switch (go.GetEntry()) + { + case GameObjectIds.Arena1: GoArena1GUID = go.GetGUID(); break; + case GameObjectIds.Arena2: GoArena2GUID = go.GetGUID(); break; + case GameObjectIds.Arena3: GoArena3GUID = go.GetGUID(); break; + case GameObjectIds.Arena4: GoArena4GUID = go.GetGUID(); break; + case GameObjectIds.ShadowLock: GoShadowLockGUID = go.GetGUID(); break; + case GameObjectIds.ShadowMechanism: GoShadowMechGUID = go.GetGUID(); break; + case GameObjectIds.ShadowGiantDoor: GoShadowGiantGUID = go.GetGUID(); break; + case GameObjectIds.ShadowDummy: GoShadowDummyGUID = go.GetGUID(); break; + case GameObjectIds.BarKegShot: GoBarKegGUID = go.GetGUID(); break; + case GameObjectIds.BarKegTrap: GoBarKegTrapGUID = go.GetGUID(); break; + case GameObjectIds.BarDoor: GoBarDoorGUID = go.GetGUID(); break; + case GameObjectIds.TombEnter: GoTombEnterGUID = go.GetGUID(); break; + case GameObjectIds.TombExit: + GoTombExitGUID = go.GetGUID(); + if (GhostKillCount >= MiscConst.TombOfSevenBossNum) + HandleGameObject(ObjectGuid.Empty, true, go); + else + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectIds.Lyceum: GoLyceumGUID = go.GetGUID(); break; + case GameObjectIds.SfS: GoSFSGUID = go.GetGUID(); break; + case GameObjectIds.SfN: GoSFNGUID = go.GetGUID(); break; + case GameObjectIds.GolemRoomN: GoGolemNGUID = go.GetGUID(); break; + case GameObjectIds.GolemRoomS: GoGolemSGUID = go.GetGUID(); break; + case GameObjectIds.ThroneRoom: GoThroneGUID = go.GetGUID(); break; + case GameObjectIds.ChestSeven: GoChestGUID = go.GetGUID(); break; + case GameObjectIds.SpectralChalice: GoSpectralChaliceGUID = go.GetGUID(); break; + } + } + + public override void SetGuidData(uint type, ObjectGuid data) + { + switch (type) + { + case DataTypes.DataEvenstarter: + TombEventStarterGUID = data; + if (TombEventStarterGUID.IsEmpty()) + TombOfSevenReset();//reset + else + TombOfSevenStart();//start + break; + } + } + + public override void SetData(uint type, uint data) + { + switch (type) + { + case DataTypes.TypeRingOfLaw: + encounter[0] = data; + break; + case DataTypes.TypeVault: + encounter[1] = data; + break; + case DataTypes.TypeBar: + if (data == (uint)EncounterState.Special) + ++BarAleCount; + else + encounter[2] = data; + break; + case DataTypes.TypeTombOfSeven: + encounter[3] = data; + break; + case DataTypes.TypeLyceum: + encounter[4] = data; + break; + case DataTypes.TypeIronHall: + encounter[5] = data; + break; + case DataTypes.DataGhostkill: + GhostKillCount += data; + break; + } + + if (data == (uint)EncounterState.Done || GhostKillCount >= MiscConst.TombOfSevenBossNum) + { + OutSaveInstData(); + + str_data = $"{encounter[0]} {encounter[1]} {encounter[2]} {encounter[3]} {encounter[4]} {encounter[5]} {GhostKillCount}"; + + SaveToDB(); + OutSaveInstDataComplete(); + } + } + + public override uint GetData(uint type) + { + switch (type) + { + case DataTypes.TypeRingOfLaw: + return encounter[0]; + case DataTypes.TypeVault: + return encounter[1]; + case DataTypes.TypeBar: + if (encounter[2] == (uint)EncounterState.InProgress && BarAleCount == 3) + return (uint)EncounterState.Special; + else + return encounter[2]; + case DataTypes.TypeTombOfSeven: + return encounter[3]; + case DataTypes.TypeLyceum: + return encounter[4]; + case DataTypes.TypeIronHall: + return encounter[5]; + case DataTypes.DataGhostkill: + return GhostKillCount; + } + return 0; + } + + public override ObjectGuid GetGuidData(uint data) + { + switch (data) + { + case DataTypes.DataEmperor: + return EmperorGUID; + case DataTypes.DataPhalanx: + return PhalanxGUID; + case DataTypes.DataMoira: + return MoiraGUID; + case DataTypes.DataCoren: + return CorenGUID; + case DataTypes.DataArena1: + return GoArena1GUID; + case DataTypes.DataArena2: + return GoArena2GUID; + case DataTypes.DataArena3: + return GoArena3GUID; + case DataTypes.DataArena4: + return GoArena4GUID; + case DataTypes.DataGoBarKeg: + return GoBarKegGUID; + case DataTypes.DataGoBarKegTrap: + return GoBarKegTrapGUID; + case DataTypes.DataGoBarDoor: + return GoBarDoorGUID; + case DataTypes.DataEvenstarter: + return TombEventStarterGUID; + case DataTypes.DataSfBrazierN: + return GoSFNGUID; + case DataTypes.DataSfBrazierS: + return GoSFSGUID; + case DataTypes.DataThroneDoor: + return GoThroneGUID; + case DataTypes.DataGolemDoorN: + return GoGolemNGUID; + case DataTypes.DataGolemDoorS: + return GoGolemSGUID; + case DataTypes.DataGoChalice: + return GoSpectralChaliceGUID; + } + return ObjectGuid.Empty; + } + + public override string GetSaveData() + { + return str_data; + } + + public override void Load(string str) + { + if (str.IsEmpty()) + { + + OutLoadInstDataFail(); + return; + } + + OutLoadInstData(str); + + StringArguments loadStream = new(str); + + for (var i = 0; i < encounter.Length; ++i) + encounter[i] = loadStream.NextUInt32(); + + GhostKillCount = loadStream.NextUInt32(); + + for (byte i = 0; i < encounter.Length; ++i) + if (encounter[i] == (uint)EncounterState.InProgress) + encounter[i] = (uint)EncounterState.NotStarted; + + if (GhostKillCount > 0 && GhostKillCount < MiscConst.TombOfSevenBossNum) + GhostKillCount = 0;//reset tomb of seven event + if (GhostKillCount >= MiscConst.TombOfSevenBossNum) + GhostKillCount = MiscConst.TombOfSevenBossNum; + + OutLoadInstDataComplete(); + } + + void TombOfSevenEvent() + { + if (GhostKillCount < MiscConst.TombOfSevenBossNum && !TombBossGUIDs[TombEventCounter].IsEmpty()) + { + Creature boss = instance.GetCreature(TombBossGUIDs[TombEventCounter]); + if (boss) + { + boss.SetFaction((uint)FactionTemplates.DarkIronDwarves); + boss.SetImmuneToPC(false); + Unit target = boss.SelectNearestTarget(500); + if (target) + boss.GetAI().AttackStart(target); + } + } + } + + void TombOfSevenReset() + { + HandleGameObject(GoTombExitGUID, false);//event reseted, close exit door + HandleGameObject(GoTombEnterGUID, true);//event reseted, open entrance door + for (byte i = 0; i < MiscConst.TombOfSevenBossNum; ++i) + { + Creature boss = instance.GetCreature(TombBossGUIDs[i]); + if (boss) + { + if (!boss.IsAlive()) + boss.Respawn(); + else + boss.SetFaction((uint)FactionTemplates.Friendly); + } + } + GhostKillCount = 0; + TombEventStarterGUID.Clear(); + TombEventCounter = 0; + TombTimer = MiscConst.TimerTombOfTheSeven; + SetData(DataTypes.TypeTombOfSeven, (uint)EncounterState.NotStarted); + } + + void TombOfSevenStart() + { + HandleGameObject(GoTombExitGUID, false);//event started, close exit door + HandleGameObject(GoTombEnterGUID, false);//event started, close entrance door + SetData(DataTypes.TypeTombOfSeven, (uint)EncounterState.InProgress); + } + + void TombOfSevenEnd() + { + DoRespawnGameObject(GoChestGUID, TimeSpan.FromHours(24)); + HandleGameObject(GoTombExitGUID, true);//event done, open exit door + HandleGameObject(GoTombEnterGUID, true);//event done, open entrance door + TombEventStarterGUID.Clear(); + SetData(DataTypes.TypeTombOfSeven, (uint)EncounterState.Done); + } + + public override void Update(uint diff) + { + if (!TombEventStarterGUID.IsEmpty() && GhostKillCount < MiscConst.TombOfSevenBossNum) + { + if (TombTimer <= diff) + { + TombTimer = MiscConst.TimerTombOfTheSeven; + if (TombEventCounter < MiscConst.TombOfSevenBossNum) + { + TombOfSevenEvent(); + ++TombEventCounter; + } + + // Check Killed bosses + for (byte i = 0; i < MiscConst.TombOfSevenBossNum; ++i) + { + Creature boss = instance.GetCreature(TombBossGUIDs[i]); + if (boss) + { + if (!boss.IsAlive()) + { + GhostKillCount = i + 1u; + } + } + } + } + else TombTimer -= diff; + } + if (GhostKillCount >= MiscConst.TombOfSevenBossNum && !TombEventStarterGUID.IsEmpty()) + TombOfSevenEnd(); + } + } + + public override InstanceScript GetInstanceScript(InstanceMap map) + { + return new instance_blackrock_depths_InstanceMapScript(map); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/Magmus.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/Magmus.cs new file mode 100644 index 000000000..5b53ef0b3 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/Magmus.cs @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Maps; +using Game.Scripting; +using Game.Spells; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths.Magmus +{ + struct SpellIds + { + //Magmus + public const uint Fieryburst = 13900; + public const uint Warstomp = 24375; + + //IronhandGuardian + public const uint Goutofflame = 15529; + } + + enum Phases + { + One = 1, + Two = 2 + } + + [Script] + class boss_magmus : ScriptedAI + { + Phases phase; + + public boss_magmus(Creature creature) : base(creature) { } + + public override void Reset() + { + _scheduler.CancelAll(); + } + + public override void JustEngagedWith(Unit who) + { + InstanceScript instance = me.GetInstanceScript(); + if (instance != null) + instance.SetData(DataTypes.TypeIronHall, (uint)EncounterState.InProgress); + + phase = Phases.One; + _scheduler.Schedule(TimeSpan.FromSeconds(5), task => + { + DoCastVictim(SpellIds.Fieryburst); + task.Repeat(TimeSpan.FromSeconds(6)); + }); + } + + public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null) + { + if (me.HealthBelowPctDamaged(50, damage) && phase == Phases.One) + { + phase = Phases.Two; + _scheduler.Schedule(TimeSpan.FromSeconds(0), task => + { + DoCastVictim(SpellIds.Warstomp); + task.Repeat(TimeSpan.FromSeconds(8)); + }); + } + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + + public override void JustDied(Unit killer) + { + InstanceScript instance = me.GetInstanceScript(); + if (instance != null) + { + instance.HandleGameObject(instance.GetGuidData(DataTypes.DataThroneDoor), true); + instance.SetData(DataTypes.TypeIronHall, (uint)EncounterState.Done); + } + } + } + + [Script] + class npc_ironhand_guardianAI : ScriptedAI + { + InstanceScript _instance; + bool _active; + + public npc_ironhand_guardianAI(Creature creature) : base(creature) + { + _instance = me.GetInstanceScript(); + _active = false; + } + + public override void Reset() + { + _scheduler.CancelAll(); + } + + public override void UpdateAI(uint diff) + { + if (!_active) + { + if (_instance.GetData(DataTypes.TypeIronHall) == (uint)EncounterState.NotStarted) + return; + // Once the boss is engaged, the guardians will stay activated until the next instance reset + _scheduler.Schedule(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(10), task => + { + DoCastAOE(SpellIds.Goutofflame); + task.Repeat(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(21)); + }); + _active = true; + } + + _scheduler.Update(diff); + } + } +} \ No newline at end of file diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/MoiraBronzebeard.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/MoiraBronzebeard.cs new file mode 100644 index 000000000..7ed6509d2 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/MoiraBronzebeard.cs @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths.MoiraBronzebeard +{ + struct SpellIds + { + public const uint Heal = 10917; + public const uint Renew = 10929; + public const uint Shield = 10901; + public const uint Mindblast = 10947; + public const uint Shadowwordpain = 10894; + public const uint Smite = 10934; + } + + [Script] + class boss_moira_bronzebeard : ScriptedAI + { + public boss_moira_bronzebeard(Creature creature) : base(creature) { } + + public override void Reset() + { + _scheduler.CancelAll(); + } + + public override void JustEngagedWith(Unit who) + { + //_scheduler.Schedule(EventHeal, TimeSpan.FromSeconds(12s)); // not used atm // These times are probably wrong + _scheduler.Schedule(TimeSpan.FromSeconds(16), task => + { + DoCastVictim(SpellIds.Mindblast); + task.Repeat(TimeSpan.FromSeconds(14)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(2), task => + { + DoCastVictim(SpellIds.Shadowwordpain); + task.Repeat(TimeSpan.FromSeconds(18)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(8), task => + { + DoCastVictim(SpellIds.Smite); + task.Repeat(TimeSpan.FromSeconds(10)); + }); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/TombOfSeven.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/TombOfSeven.cs new file mode 100644 index 000000000..a732296cd --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/TombOfSeven.cs @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Maps; +using Game.Scripting; +using Game.Spells; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths.TombOfSeven +{ + struct SpellIds + { + //Gloomrel + public const uint SmeltDarkIron = 14891; + public const uint LearnSmelt = 14894; + + //Doomrel + public const uint Shadowboltvolley = 15245; + public const uint Immolate = 12742; + public const uint Curseofweakness = 12493; + public const uint Demonarmor = 13787; + public const uint SummonVoidwalkers = 15092; + } + + struct QuestIds + { + public const uint SpectralChalice = 4083; + } + + struct TextIds + { + public const uint GossipSelectDoomrel = 1828; + public const uint GossipMenuIdContinue = 1; + + public const uint GossipMenuChallenge = 1947; + public const uint GossipMenuIdChallenge = 0; + } + + struct MiscConst + { + public const uint DataSkillpointMin = 230; + + public const string GossipItemTeach1 = "Teach me the art of smelting dark iron"; + public const string GossipItemTeach2 = "Continue..."; + public const string GossipItemTeach3 = "[PH] Continue..."; + public const string GossipItemTribute = "I want to pay tribute"; + } + + enum Phases + { + PhaseOne = 1, + PhaseTwo = 2 + } + + [Script] + class boss_gloomrel : ScriptedAI + { + InstanceScript instance; + + public boss_gloomrel(Creature creature) : base(creature) + { + instance = creature.GetInstanceScript(); + } + + public override bool OnGossipSelect(Player player, uint menuId, uint gossipListId) + { + uint action = player.PlayerTalkClass.GetGossipOptionAction(gossipListId); + player.ClearGossipMenu(); + switch (action) + { + case eTradeskill.GossipActionInfoDef + 1: + player.AddGossipItem(GossipOptionIcon.None, MiscConst.GossipItemTeach2, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 11); + player.SendGossipMenu(2606, me.GetGUID()); + break; + case eTradeskill.GossipActionInfoDef + 11: + player.CloseGossipMenu(); + player.CastSpell(player, SpellIds.LearnSmelt, false); + break; + case eTradeskill.GossipActionInfoDef + 2: + player.AddGossipItem(GossipOptionIcon.None, MiscConst.GossipItemTeach3, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 22); + player.SendGossipMenu(2604, me.GetGUID()); + break; + case eTradeskill.GossipActionInfoDef + 22: + player.CloseGossipMenu(); + //are 5 minutes expected? go template may have data to despawn when used at quest + instance.DoRespawnGameObject(instance.GetGuidData(DataTypes.DataGoChalice), TimeSpan.FromMinutes(5)); + break; + } + return true; + } + + public override bool OnGossipHello(Player player) + { + if (player.GetQuestRewardStatus(QuestIds.SpectralChalice) && player.GetSkillValue(SkillType.Mining) >= MiscConst.DataSkillpointMin && !player.HasSpell(SpellIds.SmeltDarkIron)) + player.AddGossipItem(GossipOptionIcon.None, MiscConst.GossipItemTeach1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1); + + if (!player.GetQuestRewardStatus(QuestIds.SpectralChalice) && player.GetSkillValue(SkillType.Mining) >= MiscConst.DataSkillpointMin) + player.AddGossipItem(GossipOptionIcon.None, MiscConst.GossipItemTribute, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 2); + + player.SendGossipMenu(player.GetGossipTextId(me), me.GetGUID()); + return true; + } + } + + [Script] + class boss_doomrel : ScriptedAI + { + InstanceScript _instance; + bool _voidwalkers; + + public boss_doomrel(Creature creature) : base(creature) + { + Initialize(); + _instance = creature.GetInstanceScript(); + } + + void Initialize() + { + _voidwalkers = false; + } + + public override void Reset() + { + Initialize(); + + me.SetFaction((uint)FactionTemplates.Friendly); + + // was set before event start, so set again + me.SetImmuneToPC(true); + + if (_instance.GetData(DataTypes.DataGhostkill) >= 7) + me.ReplaceAllNpcFlags(NPCFlags.None); + else + me.ReplaceAllNpcFlags(NPCFlags.Gossip); + } + + public override void JustEngagedWith(Unit who) + { + _scheduler.Schedule(TimeSpan.FromSeconds(10), task => + { + DoCastVictim(SpellIds.Shadowboltvolley); + task.Repeat(TimeSpan.FromSeconds(12)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(18), task => + { + Unit target = SelectTarget(SelectTargetMethod.Random, 0, 100.0f, true); + if (target) + DoCast(target, SpellIds.Immolate); + task.Repeat(TimeSpan.FromSeconds(25)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(5), task => + { + DoCastVictim(SpellIds.Curseofweakness); + task.Repeat(TimeSpan.FromSeconds(45)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(16), task => + { + DoCast(me, SpellIds.Demonarmor); + task.Repeat(TimeSpan.FromMinutes(5)); + }); + } + + public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null) + { + if (!_voidwalkers && !HealthAbovePct(50)) + { + DoCastVictim(SpellIds.SummonVoidwalkers, new CastSpellExtraArgs(true)); + _voidwalkers = true; + } + } + + public override void EnterEvadeMode(EvadeReason why) + { + base.EnterEvadeMode(why); + + _instance.SetGuidData(DataTypes.DataEvenstarter, ObjectGuid.Empty); + } + + public override void JustDied(Unit killer) + { + _instance.SetData(DataTypes.DataGhostkill, 1); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + + public override bool OnGossipSelect(Player player, uint menuId, uint gossipListId) + { + uint action = player.PlayerTalkClass.GetGossipOptionAction(gossipListId); + player.ClearGossipMenu(); + + switch (action) + { + case eTradeskill.GossipActionInfoDef + 1: + player.AddGossipItem(TextIds.GossipSelectDoomrel, TextIds.GossipMenuIdContinue, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 2); + player.SendGossipMenu(2605, me.GetGUID()); + break; + case eTradeskill.GossipActionInfoDef + 2: + player.CloseGossipMenu(); + //start event here + me.SetFaction((int)FactionTemplates.DarkIronDwarves); + me.SetImmuneToPC(false); + me.GetAI().AttackStart(player); + + _instance.SetGuidData(DataTypes.DataEvenstarter, player.GetGUID()); + break; + } + return true; + } + + public override bool OnGossipHello(Player player) + { + player.AddGossipItem(TextIds.GossipMenuChallenge, TextIds.GossipMenuIdChallenge, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1); + player.SendGossipMenu(2601, me.GetGUID()); + + return true; + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/Drakkisath.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/Drakkisath.cs new file mode 100644 index 000000000..85d486477 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/Drakkisath.cs @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.Drakkisath +{ + struct SpellIds + { + public const uint Firenova = 23462; + public const uint Cleave = 20691; + public const uint Confliguration = 16805; + public const uint Thunderclap = 15548; //Not sure if right Id. 23931 would be a harder possibility. + } + + [Script] + class boss_drakkisath : BossAI + { + public boss_drakkisath(Creature creature) : base(creature, DataTypes.GeneralDrakkisath) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + _scheduler.Schedule(TimeSpan.FromSeconds(6), task => + { + DoCastVictim(SpellIds.Firenova); + task.Repeat(TimeSpan.FromSeconds(10)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(8), task => + { + DoCastVictim(SpellIds.Cleave); + task.Repeat(TimeSpan.FromSeconds(8)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(15), task => + { + DoCastVictim(SpellIds.Confliguration); + task.Repeat(TimeSpan.FromSeconds(18)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(17), task => + { + DoCastVictim(SpellIds.Thunderclap); + task.Repeat(TimeSpan.FromSeconds(20)); + }); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/GizrulTheSlavener.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/GizrulTheSlavener.cs new file mode 100644 index 000000000..8b342345e --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/GizrulTheSlavener.cs @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.GizrulTheSlavener +{ + struct SpellIds + { + public const uint FatalBite = 16495; + public const uint InfectedBite = 16128; + public const uint Frenzy = 8269; + } + + struct PathIds + { + public const uint Gizrul = 402450; + } + + [Script] + class boss_gizrul_the_slavener : BossAI + { + public boss_gizrul_the_slavener(Creature creature) : base(creature, DataTypes.GizrulTheSlavener) { } + + public override void Reset() + { + _Reset(); + } + + public override void IsSummonedBy(WorldObject summoner) + { + me.GetMotionMaster().MovePath(PathIds.Gizrul, false); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(17), TimeSpan.FromSeconds(20), task => + { + DoCastVictim(SpellIds.FatalBite); + task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(12), task => + { + DoCast(me, SpellIds.InfectedBite); + task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10)); + }); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/Gyth.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/Gyth.cs new file mode 100644 index 000000000..713b6fcf6 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/Gyth.cs @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.Gyth +{ + struct SpellIds + { + public const uint RendMounts = 16167; // Change model + public const uint CorrosiveAcid = 16359; // Combat (self cast) + public const uint Flamebreath = 16390; // Combat (Self cast) + public const uint Freeze = 16350; // Combat (Self cast) + public const uint KnockAway = 10101; // Combat + public const uint SummonRend = 16328; // Summons Rend near death + } + + struct MiscConst + { + public const uint NefariusPath2 = 1379671; + public const uint NefariusPath3 = 1379672; + public const uint GythPath1 = 1379681; + } + + [Script] + class boss_gyth : BossAI + { + bool SummonedRend; + + public boss_gyth(Creature creature) : base(creature, DataTypes.Gyth) + { + Initialize(); + } + + void Initialize() + { + SummonedRend = false; + } + + public override void Reset() + { + Initialize(); + if (instance.GetBossState(DataTypes.Gyth) == EncounterState.InProgress) + { + instance.SetBossState(DataTypes.Gyth, EncounterState.Done); + me.DespawnOrUnsummon(); + } + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.CancelAll(); + _scheduler.Schedule(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(16), task => + { + DoCast(me, SpellIds.CorrosiveAcid); + task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(16)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(16), task => + { + DoCast(me, SpellIds.Freeze); + task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(16)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(16), task => + { + DoCast(me, SpellIds.Flamebreath); + task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(16)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(18), task => + { + DoCastVictim(SpellIds.KnockAway); + task.Repeat(TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(20)); + }); + } + + public override void JustDied(Unit killer) + { + instance.SetBossState(DataTypes.Gyth, EncounterState.Done); + } + + public override void SetData(uint type, uint data) + { + switch (data) + { + case 1: + _scheduler.Schedule(TimeSpan.FromSeconds(1), task => + { + me.AddAura(SpellIds.RendMounts, me); + GameObject portcullis = me.FindNearestGameObject(GameObjectsIds.DrPortcullis, 40.0f); + if (portcullis) + portcullis.UseDoorOrButton(); + Creature victor = me.FindNearestCreature(CreaturesIds.LordVictorNefarius, 75.0f, true); + if (victor) + victor.GetAI().SetData(1, 1); + + task.Schedule(TimeSpan.FromSeconds(2), summonTask2 => + { + me.GetMotionMaster().MovePath(MiscConst.GythPath1, false); + }); + }); + break; + default: + break; + } + } + + public override void UpdateAI(uint diff) + { + if (!SummonedRend && HealthBelowPct(5)) + { + DoCast(me, SpellIds.SummonRend); + me.RemoveAura(SpellIds.RendMounts); + SummonedRend = true; + } + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/Halycon.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/Halycon.cs new file mode 100644 index 000000000..955f3b046 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/Halycon.cs @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.Halycon +{ + + struct SpellIds + { + public const uint Rend = 13738; + public const uint Thrash = 3391; + } + + struct TextIds + { + public const uint EmoteDeath = 0; + } + + [Script] + class boss_halycon : BossAI + { + static Position SummonLocation = new Position(-167.9561f, -411.7844f, 76.23057f, 1.53589f); + + bool Summoned; + + public boss_halycon(Creature creature) : base(creature, DataTypes.Halycon) + { + Initialize(); + } + + void Initialize() + { + Summoned = false; + } + + public override void Reset() + { + _Reset(); + Initialize(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(17), TimeSpan.FromSeconds(20), task => + { + DoCastVictim(SpellIds.Rend); + task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(12), task => + { + DoCast(me, SpellIds.Thrash); + }); + } + + public override void JustDied(Unit killer) + { + me.SummonCreature(CreaturesIds.GizrulTheSlavener, SummonLocation, TempSummonType.TimedDespawn, TimeSpan.FromMinutes(5)); + Talk(TextIds.EmoteDeath); + + Summoned = true; + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/HighlordOmokk.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/HighlordOmokk.cs new file mode 100644 index 000000000..f6b03a7bc --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/HighlordOmokk.cs @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.HighlordOmokk +{ + struct SpellIds + { + public const uint Frenzy = 8269; + public const uint KnockAway = 10101; + } + + [Script] + class boss_highlord_omokk : BossAI + { + public boss_highlord_omokk(Creature creature) : base(creature, DataTypes.HighlordOmokk) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(20), task => + { + DoCastVictim(SpellIds.Frenzy); + task.Repeat(TimeSpan.FromMinutes(1)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(18), task => + { + DoCastVictim(SpellIds.KnockAway); + task.Repeat(TimeSpan.FromSeconds(12)); + }); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/InstanceBlackrockSpire.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/InstanceBlackrockSpire.cs new file mode 100644 index 000000000..bc3413754 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/InstanceBlackrockSpire.cs @@ -0,0 +1,721 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.DataStorage; +using Game.Entities; +using Game.Maps; +using Game.Scripting; +using System; +using System.Collections.Generic; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire +{ + struct DataTypes + { + public const uint HighlordOmokk = 0; + public const uint ShadowHunterVoshgajin = 1; + public const uint WarmasterVoone = 2; + public const uint MotherSmolderweb = 3; + public const uint UrokDoomhowl = 4; + public const uint QuartermasterZigris = 5; + public const uint GizrulTheSlavener = 6; + public const uint Halycon = 7; + public const uint OverlordWyrmthalak = 8; + public const uint PyrogaurdEmberseer = 9; + public const uint WarchiefRendBlackhand = 10; + public const uint Gyth = 11; + public const uint TheBeast = 12; + public const uint GeneralDrakkisath = 13; + public const uint LordValthalak = 14; + // Extra + public const uint DragonspireRoom = 15; + public const uint HallRune1 = 16; + public const uint HallRune2 = 17; + public const uint HallRune3 = 18; + public const uint HallRune4 = 19; + public const uint HallRune5 = 20; + public const uint HallRune6 = 21; + public const uint HallRune7 = 22; + public const uint ScarshieldInfiltrator = 23; + public const uint BlackhandIncarcerator = 24; + } + + struct CreaturesIds + { + public const uint HighlordOmokk = 9196; + public const uint ShadowHunterVoshgajin = 9236; + public const uint WarmasterVoone = 9237; + public const uint MotherSmolderweb = 10596; + public const uint UrokDoomhowl = 10584; + public const uint QuartermasterZigris = 9736; + public const uint GizrulTheSlavener = 10268; + public const uint Halycon = 10220; + public const uint OverlordWyrmthalak = 9568; + public const uint PyrogaurdEmberseer = 9816; + public const uint WarchiefRendBlackhand = 10429; + public const uint Gyth = 10339; + public const uint TheBeast = 10430; + public const uint GeneralDrakkisath = 10363; + public const uint BlackhandDreadweaver = 9817; + public const uint BlackhandSummoner = 9818; + public const uint BlackhandVeteran = 9819; + public const uint BlackhandIncarcerator = 10316; + public const uint LordVictorNefarius = 10162; + public const uint ScarshieldInfiltrator = 10299; + } + + struct GameObjectsIds + { + public const uint WhelpSpawner = 175622; // trap spawned by public const uint id 175124 + // Doors + public const uint EmberseerIn = 175244; // First door to Pyroguard Emberseer + public const uint Doors = 175705; // Second door to Pyroguard Emberseer + public const uint EmberseerOut = 175153; // Door after Pyroguard Emberseer event + public const uint GythEntryDoor = 164726; + public const uint GythCombatDoor = 175185; + public const uint GythExitDoor = 175186; + public const uint DrakkisathDoor1 = 175946; + public const uint DrakkisathDoor2 = 175947; + // Runes in drapublic const uint nspire hall + public const uint HallRune1 = 175197; + public const uint HallRune2 = 175199; + public const uint HallRune3 = 175195; + public const uint HallRune4 = 175200; + public const uint HallRune5 = 175198; + public const uint HallRune6 = 175196; + public const uint HallRune7 = 175194; + // Runes in emberseers room + public const uint EmberseerRune1 = 175266; + public const uint EmberseerRune2 = 175267; + public const uint EmberseerRune3 = 175268; + public const uint EmberseerRune4 = 175269; + public const uint EmberseerRune5 = 175270; + public const uint EmberseerRune6 = 175271; + public const uint EmberseerRune7 = 175272; + // For Gyth event + public const uint DrPortcullis = 175185; + public const uint PortcullisActive = 164726; + public const uint PortcullisTobossrooms = 175186; + } + + struct BRSMiscConst + { + public const uint SpellSummonRookeryWhelp = 15745; + public const uint EventUrokDoomhowl = 4845; + public const uint EventPyroguardEmberseer = 4884; + public const uint Areatrigger = 1; + public const uint AreatriggerDragonspireHall = 2046; + public const uint AreatriggerBlackrockStadium = 2026; + + public const uint EncounterCount = 23; + + //uint const DragonspireRunes[7] = { GoHallRune1, GoHallRune2, GoHallRune3, GoHallRune4, GoHallRune5, GoHallRune6, GoHallRune7 } + + public static uint[] DragonspireMobs = { CreaturesIds.BlackhandDreadweaver, CreaturesIds.BlackhandSummoner, CreaturesIds.BlackhandVeteran }; + + public static DoorData[] doorData = + { + new DoorData(GameObjectsIds.Doors, DataTypes.PyrogaurdEmberseer, DoorType.Passage), + new DoorData(GameObjectsIds.EmberseerOut, DataTypes.PyrogaurdEmberseer, DoorType.Passage), + new DoorData(GameObjectsIds.DrakkisathDoor1, DataTypes.GeneralDrakkisath, DoorType.Passage), + new DoorData(GameObjectsIds.DrakkisathDoor2, DataTypes.GeneralDrakkisath, DoorType.Passage), + new DoorData(GameObjectsIds.PortcullisActive, DataTypes.WarchiefRendBlackhand, DoorType.Passage), + new DoorData(GameObjectsIds.PortcullisTobossrooms, DataTypes.WarchiefRendBlackhand, DoorType.Passage), + }; + } + + struct EventIds + { + public const uint DargonspireRoomStore = 1; + public const uint DargonspireRoomCheck = 2; + public const uint UrokDoomhowlSpawns1 = 3; + public const uint UrokDoomhowlSpawns2 = 4; + public const uint UrokDoomhowlSpawns3 = 5; + public const uint UrokDoomhowlSpawns4 = 6; + public const uint UrokDoomhowlSpawns5 = 7; + public const uint UrokDoomhowlSpawnIn = 8; + } + + [Script] + class instance_blackrock_spire : InstanceMapScript + { + public instance_blackrock_spire() : base(nameof(instance_blackrock_spire), 229) { } + + class instance_blackrock_spireMapScript : InstanceScript + { + public instance_blackrock_spireMapScript(InstanceMap map) : base(map) + { + SetHeaders("BRS"); + SetBossNumber(BRSMiscConst.EncounterCount); + LoadDoorData(BRSMiscConst.doorData); + + for (byte i = 0; i < 7; ++i) + runecreaturelist[i] = new(); + } + + public override void OnCreatureCreate(Creature creature) + { + switch (creature.GetEntry()) + { + case CreaturesIds.HighlordOmokk: + HighlordOmokk = creature.GetGUID(); + break; + case CreaturesIds.ShadowHunterVoshgajin: + ShadowHunterVoshgajin = creature.GetGUID(); + break; + case CreaturesIds.WarmasterVoone: + WarMasterVoone = creature.GetGUID(); + break; + case CreaturesIds.MotherSmolderweb: + MotherSmolderweb = creature.GetGUID(); + break; + case CreaturesIds.UrokDoomhowl: + UrokDoomhowl = creature.GetGUID(); + break; + case CreaturesIds.QuartermasterZigris: + QuartermasterZigris = creature.GetGUID(); + break; + case CreaturesIds.GizrulTheSlavener: + GizrultheSlavener = creature.GetGUID(); + break; + case CreaturesIds.Halycon: + Halycon = creature.GetGUID(); + break; + case CreaturesIds.OverlordWyrmthalak: + OverlordWyrmthalak = creature.GetGUID(); + break; + case CreaturesIds.PyrogaurdEmberseer: + PyroguardEmberseer = creature.GetGUID(); + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.Done) + creature.DespawnOrUnsummon(TimeSpan.FromSeconds(0), TimeSpan.FromDays(7)); + break; + case CreaturesIds.WarchiefRendBlackhand: + WarchiefRendBlackhand = creature.GetGUID(); + if (GetBossState(DataTypes.Gyth) == EncounterState.Done) + creature.DespawnOrUnsummon(TimeSpan.FromSeconds(0), TimeSpan.FromDays(7)); + break; + case CreaturesIds.Gyth: + Gyth = creature.GetGUID(); + break; + case CreaturesIds.TheBeast: + TheBeast = creature.GetGUID(); + break; + case CreaturesIds.GeneralDrakkisath: + GeneralDrakkisath = creature.GetGUID(); + break; + case CreaturesIds.LordVictorNefarius: + LordVictorNefarius = creature.GetGUID(); + if (GetBossState(DataTypes.Gyth) == EncounterState.Done) + creature.DespawnOrUnsummon(TimeSpan.FromSeconds(0), TimeSpan.FromDays(7)); + break; + case CreaturesIds.ScarshieldInfiltrator: + ScarshieldInfiltrator = creature.GetGUID(); + break; + case CreaturesIds.BlackhandIncarcerator: + _incarceratorList.Add(creature.GetGUID()); + break; + } + } + + public override void OnGameObjectCreate(GameObject go) + { + base.OnGameObjectCreate(go); + + switch (go.GetEntry()) + { + case GameObjectsIds.WhelpSpawner: + go.CastSpell(null, BRSMiscConst.SpellSummonRookeryWhelp); + break; + case GameObjectsIds.EmberseerIn: + go_emberseerin = go.GetGUID(); + if (GetBossState(DataTypes.DragonspireRoom) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, true, go); + break; + case GameObjectsIds.Doors: + go_doors = go.GetGUID(); + if (GetBossState(DataTypes.DragonspireRoom) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, true, go); + break; + case GameObjectsIds.EmberseerOut: + go_emberseerout = go.GetGUID(); + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, true, go); + break; + case GameObjectsIds.HallRune1: + go_roomrunes[0] = go.GetGUID(); + if (GetBossState(DataTypes.HallRune1) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.HallRune2: + go_roomrunes[1] = go.GetGUID(); + if (GetBossState(DataTypes.HallRune2) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.HallRune3: + go_roomrunes[2] = go.GetGUID(); + if (GetBossState(DataTypes.HallRune3) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.HallRune4: + go_roomrunes[3] = go.GetGUID(); + if (GetBossState(DataTypes.HallRune4) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.HallRune5: + go_roomrunes[4] = go.GetGUID(); + if (GetBossState(DataTypes.HallRune5) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.HallRune6: + go_roomrunes[5] = go.GetGUID(); + if (GetBossState(DataTypes.HallRune6) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.HallRune7: + go_roomrunes[6] = go.GetGUID(); + if (GetBossState(DataTypes.HallRune7) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.EmberseerRune1: + go_emberseerrunes[0] = go.GetGUID(); + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.EmberseerRune2: + go_emberseerrunes[1] = go.GetGUID(); + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.EmberseerRune3: + go_emberseerrunes[2] = go.GetGUID(); + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.EmberseerRune4: + go_emberseerrunes[3] = go.GetGUID(); + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.EmberseerRune5: + go_emberseerrunes[4] = go.GetGUID(); + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.EmberseerRune6: + go_emberseerrunes[5] = go.GetGUID(); + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.EmberseerRune7: + go_emberseerrunes[6] = go.GetGUID(); + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, false, go); + break; + case GameObjectsIds.PortcullisActive: + go_portcullis_active = go.GetGUID(); + if (GetBossState(DataTypes.Gyth) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, true, go); + break; + case GameObjectsIds.PortcullisTobossrooms: + go_portcullis_tobossrooms = go.GetGUID(); + if (GetBossState(DataTypes.Gyth) == EncounterState.Done) + HandleGameObject(ObjectGuid.Empty, true, go); + break; + default: + break; + } + } + + public override bool SetBossState(uint type, EncounterState state) + { + if (!base.SetBossState(type, state)) + return false; + + switch (type) + { + case DataTypes.HighlordOmokk: + case DataTypes.ShadowHunterVoshgajin: + case DataTypes.WarmasterVoone: + case DataTypes.MotherSmolderweb: + case DataTypes.UrokDoomhowl: + case DataTypes.QuartermasterZigris: + case DataTypes.GizrulTheSlavener: + case DataTypes.Halycon: + case DataTypes.OverlordWyrmthalak: + case DataTypes.PyrogaurdEmberseer: + case DataTypes.WarchiefRendBlackhand: + case DataTypes.Gyth: + case DataTypes.TheBeast: + case DataTypes.GeneralDrakkisath: + case DataTypes.DragonspireRoom: + break; + default: + break; + } + + return true; + } + + public override void ProcessEvent(WorldObject obj, uint eventId, WorldObject invoker) + { + switch (eventId) + { + case BRSMiscConst.EventPyroguardEmberseer: + if (GetBossState(DataTypes.PyrogaurdEmberseer) == EncounterState.NotStarted) + { + Creature Emberseer = instance.GetCreature(PyroguardEmberseer); + if (Emberseer) + Emberseer.GetAI().SetData(1, 1); + } + break; + case BRSMiscConst.EventUrokDoomhowl: + if (GetBossState(CreaturesIds.UrokDoomhowl) == EncounterState.NotStarted) + { + + } + break; + default: + break; + } + } + + public override void SetData(uint type, uint data) + { + switch (type) + { + case BRSMiscConst.Areatrigger: + if (data == BRSMiscConst.AreatriggerDragonspireHall) + { + if (GetBossState(DataTypes.DragonspireRoom) != EncounterState.Done) + _events.ScheduleEvent(EventIds.DargonspireRoomStore, TimeSpan.FromSeconds(1)); + } + break; + case DataTypes.BlackhandIncarcerator: + foreach (var itr in _incarceratorList) + { + Creature creature = instance.GetCreature(itr); + if (creature) + creature.Respawn(); + } + break; + default: + break; + } + } + + public override ObjectGuid GetGuidData(uint type) + { + switch (type) + { + case DataTypes.HighlordOmokk: + return HighlordOmokk; + case DataTypes.ShadowHunterVoshgajin: + return ShadowHunterVoshgajin; + case DataTypes.WarmasterVoone: + return WarMasterVoone; + case DataTypes.MotherSmolderweb: + return MotherSmolderweb; + case DataTypes.UrokDoomhowl: + return UrokDoomhowl; + case DataTypes.QuartermasterZigris: + return QuartermasterZigris; + case DataTypes.GizrulTheSlavener: + return GizrultheSlavener; + case DataTypes.Halycon: + return Halycon; + case DataTypes.OverlordWyrmthalak: + return OverlordWyrmthalak; + case DataTypes.PyrogaurdEmberseer: + return PyroguardEmberseer; + case DataTypes.WarchiefRendBlackhand: + return WarchiefRendBlackhand; + case DataTypes.Gyth: + return Gyth; + case DataTypes.TheBeast: + return TheBeast; + case DataTypes.GeneralDrakkisath: + return GeneralDrakkisath; + case DataTypes.ScarshieldInfiltrator: + return ScarshieldInfiltrator; + case GameObjectsIds.EmberseerIn: + return go_emberseerin; + case GameObjectsIds.Doors: + return go_doors; + case GameObjectsIds.EmberseerOut: + return go_emberseerout; + case GameObjectsIds.HallRune1: + return go_roomrunes[0]; + case GameObjectsIds.HallRune2: + return go_roomrunes[1]; + case GameObjectsIds.HallRune3: + return go_roomrunes[2]; + case GameObjectsIds.HallRune4: + return go_roomrunes[3]; + case GameObjectsIds.HallRune5: + return go_roomrunes[4]; + case GameObjectsIds.HallRune6: + return go_roomrunes[5]; + case GameObjectsIds.HallRune7: + return go_roomrunes[6]; + case GameObjectsIds.EmberseerRune1: + return go_emberseerrunes[0]; + case GameObjectsIds.EmberseerRune2: + return go_emberseerrunes[1]; + case GameObjectsIds.EmberseerRune3: + return go_emberseerrunes[2]; + case GameObjectsIds.EmberseerRune4: + return go_emberseerrunes[3]; + case GameObjectsIds.EmberseerRune5: + return go_emberseerrunes[4]; + case GameObjectsIds.EmberseerRune6: + return go_emberseerrunes[5]; + case GameObjectsIds.EmberseerRune7: + return go_emberseerrunes[6]; + case GameObjectsIds.PortcullisActive: + return go_portcullis_active; + case GameObjectsIds.PortcullisTobossrooms: + return go_portcullis_tobossrooms; + default: + break; + } + return ObjectGuid.Empty; + } + + public override void Update(uint diff) + { + _events.Update(diff); + + _events.ExecuteEvents(eventId => + { + switch (eventId) + { + case EventIds.DargonspireRoomStore: + Dragonspireroomstore(); + _events.ScheduleEvent(EventIds.DargonspireRoomCheck, TimeSpan.FromSeconds(3)); + break; + case EventIds.DargonspireRoomCheck: + Dragonspireroomcheck(); + if (GetBossState(DataTypes.DragonspireRoom) != EncounterState.Done) + _events.ScheduleEvent(EventIds.DargonspireRoomCheck, TimeSpan.FromSeconds(3)); + break; + default: + break; + } + }); + } + + void Dragonspireroomstore() + { + for (byte i = 0; i < 7; ++i) + { + // Refresh the creature list + runecreaturelist[i].Clear(); + + GameObject rune = instance.GetGameObject(go_roomrunes[i]); + if (rune) + { + for (byte j = 0; j < 3; ++j) + { + List creatureList = rune.GetCreatureListWithEntryInGrid(BRSMiscConst.DragonspireMobs[j], 15.0f); + foreach (var creature in creatureList) + if (creature) + runecreaturelist[i].Add(creature.GetGUID()); + } + } + } + } + + void Dragonspireroomcheck() + { + Creature mob = null; + GameObject rune = null; + + for (byte i = 0; i < 7; ++i) + { + bool _mobAlive = false; + rune = instance.GetGameObject(go_roomrunes[i]); + if (!rune) + continue; + + if (rune.GetGoState() == GameObjectState.Active) + { + foreach (ObjectGuid guid in runecreaturelist[i]) + { + mob = instance.GetCreature(guid); + if (mob && mob.IsAlive()) + _mobAlive = true; + } + } + + if (!_mobAlive && rune.GetGoState() == GameObjectState.Active) + { + HandleGameObject(ObjectGuid.Empty, false, rune); + + switch (rune.GetEntry()) + { + case GameObjectsIds.HallRune1: + SetBossState(DataTypes.HallRune1, EncounterState.Done); + break; + case GameObjectsIds.HallRune2: + SetBossState(DataTypes.HallRune2, EncounterState.Done); + break; + case GameObjectsIds.HallRune3: + SetBossState(DataTypes.HallRune3, EncounterState.Done); + break; + case GameObjectsIds.HallRune4: + SetBossState(DataTypes.HallRune4, EncounterState.Done); + break; + case GameObjectsIds.HallRune5: + SetBossState(DataTypes.HallRune5, EncounterState.Done); + break; + case GameObjectsIds.HallRune6: + SetBossState(DataTypes.HallRune6, EncounterState.Done); + break; + case GameObjectsIds.HallRune7: + SetBossState(DataTypes.HallRune7, EncounterState.Done); + break; + default: + break; + } + } + } + + if (GetBossState(DataTypes.HallRune1) == EncounterState.Done && GetBossState(DataTypes.HallRune2) == EncounterState.Done && GetBossState(DataTypes.HallRune3) == EncounterState.Done && + GetBossState(DataTypes.HallRune4) == EncounterState.Done && GetBossState(DataTypes.HallRune5) == EncounterState.Done && GetBossState(DataTypes.HallRune6) == EncounterState.Done && + GetBossState(DataTypes.HallRune7) == EncounterState.Done) + { + SetBossState(DataTypes.DragonspireRoom, EncounterState.Done); + GameObject door1 = instance.GetGameObject(go_emberseerin); + if (door1) + HandleGameObject(ObjectGuid.Empty, true, door1); + GameObject door2 = instance.GetGameObject(go_doors); + if (door2) + HandleGameObject(ObjectGuid.Empty, true, door2); + } + } + + ObjectGuid HighlordOmokk; + ObjectGuid ShadowHunterVoshgajin; + ObjectGuid WarMasterVoone; + ObjectGuid MotherSmolderweb; + ObjectGuid UrokDoomhowl; + ObjectGuid QuartermasterZigris; + ObjectGuid GizrultheSlavener; + ObjectGuid Halycon; + ObjectGuid OverlordWyrmthalak; + ObjectGuid PyroguardEmberseer; + ObjectGuid WarchiefRendBlackhand; + ObjectGuid Gyth; + ObjectGuid LordVictorNefarius; + ObjectGuid TheBeast; + ObjectGuid GeneralDrakkisath; + ObjectGuid ScarshieldInfiltrator; + ObjectGuid go_emberseerin; + ObjectGuid go_doors; + ObjectGuid go_emberseerout; + ObjectGuid go_blackrockaltar; + ObjectGuid[] go_roomrunes = new ObjectGuid[7]; + ObjectGuid[] go_emberseerrunes = new ObjectGuid[7]; + List[] runecreaturelist = new List[7]; + ObjectGuid go_portcullis_active; + ObjectGuid go_portcullis_tobossrooms; + List _incarceratorList = new(); + } + + public override InstanceScript GetInstanceScript(InstanceMap map) + { + return new instance_blackrock_spireMapScript(map); + } + } + + [Script] + class at_dragonspire_hall : AreaTriggerScript + { + public at_dragonspire_hall() : base("at_dragonspire_hall") { } + + public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger) + { + if (player && player.IsAlive()) + { + InstanceScript instance = player.GetInstanceScript(); + if (instance != null) + { + instance.SetData(BRSMiscConst.Areatrigger, BRSMiscConst.AreatriggerDragonspireHall); + return true; + } + } + + return false; + } + } + + [Script] + class at_blackrock_stadium : AreaTriggerScript + { + public at_blackrock_stadium() : base("at_blackrock_stadium") { } + + public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger) + { + if (player && player.IsAlive()) + { + InstanceScript instance = player.GetInstanceScript(); + if (instance == null) + return false; + + Creature rend = player.FindNearestCreature(CreaturesIds.WarchiefRendBlackhand, 50.0f); + if (rend) + { + rend.GetAI().SetData(BRSMiscConst.Areatrigger, BRSMiscConst.AreatriggerBlackrockStadium); + return true; + } + } + + return false; + } + } + + [Script] + class at_nearby_scarshield_infiltrator : AreaTriggerScript + { + public at_nearby_scarshield_infiltrator() : base("at_nearby_scarshield_infiltrator") { } + + public override bool OnTrigger(Player player, AreaTriggerRecord at) + { + if (player.IsAlive()) + { + InstanceScript instance = player.GetInstanceScript(); + if (instance != null) + { + Creature infiltrator = ObjectAccessor.GetCreature(player, instance.GetGuidData(DataTypes.ScarshieldInfiltrator)); + if (infiltrator) + { + if (player.GetLevel() >= 57) + infiltrator.GetAI().SetData(1, 1); + else if (infiltrator.GetEntry() == CreaturesIds.ScarshieldInfiltrator) + infiltrator.GetAI().Talk(0, player); + + return true; + } + } + } + + return false; + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/LordValthalak.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/LordValthalak.cs new file mode 100644 index 000000000..23a470467 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/LordValthalak.cs @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire +{ + struct SpellIds + { + public const uint Frenzy = 8269; + public const uint SummonSpectralAssassin = 27249; + public const uint ShadowBoltVolley = 27382; + public const uint ShadowWrath = 27286; + } + + [Script] + class boss_lord_valthalak : BossAI + { + bool frenzy40; + bool frenzy15; + + public boss_lord_valthalak(Creature creature) : base(creature, DataTypes.LordValthalak) + { + Initialize(); + } + + void Initialize() + { + frenzy40 = false; + frenzy15 = false; + } + + public override void Reset() + { + _Reset(); + Initialize(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(8), 1, task => + { + DoCast(me, SpellIds.SummonSpectralAssassin); + task.Repeat(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(9), TimeSpan.FromSeconds(18), task => + { + DoCastVictim(SpellIds.ShadowWrath); + task.Repeat(TimeSpan.FromSeconds(19), TimeSpan.FromSeconds(24)); + }); + } + + public override void JustDied(Unit killer) + { + instance.SetBossState(DataTypes.LordValthalak, EncounterState.Done); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff); + + if (me.HasUnitState(UnitState.Casting)) + return; + + if (!frenzy40) + { + if (HealthBelowPct(40)) + { + DoCast(me, SpellIds.Frenzy); + _scheduler.CancelGroup(1); + frenzy40 = true; + } + } + + if (!frenzy15) + { + if (HealthBelowPct(15)) + { + DoCast(me, SpellIds.Frenzy); + _scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(14), task => + { + DoCastVictim(SpellIds.ShadowBoltVolley); + task.Repeat(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(6)); + }); + frenzy15 = true; + } + } + + DoMeleeAttackIfReady(); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/MotherSmolderweb.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/MotherSmolderweb.cs new file mode 100644 index 000000000..ecd66917d --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/MotherSmolderweb.cs @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using Game.Spells; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.MotherSmolderweb +{ + struct SpellIds + { + public const uint Crystalize = 16104; + public const uint Mothersmilk = 16468; + public const uint SummonSpireSpiderling = 16103; + } + + [Script] + class boss_mother_smolderweb : BossAI + { + public boss_mother_smolderweb(Creature creature) : base(creature, DataTypes.MotherSmolderweb) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + _scheduler.Schedule(TimeSpan.FromSeconds(20), task => + { + DoCast(me, SpellIds.Crystalize); + task.Repeat(TimeSpan.FromSeconds(15)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(10), task => + { + DoCast(me, SpellIds.Mothersmilk); + task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromMilliseconds(12500)); + }); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void DamageTaken(Unit done_by, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null) + { + if (me.GetHealth() <= damage) + DoCast(me, SpellIds.SummonSpireSpiderling, new CastSpellExtraArgs(true)); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/OverlordWyrmthalak.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/OverlordWyrmthalak.cs new file mode 100644 index 000000000..efdc3cf07 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/OverlordWyrmthalak.cs @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.OverlordWyrmthalak +{ + struct SpellIds + { + public const uint Blastwave = 11130; + public const uint Shout = 23511; + public const uint Cleave = 20691; + public const uint Knockaway = 20686; + } + + struct MiscConst + { + public const uint NpcSpirestoneWarlord = 9216; + public const uint NpcSmolderthornBerserker = 9268; + + public static Position SummonLocation1 = new Position(-39.355f, -513.456f, 88.472f, 4.679f); + public static Position SummonLocation2 = new Position(-49.875f, -511.896f, 88.195f, 4.613f); + } + + [Script] + class boss_overlord_wyrmthalak : BossAI + { + bool Summoned; + + public boss_overlord_wyrmthalak(Creature creature) : base(creature, DataTypes.OverlordWyrmthalak) + { + Initialize(); + } + + void Initialize() + { + Summoned = false; + } + + public override void Reset() + { + _Reset(); + Initialize(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(20), task => + { + DoCastVictim(SpellIds.Blastwave); + task.Repeat(TimeSpan.FromSeconds(20)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(2), task => + { + DoCastVictim(SpellIds.Shout); + task.Repeat(TimeSpan.FromSeconds(10)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(6), task => + { + DoCastVictim(SpellIds.Cleave); + task.Repeat(TimeSpan.FromSeconds(7)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(12), task => + { + DoCastVictim(SpellIds.Knockaway); + task.Repeat(TimeSpan.FromSeconds(14)); + }); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + if (!Summoned && HealthBelowPct(51)) + { + Unit target = SelectTarget(SelectTargetMethod.Random, 0, 100, true); + if (target) + { + Creature warlord = me.SummonCreature(MiscConst.NpcSpirestoneWarlord, MiscConst.SummonLocation1, TempSummonType.TimedDespawn, TimeSpan.FromMinutes(5)); + if (warlord) + warlord.GetAI().AttackStart(target); + Creature berserker = me.SummonCreature(MiscConst.NpcSmolderthornBerserker, MiscConst.SummonLocation2, TempSummonType.TimedDespawn, TimeSpan.FromMinutes(5)); + if (berserker) + berserker.GetAI().AttackStart(target); + Summoned = true; + } + } + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/PyroguardEmberseer.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/PyroguardEmberseer.cs new file mode 100644 index 000000000..9c1c25435 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/PyroguardEmberseer.cs @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using Game.Spells; +using System; +using System.Collections.Generic; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.PyroguardEmberseer +{ + struct SpellIds + { + public const uint EncagedEmberseer = 15282; // Self on spawn + public const uint FireShieldTrigger = 13377; // Self on spawn missing from 335 dbc triggers public const uint FireShield every 3 sec + public const uint FireShield = 13376; // Triggered by public const uint FireShieldTrigger + public const uint FreezeAnim = 16245; // Self on event start + public const uint EmberseerGrowing = 16048; // Self on event start + public const uint EmberseerGrowingTrigger = 16049; // Triggered by public const uint EmberseerGrowing + public const uint EmberseerFullStrength = 16047; // Emberseer Full Strength + public const uint Firenova = 23462; // Combat + public const uint Flamebuffet = 23341; // Combat + public const uint Pyroblast = 17274; // Combat + // Blackhand Incarcerator public const uint s + public const uint EncageEmberseer = 15281; // Emberseer on spawn + public const uint Strike = 15580; // Combat + public const uint Encage = 16045; // Combat + // Cast on player by altar + public const uint EmberseerObjectVisual = 16532; + } + + struct TextIds + { + public const uint EmoteOneStack = 0; + public const uint EmoteTenStack = 1; + public const uint EmoteFreeOfBonds = 2; + public const uint YellFreeOfBonds = 3; + } + + [Script] + class boss_pyroguard_emberseer : BossAI + { + public boss_pyroguard_emberseer(Creature creature) : base(creature, DataTypes.PyrogaurdEmberseer) { } + + public override void Reset() + { + me.SetUnitFlag(UnitFlags.Uninteractible); + me.SetImmuneToPC(true); + _scheduler.CancelAll(); + // Apply auras on spawn and reset + // DoCast(me, SpellFireShieldTrigger); // Need to find this in old Dbc if possible + me.RemoveAura(SpellIds.EmberseerFullStrength); + me.RemoveAura(SpellIds.EmberseerGrowing); + me.RemoveAura(SpellIds.EmberseerGrowingTrigger); + + _scheduler.Schedule(TimeSpan.FromSeconds(5), task => + { + instance.SetData(DataTypes.BlackhandIncarcerator, 1); + instance.SetBossState(DataTypes.PyrogaurdEmberseer, EncounterState.NotStarted); + }); + // Hack for missing trigger spell + _scheduler.Schedule(TimeSpan.FromSeconds(3), task => + { + // #### Spell isn't doing any damage ??? #### + DoCast(me, SpellIds.FireShield); + task.Repeat(TimeSpan.FromSeconds(3)); + }); + } + + public override void SetData(uint type, uint data) + { + switch (data) + { + case 1: + _scheduler.Schedule(TimeSpan.FromSeconds(5), task => + { + // As of Patch 3.0.8 only one person needs to channel the altar + bool _hasAura = false; + var players = me.GetMap().GetPlayers(); + foreach (var player in players) + { + if (player != null && player.HasAura(SpellIds.EmberseerObjectVisual)) + { + _hasAura = true; + break; + } + } + + if (_hasAura) + { + task.Schedule(TimeSpan.FromSeconds(1), preFlightTask1 => + { + // Set data on all Blackhand Incarcerators + List creatureList = me.GetCreatureListWithEntryInGrid(CreaturesIds.BlackhandIncarcerator, 35.0f); + foreach (var creature in creatureList) + { + if (creature) + { + creature.SetImmuneToAll(false); + creature.InterruptSpell(CurrentSpellTypes.Channeled); + DoZoneInCombat(creature); + } + } + me.RemoveAura(SpellIds.EncagedEmberseer); + preFlightTask1.Schedule(TimeSpan.FromSeconds(32), preFlightTask2 => + { + me.CastSpell(me, SpellIds.FreezeAnim); + me.CastSpell(me, SpellIds.EmberseerGrowing); + Talk(TextIds.EmoteOneStack); + }); + }); + instance.SetBossState(DataTypes.PyrogaurdEmberseer, EncounterState.InProgress); + } + }); + break; + default: + break; + } + } + + public override void JustEngagedWith(Unit who) + { + // ### Todo Check combat timing ### + _scheduler.Schedule(TimeSpan.FromSeconds(6), task => + { + DoCast(me, SpellIds.Firenova); + task.Repeat(TimeSpan.FromSeconds(6)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(3), task => + { + DoCast(me, SpellIds.Flamebuffet); + task.Repeat(TimeSpan.FromSeconds(14)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(14), task => + { + Unit target = SelectTarget(SelectTargetMethod.Random, 0, 100, true); + if (target) + DoCast(target, SpellIds.Pyroblast); + task.Repeat(TimeSpan.FromSeconds(15)); + }); + } + + public override void JustDied(Unit killer) + { + // Activate all the runes + UpdateRunes(GameObjectState.Ready); + // Complete encounter + instance.SetBossState(DataTypes.PyrogaurdEmberseer, EncounterState.Done); + } + + public override void SpellHit(WorldObject caster, SpellInfo spellInfo) + { + if (spellInfo.Id == SpellIds.EncageEmberseer) + { + if (me.GetAuraCount(SpellIds.EncagedEmberseer) == 0) + { + me.CastSpell(me, SpellIds.EncagedEmberseer); + Reset(); + } + } + + if (spellInfo.Id == SpellIds.EmberseerGrowingTrigger) + { + if (me.GetAuraCount(SpellIds.EmberseerGrowingTrigger) == 10) + Talk(TextIds.EmoteTenStack); + + if (me.GetAuraCount(SpellIds.EmberseerGrowingTrigger) == 20) + { + me.RemoveAura(SpellIds.FreezeAnim); + me.CastSpell(me, SpellIds.EmberseerFullStrength); + Talk(TextIds.EmoteFreeOfBonds); + Talk(TextIds.YellFreeOfBonds); + me.RemoveUnitFlag(UnitFlags.Uninteractible); + me.SetImmuneToPC(false); + _scheduler.Schedule(TimeSpan.FromSeconds(2), task => + { + AttackStart(me.SelectNearestPlayer(30.0f)); + }); + } + } + } + + void UpdateRunes(GameObjectState state) + { + // update all runes + GameObject rune1 = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GameObjectsIds.EmberseerRune1)); + if (rune1) + rune1.SetGoState(state); + GameObject rune2 = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GameObjectsIds.EmberseerRune2)); + if (rune2) + rune2.SetGoState(state); + GameObject rune3 = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GameObjectsIds.EmberseerRune3)); + if (rune3) + rune3.SetGoState(state); + GameObject rune4 = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GameObjectsIds.EmberseerRune4)); + if (rune4) + rune4.SetGoState(state); + GameObject rune5 = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GameObjectsIds.EmberseerRune5)); + if (rune5) + rune5.SetGoState(state); + GameObject rune6 = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GameObjectsIds.EmberseerRune6)); + if (rune6) + rune6.SetGoState(state); + GameObject rune7 = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GameObjectsIds.EmberseerRune7)); + if (rune7) + rune7.SetGoState(state); + } + + public override void UpdateAI(uint diff) + { + _scheduler.Update(diff); + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + } + + [Script] + class npc_blackhand_incarcerator : ScriptedAI + { + public npc_blackhand_incarcerator(Creature creature) : base(creature) { } + + public override void JustAppeared() + { + DoCast(SpellIds.EncageEmberseer); + } + + public override void JustEngagedWith(Unit who) + { + // Had to do this because CallForHelp will ignore any npcs without Los + List creatureList = me.GetCreatureListWithEntryInGrid(CreaturesIds.BlackhandIncarcerator, 60.0f); + foreach (var creature in creatureList) + if (creature) + DoZoneInCombat(creature); // GetAI().AttackStart(me.GetVictim()); + + _scheduler.Schedule(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(16), task => + { + DoCastVictim(SpellIds.Strike, new CastSpellExtraArgs(true)); + task.Repeat(TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(23)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20), task => + { + DoCast(SelectTarget(SelectTargetMethod.Random, 0, 100, true), SpellIds.Encage, new CastSpellExtraArgs(true)); + task.Repeat(TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(12)); + }); + } + + public override void JustReachedHome() + { + DoCast(SpellIds.EncageEmberseer); + + me.SetImmuneToAll(true); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/QuartermasterZigris.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/QuartermasterZigris.cs new file mode 100644 index 000000000..605a1e274 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/QuartermasterZigris.cs @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.QuartermasterZigris +{ + struct SpellIds + { + public const uint Shoot = 16496; + public const uint Stunbomb = 16497; + public const uint HealingPotion = 15504; + public const uint Hookednet = 15609; + } + + [Script] + class quartermaster_zigris : BossAI + { + public quartermaster_zigris(Creature creature) : base(creature, DataTypes.QuartermasterZigris) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(1), task => + { + DoCastVictim(SpellIds.Shoot); + task.Repeat(TimeSpan.FromMilliseconds(500)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(16), task => + { + DoCastVictim(SpellIds.Stunbomb); + task.Repeat(TimeSpan.FromSeconds(14)); + }); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/RendBlackhand.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/RendBlackhand.cs new file mode 100644 index 000000000..43e758b49 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/RendBlackhand.cs @@ -0,0 +1,523 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Framework.Constants; +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.RendBlackhand +{ + struct SpellIds + { + public const uint Whirlwind = 13736; // sniffed + public const uint Cleave = 15284; + public const uint MortalStrike = 16856; + public const uint Frenzy = 8269; + public const uint Knockdown = 13360; // On spawn during Gyth fight + } + + struct TextIds + { + // Rend Blackhand + public const uint SayBlackhand1 = 0; + public const uint SayBlackhand2 = 1; + public const uint EmoteBlackhandDismount = 2; + // Victor Nefarius + public const uint SayNefarius0 = 0; + public const uint SayNefarius1 = 1; + public const uint SayNefarius2 = 2; + public const uint SayNefarius3 = 3; + public const uint SayNefarius4 = 4; + public const uint SayNefarius5 = 5; + public const uint SayNefarius6 = 6; + public const uint SayNefarius7 = 7; + public const uint SayNefarius8 = 8; + public const uint SayNefarius9 = 9; + } + + struct AddIds + { + public const uint ChromaticWhelp = 10442; + public const uint ChromaticDragonspawn = 10447; + public const uint BlackhandDragonHandler = 10742; + } + + struct MiscConst + { + public const uint NefariusPath1 = 1379670; + public const uint NefariusPath2 = 1379671; + public const uint NefariusPath3 = 1379672; + public const uint RendPath1 = 1379680; + public const uint RendPath2 = 1379681; + + public static Wave[] Wave2 = // 22 sec + { + new Wave(10447, 209.8637f, -428.2729f, 110.9877f, 0.6632251f), + new Wave(10442, 209.3122f, -430.8724f, 110.9814f, 2.9147f), + new Wave(10442, 211.3309f, -425.9111f, 111.0006f, 1.727876f) + }; + + public static Wave[] Wave3 = // 60 sec + { + new Wave(10742, 208.6493f, -424.5787f, 110.9872f, 5.8294f), + new Wave(10447, 203.9482f, -428.9446f, 110.982f, 4.677482f), + new Wave(10442, 203.3441f, -426.8668f, 110.9772f, 4.712389f), + new Wave(10442, 206.3079f, -424.7509f, 110.9943f, 4.08407f) + }; + + public static Wave[] Wave4 = // 49 sec + { + new Wave(10742, 212.3541f, -412.6826f, 111.0352f, 5.88176f), + new Wave(10447, 212.5754f, -410.2841f, 111.0296f, 2.740167f), + new Wave(10442, 212.3449f, -414.8659f, 111.0348f, 2.356194f), + new Wave(10442, 210.6568f, -412.1552f, 111.0124f, 0.9773844f) + }; + + public static Wave[] Wave5 = // 60 sec + { + new Wave(10742, 210.2188f, -410.6686f, 111.0211f, 5.8294f), + new Wave(10447, 209.4078f, -414.13f, 111.0264f, 4.677482f), + new Wave(10442, 208.0858f, -409.3145f, 111.0118f, 4.642576f), + new Wave(10442, 207.9811f, -413.0728f, 111.0098f, 5.288348f), + new Wave(10442, 208.0854f, -412.1505f, 111.0057f, 4.08407f) + }; + + public static Wave[] Wave6 = // 27 sec + { + new Wave(10742, 213.9138f, -426.512f, 111.0013f, 3.316126f), + new Wave(10447, 213.7121f, -429.8102f, 110.9888f, 1.413717f), + new Wave(10447, 213.7157f, -424.4268f, 111.009f, 3.001966f), + new Wave(10442, 210.8935f, -423.913f, 111.0125f, 5.969026f), + new Wave(10442, 212.2642f, -430.7648f, 110.9807f, 5.934119f) + }; + + public static Position GythLoc = new Position(211.762f, -397.5885f, 111.1817f, 4.747295f); + public static Position Teleport1Loc = new Position(194.2993f, -474.0814f, 121.4505f, -0.01225555f); + public static Position Teleport2Loc = new Position(216.485f, -434.93f, 110.888f, -0.01225555f); + } + + class Wave + { + public uint entry; + public float x_pos; + public float y_pos; + public float z_pos; + public float o_pos; + + public Wave(uint _entry, float x, float y, float z, float o) + { + entry = _entry; + x_pos = x; + y_pos = y; + z_pos = z; + o_pos = o; + } + } + + struct EventIds + { + public const uint Start1 = 1; + public const uint Start2 = 2; + public const uint Start3 = 3; + public const uint Start4 = 4; + public const uint TurnToRend = 5; + public const uint TurnToPlayer = 6; + public const uint TurnToFacing1 = 7; + public const uint TurnToFacing2 = 8; + public const uint TurnToFacing3 = 9; + public const uint Wave1 = 10; + public const uint Wave2 = 11; + public const uint Wave3 = 12; + public const uint Wave4 = 13; + public const uint Wave5 = 14; + public const uint Wave6 = 15; + public const uint WavesText1 = 16; + public const uint WavesText2 = 17; + public const uint WavesText3 = 18; + public const uint WavesText4 = 19; + public const uint WavesText5 = 20; + public const uint WavesCompleteText1 = 21; + public const uint WavesCompleteText2 = 22; + public const uint WavesCompleteText3 = 23; + public const uint WavesEmote1 = 24; + public const uint WavesEmote2 = 25; + public const uint PathRend = 26; + public const uint PathNefarius = 27; + public const uint Teleport1 = 28; + public const uint Teleport2 = 29; + public const uint Whirlwind = 30; + public const uint Cleave = 31; + public const uint MortalStrike = 32; + } + + [Script] + class boss_rend_blackhand : BossAI + { + bool gythEvent; + ObjectGuid victorGUID; + ObjectGuid portcullisGUID; + + public boss_rend_blackhand(Creature creature) : base(creature, DataTypes.WarchiefRendBlackhand) { } + + public override void Reset() + { + _Reset(); + gythEvent = false; + victorGUID.Clear(); + portcullisGUID.Clear(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + _events.ScheduleEvent(EventIds.Whirlwind, TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(15)); + _events.ScheduleEvent(EventIds.Cleave, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(17)); + _events.ScheduleEvent(EventIds.MortalStrike, TimeSpan.FromSeconds(17), TimeSpan.FromSeconds(19)); + } + + public override void IsSummonedBy(WorldObject summoner) + { + me.SetImmuneToPC(false); + DoZoneInCombat(); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + Creature victor = me.FindNearestCreature(CreaturesIds.LordVictorNefarius, 75.0f, true); + if (victor != null) + victor.GetAI().SetData(1, 2); + } + + public override void SetData(uint type, uint data) + { + if (type == BRSMiscConst.Areatrigger && data == BRSMiscConst.AreatriggerBlackrockStadium) + { + if (!gythEvent) + { + gythEvent = true; + + Creature victor = me.FindNearestCreature(CreaturesIds.LordVictorNefarius, 5.0f, true); + if (victor != null) + victorGUID = victor.GetGUID(); + + GameObject portcullis = me.FindNearestGameObject(GameObjectsIds.DrPortcullis, 50.0f); + if (portcullis != null) + portcullisGUID = portcullis.GetGUID(); + + _events.ScheduleEvent(EventIds.TurnToPlayer, TimeSpan.FromSeconds(0)); + _events.ScheduleEvent(EventIds.Start1, TimeSpan.FromSeconds(1)); + } + } + } + + public override void MovementInform(MovementGeneratorType type, uint id) + { + if (type == MovementGeneratorType.Waypoint) + { + switch (id) + { + case 5: + _events.ScheduleEvent(EventIds.Teleport1, TimeSpan.FromSeconds(2)); + break; + case 11: + Creature gyth = me.FindNearestCreature(CreaturesIds.Gyth, 10.0f, true); + if (gyth) + gyth.GetAI().SetData(1, 1); + me.DespawnOrUnsummon(TimeSpan.FromSeconds(1), TimeSpan.FromDays(7)); + break; + } + } + } + + public override void UpdateAI(uint diff) + { + if (gythEvent) + { + _events.Update(diff); + + _events.ExecuteEvents(eventId => + { + switch (eventId) + { + case EventIds.Start1: + { + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetAI().Talk(TextIds.SayNefarius0); + _events.ScheduleEvent(EventIds.Start2, TimeSpan.FromSeconds(4)); + break; + } + case EventIds.Start2: + { + _events.ScheduleEvent(EventIds.TurnToPlayer, TimeSpan.FromSeconds(0)); + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.HandleEmoteCommand(Emote.OneshotPoint); + _events.ScheduleEvent(EventIds.Start3, TimeSpan.FromSeconds(4)); + break; + } + case EventIds.Start3: + { + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetAI().Talk(TextIds.SayNefarius1); + _events.ScheduleEvent(EventIds.Wave1, TimeSpan.FromSeconds(2)); + _events.ScheduleEvent(EventIds.TurnToRend, TimeSpan.FromSeconds(4)); + _events.ScheduleEvent(EventIds.WavesText1, TimeSpan.FromSeconds(20)); + break; + } + case EventIds.TurnToRend: + { + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + { + victor.SetFacingToObject(me); + victor.HandleEmoteCommand(Emote.OneshotTalk); + } + break; + } + case EventIds.TurnToPlayer: + { + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + { + Unit player = victor.SelectNearestPlayer(60.0f); + if (player != null) + victor.SetFacingToObject(player); + } + break; + } + case EventIds.TurnToFacing1: + { + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.SetFacingTo(1.518436f); + break; + } + case EventIds.TurnToFacing2: + me.SetFacingTo(1.658063f); + break; + case EventIds.TurnToFacing3: + me.SetFacingTo(1.500983f); + break; + case EventIds.WavesEmote1: + { + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.HandleEmoteCommand(Emote.OneshotQuestion); + break; + } + case EventIds.WavesEmote2: + me.HandleEmoteCommand(Emote.OneshotRoar); + break; + case EventIds.WavesText1: + { + _events.ScheduleEvent(EventIds.TurnToPlayer, TimeSpan.FromSeconds(0)); + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetAI().Talk(TextIds.SayNefarius2); + me.HandleEmoteCommand(Emote.OneshotTalk); + _events.ScheduleEvent(EventIds.TurnToFacing1, TimeSpan.FromSeconds(4)); + _events.ScheduleEvent(EventIds.WavesEmote1, TimeSpan.FromSeconds(5)); + _events.ScheduleEvent(EventIds.Wave2, TimeSpan.FromSeconds(2)); + _events.ScheduleEvent(EventIds.WavesText2, TimeSpan.FromSeconds(20)); + break; + } + case EventIds.WavesText2: + { + _events.ScheduleEvent(EventIds.TurnToPlayer, TimeSpan.FromSeconds(0)); + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetAI().Talk(TextIds.SayNefarius3); + _events.ScheduleEvent(EventIds.TurnToFacing1, TimeSpan.FromSeconds(4)); + _events.ScheduleEvent(EventIds.Wave3, TimeSpan.FromSeconds(2)); + _events.ScheduleEvent(EventIds.WavesText3, TimeSpan.FromSeconds(20)); + break; + } + case EventIds.WavesText3: + { + _events.ScheduleEvent(EventIds.TurnToPlayer, TimeSpan.FromSeconds(0)); + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetAI().Talk(TextIds.SayNefarius4); + _events.ScheduleEvent(EventIds.TurnToFacing1, TimeSpan.FromSeconds(4)); + _events.ScheduleEvent(EventIds.Wave4, TimeSpan.FromSeconds(2)); + _events.ScheduleEvent(EventIds.WavesText4, TimeSpan.FromSeconds(20)); + break; + } + case EventIds.WavesText4: + Talk(TextIds.SayBlackhand1); + _events.ScheduleEvent(EventIds.WavesEmote2, TimeSpan.FromSeconds(4)); + _events.ScheduleEvent(EventIds.TurnToFacing3, TimeSpan.FromSeconds(8)); + _events.ScheduleEvent(EventIds.Wave5, TimeSpan.FromSeconds(2)); + _events.ScheduleEvent(EventIds.WavesText5, TimeSpan.FromSeconds(20)); + break; + case EventIds.WavesText5: + { + _events.ScheduleEvent(EventIds.TurnToPlayer, TimeSpan.FromSeconds(0)); + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetAI().Talk(TextIds.SayNefarius5); + _events.ScheduleEvent(EventIds.TurnToFacing1, TimeSpan.FromSeconds(4)); + _events.ScheduleEvent(EventIds.Wave6, TimeSpan.FromSeconds(2)); + _events.ScheduleEvent(EventIds.WavesCompleteText1, TimeSpan.FromSeconds(20)); + break; + } + case EventIds.WavesCompleteText1: + { + _events.ScheduleEvent(EventIds.TurnToPlayer, TimeSpan.FromSeconds(0)); + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetAI().Talk(TextIds.SayNefarius6); + _events.ScheduleEvent(EventIds.TurnToFacing1, TimeSpan.FromSeconds(4)); + _events.ScheduleEvent(EventIds.WavesCompleteText2, TimeSpan.FromSeconds(13)); + break; + } + case EventIds.WavesCompleteText2: + { + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetAI().Talk(TextIds.SayNefarius7); + Talk(TextIds.SayBlackhand2); + _events.ScheduleEvent(EventIds.PathRend, TimeSpan.FromSeconds(1)); + _events.ScheduleEvent(EventIds.WavesCompleteText3, TimeSpan.FromSeconds(4)); + break; + } + case EventIds.WavesCompleteText3: + { + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetAI().Talk(TextIds.SayNefarius8); + _events.ScheduleEvent(EventIds.PathNefarius, TimeSpan.FromSeconds(1)); + _events.ScheduleEvent(EventIds.PathRend, TimeSpan.FromSeconds(1)); + break; + } + case EventIds.PathNefarius: + { + Creature victor = ObjectAccessor.GetCreature(me, victorGUID); + if (victor != null) + victor.GetMotionMaster().MovePath(MiscConst.NefariusPath1, true); + break; + } + case EventIds.PathRend: + me.GetMotionMaster().MovePath(MiscConst.RendPath1, false); + break; + case EventIds.Teleport1: + me.NearTeleportTo(194.2993f, -474.0814f, 121.4505f, -0.01225555f); + _events.ScheduleEvent(EventIds.Teleport2, TimeSpan.FromSeconds(50)); + break; + case EventIds.Teleport2: + me.NearTeleportTo(216.485f, -434.93f, 110.888f, -0.01225555f); + me.SummonCreature(CreaturesIds.Gyth, 211.762f, -397.5885f, 111.1817f, 4.747295f); + break; + case EventIds.Wave1: + { + GameObject portcullis = ObjectAccessor.GetGameObject(me, portcullisGUID); + if (portcullis != null) + portcullis.UseDoorOrButton(); + + // move wave + break; + } + case EventIds.Wave2: + { + // spawn wave + GameObject portcullis = ObjectAccessor.GetGameObject(me, portcullisGUID); + if (portcullis != null) + portcullis.UseDoorOrButton(); + // move wave + break; + } + case EventIds.Wave3: + { + // spawn wave + GameObject portcullis = ObjectAccessor.GetGameObject(me, portcullisGUID); + if (portcullis != null) + portcullis.UseDoorOrButton(); + // move wave + break; + } + case EventIds.Wave4: + { + // spawn wave + GameObject portcullis = ObjectAccessor.GetGameObject(me, portcullisGUID); + if (portcullis != null) + portcullis.UseDoorOrButton(); + // move wave + break; + } + case EventIds.Wave5: + { + // spawn wave + GameObject portcullis = ObjectAccessor.GetGameObject(me, portcullisGUID); + if (portcullis != null) + portcullis.UseDoorOrButton(); + // move wave + break; + } + case EventIds.Wave6: + { + // spawn wave + GameObject portcullis = ObjectAccessor.GetGameObject(me, portcullisGUID); + if (portcullis != null) + portcullis.UseDoorOrButton(); + // move wave + break; + } + default: + break; + } + }); + } + + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me.HasUnitState(UnitState.Casting)) + return; + + _events.ExecuteEvents(eventId => + { + switch (eventId) + { + case EventIds.Whirlwind: + DoCast(SpellIds.Whirlwind); + _events.ScheduleEvent(EventIds.Whirlwind, TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(18)); + break; + case EventIds.Cleave: + DoCastVictim(SpellIds.Cleave); + _events.ScheduleEvent(EventIds.Cleave, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(14)); + break; + case EventIds.MortalStrike: + DoCastVictim(SpellIds.MortalStrike); + _events.ScheduleEvent(EventIds.MortalStrike, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(16)); + break; + } + + if (me.HasUnitState(UnitState.Casting)) + return; + }); + DoMeleeAttackIfReady(); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/ShadowHunterVoshgajin.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/ShadowHunterVoshgajin.cs new file mode 100644 index 000000000..5d0dbd60a --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/ShadowHunterVoshgajin.cs @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.ShadowHunterVoshgajin +{ + struct SpellIds + { + public const uint Curseofblood = 24673; + public const uint Hex = 16708; + public const uint Cleave = 20691; + } + + [Script] + class boss_shadow_hunter_voshgajin : BossAI + { + public boss_shadow_hunter_voshgajin(Creature creature) : base(creature, DataTypes.ShadowHunterVoshgajin) { } + + public override void Reset() + { + _Reset(); + //DoCast(me, SpellIcearmor, true); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(2), task => + { + DoCastVictim(SpellIds.Curseofblood); + task.Repeat(TimeSpan.FromSeconds(45)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(8), task => + { + Unit target = SelectTarget(SelectTargetMethod.Random, 0, 100, true); + if (target) + DoCast(target, SpellIds.Hex); + task.Repeat(TimeSpan.FromSeconds(15)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(14), task => + { + DoCastVictim(SpellIds.Cleave); + task.Repeat(TimeSpan.FromSeconds(7)); + }); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/TheBeast.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/TheBeast.cs new file mode 100644 index 000000000..ded515430 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/TheBeast.cs @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.Thebeast +{ + struct SpellIds + { + public const uint Flamebreak = 16785; + public const uint Immolate = 20294; + public const uint Terrifyingroar = 14100; + } + + [Script] + class boss_thebeast : BossAI + { + public boss_thebeast(Creature creature) : base(creature, DataTypes.TheBeast) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(12), task => + { + DoCastVictim(SpellIds.Flamebreak); + task.Repeat(TimeSpan.FromSeconds(10)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(3), task => + { + Unit target = SelectTarget(SelectTargetMethod.Random, 0, 100, true); + if (target) + DoCast(target, SpellIds.Immolate); + task.Repeat(TimeSpan.FromSeconds(8)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(23), task => + { + DoCastVictim(SpellIds.Terrifyingroar); + task.Repeat(TimeSpan.FromSeconds(20)); + }); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/UrokDoomhowl.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/UrokDoomhowl.cs new file mode 100644 index 000000000..9234ddb36 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/UrokDoomhowl.cs @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.UrokDoomhowl +{ + struct SpellIds + { + public const uint Rend = 16509; + public const uint Strike = 15580; + public const uint IntimidatingRoar = 16508; + } + + struct TextIds + { + public const uint SaySummon = 0; + public const uint SayAggro = 1; + } + + [Script] + class boss_urok_doomhowl : BossAI + { + public boss_urok_doomhowl(Creature creature) : base(creature, DataTypes.UrokDoomhowl) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(17), TimeSpan.FromSeconds(20), task => + { + DoCastVictim(SpellIds.Rend); + task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(12), task => + { + DoCastVictim(SpellIds.Strike); + task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10)); + }); + + Talk(TextIds.SayAggro); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} diff --git a/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/WarmasterVoone.cs b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/WarmasterVoone.cs new file mode 100644 index 000000000..c23578451 --- /dev/null +++ b/Source/Scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/WarmasterVoone.cs @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2012-2020 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 . + */ + +using Game.AI; +using Game.Entities; +using Game.Scripting; +using System; + +namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockSpire.WarmasterVoone +{ + struct SpellIds + { + public const uint Snapkick = 15618; + public const uint Cleave = 15284; + public const uint Uppercut = 10966; + public const uint Mortalstrike = 16856; + public const uint Pummel = 15615; + public const uint Throwaxe = 16075; + } + + [Script] + class boss_warmaster_voone : BossAI + { + public boss_warmaster_voone(Creature creature) : base(creature, DataTypes.WarmasterVoone) { } + + public override void Reset() + { + _Reset(); + } + + public override void JustEngagedWith(Unit who) + { + base.JustEngagedWith(who); + + _scheduler.Schedule(TimeSpan.FromSeconds(8), task => + { + DoCastVictim(SpellIds.Snapkick); + task.Repeat(TimeSpan.FromSeconds(6)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(14), task => + { + DoCastVictim(SpellIds.Cleave); + task.Repeat(TimeSpan.FromSeconds(12)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(20), task => + { + DoCastVictim(SpellIds.Uppercut); + task.Repeat(TimeSpan.FromSeconds(14)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(12), task => + { + DoCastVictim(SpellIds.Mortalstrike); + task.Repeat(TimeSpan.FromSeconds(10)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(32), task => + { + DoCastVictim(SpellIds.Pummel); + task.Repeat(TimeSpan.FromSeconds(16)); + }); + _scheduler.Schedule(TimeSpan.FromSeconds(1), task => + { + DoCastVictim(SpellIds.Throwaxe); + task.Repeat(TimeSpan.FromSeconds(8)); + }); + } + + public override void JustDied(Unit killer) + { + _JustDied(); + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, () => DoMeleeAttackIfReady()); + } + } +} + diff --git a/Source/Scripts/World/GameObject.cs b/Source/Scripts/World/GameObject.cs index 0636bb562..7d63400c7 100644 --- a/Source/Scripts/World/GameObject.cs +++ b/Source/Scripts/World/GameObject.cs @@ -529,8 +529,7 @@ namespace Scripts.World.GameObjects me.UseDoorOrButton(); if (player.GetQuestStatus(QuestIds.MissingFriends) == QuestStatus.Incomplete) { - List childrenList = new(); - me.GetCreatureListWithEntryInGrid(childrenList, CreatureIds.CaptiveChild, SharedConst.InteractionDistance); + List childrenList = me.GetCreatureListWithEntryInGrid(CreatureIds.CaptiveChild, SharedConst.InteractionDistance); foreach (Creature creature in childrenList) { player.KilledMonsterCredit(CreatureIds.CaptiveChild, creature.GetGUID()); diff --git a/Source/Scripts/World/NpcSpecial.cs b/Source/Scripts/World/NpcSpecial.cs index 19ecb8ba1..cb0f07a94 100644 --- a/Source/Scripts/World/NpcSpecial.cs +++ b/Source/Scripts/World/NpcSpecial.cs @@ -655,8 +655,7 @@ namespace Scripts.World.NpcSpecial ObjectGuid DoSearchForTargets(ObjectGuid lastTargetGUID) { - List targets = new(); - me.GetCreatureListWithEntryInGrid(targets, CreatureIds.TorchTossingTargetBunny, 60.0f); + List targets = me.GetCreatureListWithEntryInGrid(CreatureIds.TorchTossingTargetBunny, 60.0f); targets.RemoveAll(creature => creature.GetGUID() == lastTargetGUID); if (!targets.Empty()) @@ -1292,8 +1291,7 @@ namespace Scripts.World.NpcSpecial _events.Reset(); _scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), fillListTask => { - List creatureList = new(); - me.GetCreatureListWithEntryInGrid(creatureList, CreatureIds.BrewfestReveler, 5.0f); + List creatureList = me.GetCreatureListWithEntryInGrid(CreatureIds.BrewfestReveler, 5.0f); foreach (Creature creature in creatureList) if (creature != me) _revelerGuids.Add(creature.GetGUID());