/* * Copyright (C) 2012-2018 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.Collections.Generic; using System.Text; namespace Scripts.Northrend.Gundrak { struct GDInstanceMisc { public const uint TimerStatueActivation = 3500; public static DoorData[] doorData = { new DoorData(GDGameObjectIds.GalDarahDoor1, GDDataTypes.GalDarah, DoorType.Passage), new DoorData(GDGameObjectIds.GalDarahDoor2, GDDataTypes.GalDarah, DoorType.Passage), new DoorData(GDGameObjectIds.GalDarahDoor3, GDDataTypes.GalDarah, DoorType.Room), new DoorData(GDGameObjectIds.EckTheFerociousDoor, GDDataTypes.Moorabi, DoorType.Passage), new DoorData(GDGameObjectIds.EckTheFerociousDoorBehind, GDDataTypes.EckTheFerocious, DoorType.Passage), }; public static ObjectData[] creatureData = { new ObjectData(GDCreatureIds.DrakkariColossus, GDDataTypes.DrakkariColossus), }; public static ObjectData[] gameObjectData = { new ObjectData(GDGameObjectIds.SladRanAltar, GDDataTypes.SladRanAltar), new ObjectData(GDGameObjectIds.MoorabiAltar, GDDataTypes.MoorabiAltar), new ObjectData(GDGameObjectIds.DrakkariColossusAltar, GDDataTypes.DrakkariColossusAltar), new ObjectData(GDGameObjectIds.SladRanStatue, GDDataTypes.SladRanStatue), new ObjectData(GDGameObjectIds.MoorabiStatue, GDDataTypes.MoorabiStatue), new ObjectData(GDGameObjectIds.DrakkariColossusStatue, GDDataTypes.DrakkariColossusStatue), new ObjectData(GDGameObjectIds.GalDarahStatue, GDDataTypes.GalDarahStatue), new ObjectData(GDGameObjectIds.Trapdoor, GDDataTypes.Trapdoor), new ObjectData(GDGameObjectIds.Collision, GDDataTypes.Collision) }; public static Position EckSpawnPoint = new Position(1643.877930f, 936.278015f, 107.204948f, 0.668432f); } struct GDDataTypes { // Encounter Ids // Encounter States // Boss Guids public const uint SladRan = 0; public const uint DrakkariColossus = 1; public const uint Moorabi = 2; public const uint GalDarah = 3; public const uint EckTheFerocious = 4; // Additional Objects public const uint SladRanAltar = 5; public const uint DrakkariColossusAltar = 6; public const uint MoorabiAltar = 7; public const uint SladRanStatue = 8; public const uint DrakkariColossusStatue = 9; public const uint MoorabiStatue = 10; public const uint GalDarahStatue = 11; public const uint Trapdoor = 12; public const uint Collision = 13; public const uint Bridge = 14; public const uint StatueActivate = 15; } struct GDCreatureIds { public const uint SladRan = 29304; public const uint Moorabi = 29305; public const uint GalDarah = 29306; public const uint DrakkariColossus = 29307; public const uint RuinDweller = 29920; public const uint EckTheFerocious = 29932; public const uint AltarTrigger = 30298; } struct GDGameObjectIds { public const uint SladRanAltar = 192518; public const uint MoorabiAltar = 192519; public const uint DrakkariColossusAltar = 192520; public const uint SladRanStatue = 192564; public const uint MoorabiStatue = 192565; public const uint GalDarahStatue = 192566; public const uint DrakkariColossusStatue = 192567; public const uint EckTheFerociousDoor = 192632; public const uint EckTheFerociousDoorBehind = 192569; public const uint GalDarahDoor1 = 193208; public const uint GalDarahDoor2 = 193209; public const uint GalDarahDoor3 = 192568; public const uint Trapdoor = 193188; public const uint Collision = 192633; } struct GDSpellIds { public const uint FireBeamMammoth = 57068; public const uint FireBeamSnake = 57071; public const uint FireBeamElemental = 57072; } [Script] class instance_gundrak : InstanceMapScript { public instance_gundrak() : base(nameof(instance_gundrak), 604) { } class instance_gundrak_InstanceMapScript : InstanceScript { public instance_gundrak_InstanceMapScript(Map map) : base(map) { SetHeaders("GD"); SetBossNumber(5); LoadDoorData(GDInstanceMisc.doorData); LoadObjectData(GDInstanceMisc.creatureData, GDInstanceMisc.gameObjectData); SladRanStatueState = GameObjectState.Active; DrakkariColossusStatueState = GameObjectState.Active; MoorabiStatueState = GameObjectState.Active; } public override void OnCreatureCreate(Creature creature) { switch (creature.GetEntry()) { case GDCreatureIds.RuinDweller: if (creature.IsAlive()) DwellerGUIDs.Add(creature.GetGUID()); break; default: break; } base.OnCreatureCreate(creature); } public override void OnGameObjectCreate(GameObject go) { switch (go.GetEntry()) { case GDGameObjectIds.SladRanAltar: if (GetBossState(GDDataTypes.SladRan) == EncounterState.Done) { if (SladRanStatueState == GameObjectState.Active) go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable); else go.SetGoState(GameObjectState.Active); } break; case GDGameObjectIds.MoorabiAltar: if (GetBossState(GDDataTypes.Moorabi) == EncounterState.Done) { if (MoorabiStatueState == GameObjectState.Active) go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable); else go.SetGoState(GameObjectState.Active); } break; case GDGameObjectIds.DrakkariColossusAltar: if (GetBossState(GDDataTypes.DrakkariColossus) == EncounterState.Done) { if (DrakkariColossusStatueState == GameObjectState.Active) go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable); else go.SetGoState(GameObjectState.Active); } break; case GDGameObjectIds.SladRanStatue: go.SetGoState(SladRanStatueState); break; case GDGameObjectIds.MoorabiStatue: go.SetGoState(MoorabiStatueState); break; case GDGameObjectIds.GalDarahStatue: go.SetGoState(CheckRequiredBosses(GDDataTypes.GalDarah) ? GameObjectState.ActiveAlternative : GameObjectState.Ready); break; case GDGameObjectIds.DrakkariColossusStatue: go.SetGoState(DrakkariColossusStatueState); break; case GDGameObjectIds.EckTheFerociousDoor: // Don't store door on non-heroic if (!instance.IsHeroic()) return; break; case GDGameObjectIds.Trapdoor: go.SetGoState(CheckRequiredBosses(GDDataTypes.GalDarah) ? GameObjectState.Ready : GameObjectState.Active); break; case GDGameObjectIds.Collision: go.SetGoState(CheckRequiredBosses(GDDataTypes.GalDarah) ? GameObjectState.Active : GameObjectState.Ready); break; default: break; } base.OnGameObjectCreate(go); } public override void OnUnitDeath(Unit unit) { if (unit.GetEntry() == GDCreatureIds.RuinDweller) { DwellerGUIDs.Remove(unit.GetGUID()); if (DwellerGUIDs.Empty()) unit.SummonCreature(GDCreatureIds.EckTheFerocious, GDInstanceMisc.EckSpawnPoint, TempSummonType.CorpseTimedDespawn, 300 * Time.InMilliseconds); } } public override bool SetBossState(uint type, EncounterState state) { if (!base.SetBossState(type, state)) return false; switch (type) { case GDDataTypes.SladRan: if (state == EncounterState.Done) { GameObject go = GetGameObject(GDDataTypes.SladRanAltar); if (go) go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable); } break; case GDDataTypes.DrakkariColossus: if (state == EncounterState.Done) { GameObject go = GetGameObject(GDDataTypes.DrakkariColossusAltar); if (go) go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable); } break; case GDDataTypes.Moorabi: if (state == EncounterState.Done) { GameObject go = GetGameObject(GDDataTypes.MoorabiAltar); if (go) go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable); } break; default: break; } return true; } public override bool CheckRequiredBosses(uint bossId, Player player = null) { if (_SkipCheckRequiredBosses(player)) return true; switch (bossId) { case GDDataTypes.EckTheFerocious: if (!instance.IsHeroic() || GetBossState(GDDataTypes.Moorabi) != EncounterState.Done) return false; break; case GDDataTypes.GalDarah: if (SladRanStatueState != GameObjectState.ActiveAlternative || DrakkariColossusStatueState != GameObjectState.ActiveAlternative || MoorabiStatueState != GameObjectState.ActiveAlternative) return false; break; default: break; } return true; } bool IsBridgeReady() { return SladRanStatueState == GameObjectState.Ready && DrakkariColossusStatueState == GameObjectState.Ready && MoorabiStatueState == GameObjectState.Ready; } public override void SetData(uint type, uint data) { if (type == GDDataTypes.StatueActivate) { switch (data) { case GDGameObjectIds.SladRanAltar: _events.ScheduleEvent(GDDataTypes.SladRanStatue, GDInstanceMisc.TimerStatueActivation); break; case GDGameObjectIds.DrakkariColossusAltar: _events.ScheduleEvent(GDDataTypes.DrakkariColossusStatue, GDInstanceMisc.TimerStatueActivation); break; case GDGameObjectIds.MoorabiAltar: _events.ScheduleEvent(GDDataTypes.MoorabiStatue, GDInstanceMisc.TimerStatueActivation); break; default: break; } } } public override void WriteSaveDataMore(StringBuilder data) { data.AppendFormat("{0} {1} {2} ", (uint)SladRanStatueState, (uint)DrakkariColossusStatueState, (uint)MoorabiStatueState); } public override void ReadSaveDataMore(StringArguments data) { SladRanStatueState = (GameObjectState)data.NextUInt32(); DrakkariColossusStatueState = (GameObjectState)data.NextUInt32(); MoorabiStatueState = (GameObjectState)data.NextUInt32(); if (IsBridgeReady()) _events.ScheduleEvent(GDDataTypes.Bridge, GDInstanceMisc.TimerStatueActivation); } void ToggleGameObject(uint type, GameObjectState state) { GameObject go = GetGameObject(type); if (go) go.SetGoState(state); switch (type) { case GDDataTypes.SladRanStatue: SladRanStatueState = state; break; case GDDataTypes.DrakkariColossusStatue: DrakkariColossusStatueState = state; break; case GDDataTypes.MoorabiStatue: MoorabiStatueState = state; break; default: break; } } public override void Update(uint diff) { _events.Update(diff); _events.ExecuteEvents(eventId => { uint spellId = 0; uint altarId = 0; switch (eventId) { case GDDataTypes.SladRanStatue: spellId = GDSpellIds.FireBeamSnake; altarId = GDDataTypes.SladRanAltar; break; case GDDataTypes.DrakkariColossusStatue: spellId = GDSpellIds.FireBeamElemental; altarId = GDDataTypes.DrakkariColossusAltar; break; case GDDataTypes.MoorabiStatue: spellId = GDSpellIds.FireBeamMammoth; altarId = GDDataTypes.MoorabiAltar; break; case GDDataTypes.Bridge: for (uint type = GDDataTypes.SladRanStatue; type <= GDDataTypes.GalDarahStatue; ++type) ToggleGameObject(type, GameObjectState.ActiveAlternative); ToggleGameObject(GDDataTypes.Trapdoor, GameObjectState.Ready); ToggleGameObject(GDDataTypes.Collision, GameObjectState.Active); SaveToDB(); return; default: return; } GameObject altar = GetGameObject(altarId); if (altar) { Creature trigger = altar.FindNearestCreature(GDCreatureIds.AltarTrigger, 10.0f); if (trigger) trigger.CastSpell((Unit)null, spellId, true); } // eventId equals statueId ToggleGameObject(eventId, GameObjectState.Ready); if (IsBridgeReady()) _events.ScheduleEvent(GDDataTypes.Bridge, GDInstanceMisc.TimerStatueActivation); SaveToDB(); }); } List DwellerGUIDs = new List(); GameObjectState SladRanStatueState; GameObjectState DrakkariColossusStatueState; GameObjectState MoorabiStatueState; } public override InstanceScript GetInstanceScript(InstanceMap map) { return new instance_gundrak_InstanceMapScript(map); } } [Script] class go_gundrak_altar : GameObjectScript { public go_gundrak_altar() : base("go_gundrak_altar") { } public override bool OnGossipHello(Player player, GameObject go) { go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable); go.SetGoState(GameObjectState.Active); InstanceScript instance = go.GetInstanceScript(); if (instance != null) { instance.SetData(GDDataTypes.StatueActivate, go.GetEntry()); return true; } return false; } } }